中序遍历的模板(以及变形更新中。。。)
描述
給定一個(gè)二叉樹(shù)的根節(jié)點(diǎn)root,返回它的中序遍歷結(jié)果。
數(shù)據(jù)范圍:樹(shù)上節(jié)點(diǎn)數(shù)滿(mǎn)足0≤n≤1000,樹(shù)上每個(gè)節(jié)點(diǎn)的值滿(mǎn)足 0≤val≤1000
進(jìn)階:空間復(fù)雜度?O(n),時(shí)間復(fù)雜度?O(n)
示例1
輸入:
{1,2,#,#,3} 返回值: [2,3,1] 說(shuō)明:示例2
輸入:
{}返回值:
[]示例3
輸入:
{1,2}
返回值:
[2,1]
說(shuō)明:
0原始的中序遍歷模塊?
/*** struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };** C語(yǔ)言聲明定義全局變量請(qǐng)加上static,防止重復(fù)定義*/ /*** 代碼中的類(lèi)名、方法名、參數(shù)名已經(jīng)指定,請(qǐng)勿修改,直接返回方法規(guī)定的值即可** * @param root TreeNode類(lèi) * @return int整型一維數(shù)組* @return int* returnSize 返回?cái)?shù)組行數(shù)*/ void dfs(struct TreeNode*root,int *a,int* returnSize){if(root==NULL){return;}dfs(root->left,a,returnSize);a[(*returnSize)++]=root->val;dfs(root->right,a,returnSize); } int* inorderTraversal(struct TreeNode* root, int* returnSize ) {// write code hereint* a=(int*)malloc(sizeof(int)*1000);*returnSize=0;dfs(root, a, returnSize);return a; }1.?二叉搜索樹(shù)與雙向鏈表(中序遍歷的變形)
描述
輸入一棵二叉搜索樹(shù),將該二叉搜索樹(shù)轉(zhuǎn)換成一個(gè)排序的雙向鏈表。如下圖所示
數(shù)據(jù)范圍:輸入二叉樹(shù)的節(jié)點(diǎn)數(shù) 0≤n≤1000,二叉樹(shù)中每個(gè)節(jié)點(diǎn)的值0≤val≤1000
要求:空間復(fù)雜度O(1)(即在原樹(shù)上操作),時(shí)間復(fù)雜度O(n)
注意:
1.要求不能創(chuàng)建任何新的結(jié)點(diǎn),只能調(diào)整樹(shù)中結(jié)點(diǎn)指針的指向。當(dāng)轉(zhuǎn)化完成以后,樹(shù)中節(jié)點(diǎn)的左指針需要指向前驅(qū),樹(shù)中節(jié)點(diǎn)的右指針需要指向后繼
2.返回鏈表中的第一個(gè)節(jié)點(diǎn)的指針
3.函數(shù)返回的TreeNode,有左右指針,其實(shí)可以看成一個(gè)雙向鏈表的數(shù)據(jù)結(jié)構(gòu)
4.你不用輸出雙向鏈表,程序會(huì)根據(jù)你的返回值自動(dòng)打印輸出
輸入描述:
二叉樹(shù)的根節(jié)點(diǎn)
返回值描述:
雙向鏈表的其中一個(gè)頭節(jié)點(diǎn)。
示例1
輸入:
{10,6,14,4,8,12,16}返回值:
From left to right are:4,6,8,10,12,14,16;From right to left are:16,14,12,10,8,6,4;說(shuō)明:
輸入題面圖中二叉樹(shù),輸出的時(shí)候?qū)㈦p向鏈表的頭節(jié)點(diǎn)返回即可。示例2
輸入:
{5,4,#,3,#,2,#,1}返回值:
From left to right are:1,2,3,4,5;From right to left are:5,4,3,2,1;?++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
看起來(lái)復(fù)雜,其實(shí)就是中序遍歷對(duì)訪(fǎng)問(wèn)節(jié)點(diǎn)進(jìn)行一個(gè)修改左右指針
1.使用二叉樹(shù)的中序遍歷可以獲得一個(gè)要求鏈表結(jié)點(diǎn)的訪(fǎng)問(wèn)順序;
2.在這個(gè)順序中,我們要存儲(chǔ)當(dāng)前的結(jié)點(diǎn)root和訪(fǎng)問(wèn)前的結(jié)點(diǎn)pre(pre的值一定是比root小的)
3.判斷當(dāng)前節(jié)點(diǎn)的左驅(qū)節(jié)點(diǎn)是否存在?
? ? ?如果不存在,則(當(dāng)前節(jié)點(diǎn)為最左邊的節(jié)點(diǎn))head=root? ?(雙鏈表的頭指針)
? ? ?如果存在,? 修改pre和cur的左右指向,pre.right = root; root.left = pre;
4.更新左驅(qū)節(jié)點(diǎn)? ?pre=root? (將當(dāng)前的節(jié)點(diǎn)變?yōu)橄乱粋€(gè)節(jié)點(diǎn)的左驅(qū)節(jié)點(diǎn))
/** public class TreeNode {int val = 0;TreeNode left = null;TreeNode right = null;public TreeNode(int val) {this.val = val;}} */public class Solution {TreeNode pre=null; //初始化左驅(qū)節(jié)點(diǎn)TreeNode head=null; //初始化雙鏈表的頭結(jié)點(diǎn)void inorder(TreeNode root){if(root==null) return ;inorder(root.left); //左遞歸if(pre==null){ //如果該節(jié)點(diǎn)沒(méi)有左驅(qū)節(jié)點(diǎn)則說(shuō)明該節(jié)點(diǎn)是第一個(gè)節(jié)點(diǎn)head=root; //作為雙鏈表的頭指針}else{pre.right=root; //左驅(qū)節(jié)點(diǎn)的右指針指向當(dāng)前節(jié)點(diǎn)root.left=pre; //當(dāng)前節(jié)點(diǎn)的左指針指向左驅(qū)節(jié)點(diǎn)}pre=root; //更新左驅(qū)節(jié)點(diǎn),將當(dāng)前的節(jié)點(diǎn)變?yōu)樽篁?qū)節(jié)點(diǎn)inorder(root.right); //右遞歸}public TreeNode Convert(TreeNode pRootOfTree) {if(pRootOfTree==null){return pRootOfTree;}inorder(pRootOfTree);return head;} }2.BM34?判斷是不是二叉搜索樹(shù)(中序遍歷)
描述
給定一個(gè)二叉樹(shù)根節(jié)點(diǎn),請(qǐng)你判斷這棵樹(shù)是不是二叉搜索樹(shù)。
二叉搜索樹(shù)滿(mǎn)足每個(gè)節(jié)點(diǎn)的左子樹(shù)上的所有節(jié)點(diǎn)均小于當(dāng)前節(jié)點(diǎn)且右子樹(shù)上的所有節(jié)點(diǎn)均大于當(dāng)前節(jié)點(diǎn)。
例:
上圖1
上圖2
數(shù)據(jù)范圍:節(jié)點(diǎn)數(shù)量滿(mǎn)足\1≤n≤10^4??,節(jié)點(diǎn)上的值滿(mǎn)足??2^31≤val≤2^31?1?
示例1
輸入:
{1,2,3}返回值:
false說(shuō)明:
如題面圖1示例2
輸入:
{2,1,3}返回值:
true說(shuō)明:
如題面圖2法一:可以遞歸中序遍歷判斷左右每個(gè)子樹(shù)是否是二叉搜索樹(shù)
import java.util.*;/** public class TreeNode {* int val = 0;* TreeNode left = null;* TreeNode right = null;* public TreeNode(int val) {* this.val = val;* }* }*/public class Solution {/*** 代碼中的類(lèi)名、方法名、參數(shù)名已經(jīng)指定,請(qǐng)勿修改,直接返回方法規(guī)定的值即可** * @param root TreeNode類(lèi) * @return bool布爾型*/int pre=Integer.MIN_VALUE;public boolean isValidBST (TreeNode root) {if(root==null){return true;}if(!isValidBST(root.left)){ //遍歷左子樹(shù),判斷左子樹(shù)是否是二叉搜索樹(shù)return false;}if(pre>root.val){ //根節(jié)點(diǎn)的處理return false;}else{pre=root.val; //上一個(gè)節(jié)點(diǎn)的值更新,這個(gè)值始終是當(dāng)前節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)的值}if(!isValidBST(root.right)){ //遍歷右子樹(shù),判斷右子樹(shù)是否是二叉搜索樹(shù)return false;}return true; //是二叉搜索樹(shù)//return isValidBST(root.right); //上述的遍歷右子樹(shù)也可以直接這樣返回遍歷左子樹(shù),判斷左子樹(shù)是否是二叉搜索樹(shù)} }法二:非遞歸中序遍歷的方式(原理跟遞歸中序一樣)
import java.util.*;/** public class TreeNode {* int val = 0;* TreeNode left = null;* TreeNode right = null;* public TreeNode(int val) {* this.val = val;* }* }*/public class Solution {/*** 代碼中的類(lèi)名、方法名、參數(shù)名已經(jīng)指定,請(qǐng)勿修改,直接返回方法規(guī)定的值即可** * @param root TreeNode類(lèi) * @return bool布爾型*/public boolean isValidBST (TreeNode root) {if(root.left==null&&root.right==null)return true;Stack<TreeNode> st=new Stack<>();TreeNode p=root;int pre=Integer.MIN_VALUE; //定義最小值while(!st.isEmpty()||p!=null){ //棧實(shí)現(xiàn)中序遍歷while(p!=null){st.push(p); //不停的進(jìn)棧p=p.left; //不停訪(fǎng)問(wèn)左節(jié)點(diǎn)子樹(shù)}//當(dāng)左節(jié)點(diǎn)為空,則表示已經(jīng)到了最左節(jié)點(diǎn),此時(shí)p=null//出棧p=st.pop();if(p.val<pre){return false;}pre=p.val; //更改上一個(gè)節(jié)點(diǎn)的值p=p.right; //遍歷右子樹(shù)}return true;} }法三:遞歸
思路:
????? ??每個(gè)節(jié)點(diǎn)的值都滿(mǎn)足一個(gè)區(qū)間范圍。
????? ? 初始化,根節(jié)點(diǎn)的范圍 int 的范圍。
????????如果當(dāng)前節(jié)點(diǎn)的值小于左區(qū)間或者大于右區(qū)間,則返回 false。
????? ? 否則,繼續(xù)分別遞歸左右兒子節(jié)點(diǎn):
????????????????????遞歸左兒子,并將左兒子的右區(qū)間修改為父節(jié)點(diǎn)的值;
????????????????????遞歸右兒子,并將右兒子的左區(qū)間修改為父節(jié)點(diǎn)的值。
????? ? 最后,如果沒(méi)有返回false,說(shuō)明滿(mǎn)足二叉搜索樹(shù),返回true。
import java.util.*;/** public class TreeNode {* int val = 0;* TreeNode left = null;* TreeNode right = null;* public TreeNode(int val) {* this.val = val;* }* }*/public class Solution {/*** 代碼中的類(lèi)名、方法名、參數(shù)名已經(jīng)指定,請(qǐng)勿修改,直接返回方法規(guī)定的值即可** * @param root TreeNode類(lèi) * @return bool布爾型*/public boolean dfs(TreeNode root,int l,int r){if(root==null){return true;}if(root.val<l||root.val>r){return false;}return dfs(root.left,l,root.val)&&dfs(root.right,root.val,r);}int pre=Integer.MIN_VALUE;public boolean isValidBST (TreeNode root) {int INT_MIN=Integer.MIN_VALUE; //區(qū)間最小值int INT_MAX=Integer.MAX_VALUE; //區(qū)間最大值if(root==null)return true;return dfs(root,INT_MIN,INT_MAX);//根節(jié)點(diǎn)的區(qū)間范圍為int的范圍} }總結(jié)
以上是生活随笔為你收集整理的中序遍历的模板(以及变形更新中。。。)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 初学JSON
- 下一篇: 二叉树的的前序遍历和后序遍历(题型变种更