二叉樹的性質
1,二叉樹的第i層最多包含2*i-1個節點。
2,二叉樹如果深度爲k(有k層),那麼最多含有(2^k )-1個節點。
3,若二叉樹按照從上到下從左到右的方式編號,某節點的編號爲k,那麼他的左右子樹分別編號爲2k,2k+1.
4,二叉樹分類:滿二叉樹,完全二叉樹,平衡二叉樹。
滿二叉樹:除了葉子結點以外所有的結點都必須滿足度最大,即,一個深度爲k的滿二叉樹,其包含的葉子結點數爲(2^k )-1。滿二叉樹即每個非葉子節點的左右子樹均在。
完全二叉樹:除了深度最大的一層以外,其他每層結點都必須均在,層數爲k的完全二叉樹的每個節點的編號,與層數爲k的滿二叉樹的結點編號一一對應。
滿二叉樹必爲完全二叉樹,完全二叉樹不一定爲滿二叉樹。
二叉樹的創建:
public static Tree createTree(int [] array){
ArrayList<Tree> list = new ArrayList<>();
for (int i = 0; i < array.length; i++) {
list.add(new Tree(array[i]));
}
Tree root = list.get(0);
for (int i = 0; i < list.size()/2; i++) {
list.get(i).setLeft(list.get(2*i + 1));
if(i*2 + 2 < list.size()){
list.get(i).setRight(list.get(2*i + 2));
}
}
return root;
}
二叉樹的遍歷:
深度優先,廣度優先
前序中序和後序。
深度優先遍歷使用棧,廣度優先遍歷使用隊列。
public static void DepthFirstSearch(Tree root){
Stack<Tree> stack = new Stack<>();
stack.push(root);
while(!stack.empty()){
Tree temp = stack.pop();
System.out.println(temp.getVal());
if(temp.getRight() != null){
stack.push(temp.getRight());
}
if(temp.getLeft() != null){
stack.push(temp.getLeft());
}
}
//原樹 6 5 4 3 2 1 0
//6 5 3 2 4 1 0
深度優先即先左後右,則在遍歷的時候,現將根節點打印之後,將根節點的右子樹壓入棧中,再將左子樹壓入棧中。利用棧的性質進行遍歷。
廣度優先使用隊列,先進先出。
public static void breadthFirstSearch(Tree root){
Queue<Tree> queue = new LinkedList<>();
queue.offer(root);
while(queue.size() != 0){
Tree temp = queue.poll(); //取出第一個元素並刪除
System.out.print(temp.getVal() + " ");
if(temp.getLeft() != null){
queue.offer(temp.getLeft());
}
if(temp.getRight() != null){
queue.offer(temp.getRight());
}
}
}
先序遍歷:根 ->左->右 和深度遍歷一致。
中序遍歷:左 ->根->右
後序遍歷 :左->右->跟
//二叉樹中序遍歷 左 根 右
public static void inorderTraversal(Tree root){
if(root == null){
return;
}
Stack<Tree> stack = new Stack<Tree>();
Tree p = root;
while(p != null || !stack.empty()){
while(p != null){
stack.push(p);
p = p.getLeft();
}//將該節點壓入棧並且其所有左結點都壓入
p = stack.pop();
System.out.print(p.getVal() + " ");
p = p.getRight();
}
}
// 二叉樹後序遍歷
public static void postOrderTraversal(Tree root){
if(root == null){
return;
}
//利用兩個棧 對於第一個棧入得順序是跟左右 入第二個棧的順序是 跟右左 出棧順序 左右根
Stack<Tree> stack1 = new Stack<>();
Stack<Tree> stack2 = new Stack<>();
stack1.push(root);
while(!stack1.empty()){
Tree node = stack1.pop();
stack2.push(node);
if(node.getLeft() != null){
stack1.push(node.getLeft());
}
if(node.getRight() != null){
stack1.push(node.getRight());
}
}
while(!stack2.empty()){
System.out.print(stack2.pop().getVal() + " ");
}
}