二叉樹:搜尋二叉樹和完全二叉樹
阿新 • • 發佈:2018-12-25
搜尋二叉樹又叫作二叉樹查詢樹或者二叉排序樹,
所謂搜尋二叉樹是指對於任何一個結點,它的左子樹的所有結點都比這個根結點要小,它的右子樹的所有結點都比這個根結點要大。注意是根結點與左右子樹上所有的結點進行比較而不是僅僅與左右孩子結點進行比較,因此根據這個定義,那麼當按照中序遍歷來遍歷一棵搜尋二叉樹時,必然是單調遞增的,即是有序的序列,反之,如果一棵二叉樹按照中序遍歷得到的序列時有序的,那麼這棵二叉樹一定是搜尋二叉樹,因此對於搜尋二叉樹通常總是進行中序遍歷的操作。
紅黑樹、平衡搜尋二叉樹(AVL樹)等其實都是搜尋二叉樹的不同實現,它們都努力使得搜尋二叉樹的搜尋效率更高,調整代價更小。
題目:判斷一棵二叉樹是否是搜尋二叉樹
思路:根據定義檢查在進行中序遍歷時結點值是否遞增即可,如果一旦出現減小,必然不是搜尋二叉樹。
可以使用遞迴也可以不使用遞迴,當使用遞迴時注意,由於每次遍歷到的結點需要與上一個結點進行比較,因此要保留上一個結點的值,因此在遞迴外面要設定一個成員變數temp(不能是區域性變數)用來記住上一次遍歷到的結點值,如果本次結點>=temp表示符合要求,再將temp替換為當前的值即可。並且,為了使得當遇到<temp的結點時停止,因此要設定一個falg變數作為標記符,每次判斷當前值與temp時如果不符合要去就將falg設定為false,然後結束方法。package com.caicainiao.nowcoder; //主函式 public class SearchBinaryTree { public static void main(String[] args) { TreeNode node1=new TreeNode(1); TreeNode node2=new TreeNode(2); TreeNode node3=new TreeNode(3); TreeNode node4=new TreeNode(4); TreeNode node5=new TreeNode(5); TreeNode node6=new TreeNode(6); TreeNode node7=new TreeNode(7); node4.left=node2; node4.right=node6; node2.left=node1; node2.right=node3; node6.left=node5; node6.right=node7; new SearchBinaryTree().checkIsSearch(node4); } //輔助變數:成員變數,所有遞迴棧共享 int temp; boolean flag=true; //判斷是否是搜尋二叉樹,中序遍歷 public void checkIsSearch(TreeNode treeNode ){ temp=Integer.MIN_VALUE; this.inOrderRecru(treeNode); if(flag){ System.out.println("是搜尋二叉樹"); }else{ System.out.println("不是搜尋二叉樹"); } } //中序遍歷,同時判斷是否遞增 private void inOrderRecru(TreeNode treeNode){ //這是一個遞迴方法,要有結束的邊界條件,當沒有子節點時返回 if(treeNode==null) return; //①先遍歷子樹的左子樹 this.inOrderRecru(treeNode.left); //②與前一個結點值比較 if(treeNode.val<temp){ flag=false; return; } temp=treeNode.val; //③遍歷子樹的右子樹 this.inOrderRecru(treeNode.right); } }
滿二叉樹與完全二叉樹
所謂的滿二叉樹是指一棵二叉樹中除了最後一層的結點沒有任何子節點之外,剩下每一層上的結點都有2個子節點,即直觀地看,滿二叉樹沒有任何確實的結點。對於滿二叉樹,它的結點數目與層數存在直接的對應關係,如果層數為L,那麼滿二叉樹的結點數目為N=2^L-1,反之L=log2(N+1)
所謂完全二叉樹是指除了最後一層之外,其他每一層的結點數目都是滿的,如果最後一層也滿了就是滿二叉樹,如果最後一層不滿那麼結點全部集中在左側。滿二叉樹是一棵特殊的完全二叉樹,對於完全二叉樹這種特殊的結構,它可以使用陣列來表示各個結點,此時每個結點與它的子節點的位置下標之間存在直接的對應關係,即從陣列中i=1開始存放元素,於是對於某個結點i,它的左孩子下標是2*i,它的右孩子結點時2*i+1,它的父節點下標是i/2。堆(優先佇列)就是一種完全二叉樹結構。