算法练习day11——190329(平衡二叉树、搜索二叉树、完全二叉树)
生活随笔
收集整理的這篇文章主要介紹了
算法练习day11——190329(平衡二叉树、搜索二叉树、完全二叉树)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.平衡二叉樹
判斷一棵樹是否為平衡二叉樹
1.1 分析
首先需要得到一個節點的以下四個信息:
接著,設計遞歸:
- 應該返回以此節點為根的樹是否平衡,以及此樹的高度
- 平衡:
- 它的左右子樹都平衡;
- 它的左右子樹高度差不超過1;
- 樹高:
- 子樹中高度較大的值+1;
- 平衡:
注:空樹是平衡的。
1.2 代碼實現
package Tree;public class BalancedTree {public static class ReturnData{public boolean isB;public int h;public ReturnData(boolean isB, int h) {this.isB=isB;this.h=h;}}public static void main(String[] args) {Node head = new Node(1);head.left = new Node(2);head.right = new Node(3);head.left.left = new Node(4);head.left.right = new Node(5);head.right.left = new Node(6);head.right.right = new Node(7);System.out.println(isBalanced(head).isB);}public static ReturnData isBalanced(Node head) {if(head==null)return new ReturnData(true,0);ReturnData leftData=isBalanced(head.left); if(!leftData.isB)//若左子樹不平衡,則后面的不用計算;一路向上返回false//不平衡后,高度無所謂了。return new ReturnData(false,0);ReturnData rightData=isBalanced(head.right); if(!rightData.isB)return new ReturnData(false,0);if(Math.abs(leftData.h-rightData.h)>1)return new ReturnData(false,0); return new ReturnData(true,Math.max(leftData.h, rightData.h)+1);} }平衡樹是為了解決效率問題
2.搜索二叉樹
左子樹的值都比節點值小,右子樹的值都比節點值大。
通常,搜索二叉樹中是不會出現重復節點的。
- 若出現了,一般把相同的壓入一個節點,節點值所帶的信息可以存入一個list中。
- 需要的話可以記錄下重復次數。
2.1 分析
判斷一棵樹是不是搜索二叉樹:如果它的中序遍歷序列,節點值是升序的,則是搜索二叉樹。
只要將中序遍歷的非遞歸實現中輸出節點的語句改為判斷當前值是否大于前一個值的語句即可。
要考慮怎么將之前的值存下來。
2.2 代碼實現
package Tree;import java.util.LinkedList; import java.util.Queue; import java.util.Stack;public class BinarySearchTree {public static void main(String[] args) {Node head = new Node(4);head.left = new Node(2);head.right = new Node(6);head.left.left = new Node(1);head.left.right = new Node(3);head.right.left = new Node(5);System.out.println(isBST(head));}public static boolean isBST(Node head) {Node cur=null;if(head!=null) {Stack<Node> stack=new Stack<Node>();Queue<Integer> queue=new LinkedList<Integer>();while(!stack.isEmpty()||head!=null) {if(head!=null) {//以節點不為空的條件進來stack.push(head);head=head.left;}else {//以棧不為空的條件進來cur=stack.pop();if(!queue.isEmpty()) if(cur.value<queue.poll())return false;queue.add(cur.value);cur=cur.right;}}}return true;} }3.完全二叉樹
?判斷一個二叉樹是不是完全二叉樹
3.1 分析
首先二叉樹按層遍歷,
- 如果一個節點右右孩子但是沒有左孩子,一定不是完全二叉樹;
- 如果一個節點,它不是左右兩個孩子都全:則,它后面的節點必須都是葉子節點,否則不是完全二叉樹。
- 有左沒右(有右沒左第一點已排除);
- 沒有孩子。
設置一個boolean stage=false。
當當前數通過了第一點驗證,進入第二點時,stage=true,此時,后面節點必須都是葉子節點。
3.2 代碼實現
public static boolean isCBT(Node head) {if(head==null)return true;Queue<Node> queue=new LinkedList<Node>();boolean leaf=false;Node l=null;Node r=null;queue.add(head);while(!queue.isEmpty()) {head=queue.poll();l=head.left;r=head.right;if((leaf&&(l!=null||r!=null))||(l==null&&r!=null))//開啟了第二階段(后面的節點必須為空),但是有一個節點不為空;//第一階段:左為空,右不為空//則返回falsereturn false;if(l!=null)queue.add(l);if(r!=null)queue.add(r);if(l==null||r==null)leaf=true;}return true; }用二叉樹實現堆結構與數組實現堆結構的比較
二叉樹實現沒有空間浪費,沒有擴容代價。
3.3?已知一棵完全二叉樹, 求其節點的個數
要求: 時間復雜度低于O(N), N為這棵樹的節點個數
3.3.1 分析
結論:一棵高的滿二叉樹,節點個數為。
首先遍歷以當前節點形成的一棵完全二叉樹的左邊界,得到此樹的高度?!?/p>
遍歷當前節點右子樹的左邊界,看它到沒到最后一層?!?/p>
- 到了最后一層,則說明根節點的左子樹是滿的;
- 可得到左子樹的節點個數;
- 加上當前節點:
- 再遞歸求右子樹(也是一棵完全二叉樹,和母問題等效)的節點個數。
- 沒到最后一層,說明右子樹是一棵滿二叉樹(高度=左子樹高度-1);
- 右樹的節點;
- 加上當前節點:;
- 再遞歸求左子樹(也是一棵完全二叉樹,和母問題等效)的節點個數。
3.3.2 代碼實現
package Tree;import Tree.Test.Node;public class CountNode {public static void main(String[] args) {Node head = new Node(1);head.left = new Node(2);head.right = new Node(3);head.left.left = new Node(4);head.left.right = new Node(5);head.right.left = new Node(6);System.out.println(countNode(head));}public static int countNode(Node head) {if(head==null)return 0;return bs(head,1,mostLevel(head,1));}public static int bs(Node node, int level, int h) {if(level==h)//node為葉子節點return 1;if(mostLevel(node.right,level+1)==h)//右子樹最左節點的深度到達最深(即到達最后一層)//左子樹為滿二叉樹,遞歸右子樹//return (1 << (h - level)) +bs(node.right,level+1,h);return (int) (Math.pow(2,(h-level))+bs(node.right,level+1,h));else //右子樹為滿二叉樹,遞歸左子樹return (int) (Math.pow(2,(h-level-1))+bs(node.left,level+1,h));//return (1 << (h - level - 1))+bs(node.left,level+1,h);}public static int mostLevel(Node head,int h) {while(head!=null) {h++;head=head.left;}return h-1;} }時間復雜度:
- 每一層需要遍歷一個節點
- 要么左子樹的根節點,要么右子樹的根節點
- 總共層
- 每個節點需要求高度,也是
?
總結
以上是生活随笔為你收集整理的算法练习day11——190329(平衡二叉树、搜索二叉树、完全二叉树)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法练习day10——190328(二叉
- 下一篇: 算法练习day12——190331(哈希