《剑指offer》-- 从上往下打印二叉树、二叉搜素树的后序遍历、二叉树中和为某一值的路径、二叉树与双向链表
一、從上往下打印二叉樹:
1、題目:
上往下打印出二叉樹的每個節點,同層節點從左至右打印。
2、解題思路:
用arraylist模擬一個隊列來存儲相應的TreeNode。
3、代碼實現:
public class Test9 {public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {ArrayList<Integer> list=new ArrayList<Integer>();if(root == null){return list;}ArrayList<TreeNode> queen=new ArrayList<TreeNode>();queen.add(root);while(queen.size()!=0){TreeNode temp=queen.remove(0);if(temp.left!=null){queen.add(temp.left);}if(temp.right!=null){queen.add(temp.right);}list.add(temp.val);}return list;} }class TreeNode{int val = 0;TreeNode left = null;TreeNode right = null;public TreeNode(int val) {this.val = val;} }二、二叉搜索樹的后序遍歷:
1、題目:
輸入一個整數數組,判斷該數組是不是某二叉搜索樹的后序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同
2、解題思路:
已知條件:后序序列最后一個值為root;二叉搜索樹左子樹值都比root小,右子樹值都比root大。
(1)確定root;
(2)遍歷序列(除去root結點),找到第一個大于root的位置,則該位置左邊為左子樹,右邊為右子樹;
(3)遍歷右子樹,若發現有小于root的值,則直接返回false;
(4)分別判斷左子樹和右子樹是否仍是二叉搜索樹(即遞歸步驟1、2、3)。
3、代碼實現:
public class Test10 {public boolean VerifySquenceOfBST(int [] sequence) {if(sequence.length==0){return false;}if(sequence.length==1){return true;}return judge(sequence,0,sequence.length-1);}public boolean judge(int [] sequence,int startIndex,int rootIndex){if(startIndex>rootIndex){return true;}int i=startIndex;//找到右子樹的第一個節點的下標while(sequence[i]<sequence[rootIndex]){i++;}for(int j=i;j<rootIndex;j++){if(sequence[j]<sequence[rootIndex]){return false;}}return judge(sequence,startIndex,i-1)&&judge(sequence,i,rootIndex-1);} }三、二叉樹中和為某一值的路徑:
1、題目
輸入一顆二叉樹的跟節點和一個整數,打印出二叉樹中結點值的和為輸入整數的所有路徑。路徑定義為從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。(注意: 在返回值的list中,數組長度大的數組靠前)。
2、解題思路:
?(1)root入棧,跳入該子樹進行尋路操作 ;
?(2)若root的這條路徑,已滿足要求,則將該路徑加入到listAll中去;
?(3)對root左右子樹,繼續尋路;
?(4)root出棧,該子樹訪問完畢;
3、代碼實現:
public class Test11 {private ArrayList<ArrayList<Integer>> resultList=new ArrayList<>();//最終返回的resultListprivate ArrayList<Integer> list= new ArrayList<>();public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {find(root,target);//對resultList的進行按長度排序Collections.sort(resultList,new Comparator<ArrayList<Integer>>() {@Overridepublic int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {return o2.size()-o1.size();}});return resultList;}public void find(TreeNode root,int target){if(root==null){return ;}list.add(root.val);target=target-root.val;if(target==0 && root.left==null && root.right==null){resultList.add(new ArrayList<Integer>(list));}//如果提前超過target的值,則終止遍歷,不繼續查找子節點if(target<0){list.remove(list.size()-1);return ;}find(root.left,target);find(root.right,target);//回退list.remove(list.size()-1);} }class TreeNode {int val = 0;TreeNode left = null;TreeNode right = null;public TreeNode(int val) {this.val = val;} }四、二叉樹與雙向鏈表:
1、題目:
輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。
2、解題思路:
代碼中有注釋。
3、代碼實現:
public class Test13 {//第二種遞歸方式://改進步驟2://記錄子樹鏈表的最后一個節點,終結點只可能為只含左子樹的非葉節點與葉節點protected TreeNode leftLast = null;public TreeNode Convert2(TreeNode pRootOfTree) {if(pRootOfTree == null){return null;}if(pRootOfTree.left == null && pRootOfTree.right == null){leftLast = pRootOfTree;return pRootOfTree;}//1、將左子樹構造成雙鏈表,并返回鏈表頭結點。TreeNode left=Convert2(pRootOfTree.left);//3、如果左子樹的鏈表不為空的話,將當前root追加到左子樹鏈表if(left!=null){leftLast.right = pRootOfTree;pRootOfTree.left=leftLast;}leftLast = pRootOfTree;//當根節點只含左子樹時,則該根節點為最后一個節點。//4、將右子樹構造成雙鏈表,并返回鏈表頭結點TreeNode right= Convert2(pRootOfTree.right);//5、如果右子樹鏈表不為空的話,將該鏈表追加到root節點if(right!=null){right.left=pRootOfTree;pRootOfTree.right=right;}return left!=null?left:pRootOfTree;}//第一種遞歸方式:public TreeNode Convert(TreeNode pRootOfTree) {if(pRootOfTree == null){return null;}if(pRootOfTree.left == null && pRootOfTree.right == null){return pRootOfTree;}//1、將左子樹構造成雙鏈表,并返回鏈表頭結點。TreeNode left=Convert(pRootOfTree.left);TreeNode p=left;//2、定位至左子樹雙鏈表最后一個節點while(p!=null && p.right!=null){p=p.right;}//3、如果左子樹的鏈表不為空的話,將當前root追加到左子樹鏈表if(left!=null){p.right = pRootOfTree;pRootOfTree.left=p;}//4、將右子樹構造成雙鏈表,并返回鏈表頭結點TreeNode right= Convert(pRootOfTree.right);//5、如果右子樹鏈表不為空的話,將該鏈表追加到root節點if(right!=null){right.left=pRootOfTree;pRootOfTree.right=right;}return left!=null?left:pRootOfTree;} }class TreeNode {int val = 0;TreeNode left = null;TreeNode right = null;public TreeNode(int val) {this.val = val;} }總結
以上是生活随笔為你收集整理的《剑指offer》-- 从上往下打印二叉树、二叉搜素树的后序遍历、二叉树中和为某一值的路径、二叉树与双向链表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《剑指offer》-- 栈的压入与弹出序
- 下一篇: 《剑指offer》-- 复杂链表的复制、