二叉樹的一些學習
轉:https://xiaozhuanlan.com/topic/5036471892
二叉樹性質
1)在二叉樹的第i層上最多有2i-1 個節點 。(i>=1)
2)二叉樹中如果深度為k,那麼最多有2k-1個節點。(k>=1)
3)n0=n2+1 n0表示度數為0的節點數,n2表示度數為2的節點數。
4)在完全二叉樹中,具有n個節點的完全二叉樹的深度為[log2n]+1,其中[log2n]是向下取整。
5)若對含 n 個結點的完全二叉樹從上到下且從左至右進行 1 至 n 的編號,則對完全二叉樹中任意一個編號為 i 的結點有如下特性:
(1) 若 i=1,則該結點是二叉樹的根,無雙親, 否則,編號為 [i/2] 的結點為其雙親結點;
(2) 若 2i>n,則該結點無左孩子, 否則,編號為 2i 的結點為其左孩子結點;
(3) 若 2i+1>n,則該結點無右孩子結點, 否則,編號為2i+1 的結點為其右孩子結點。
二叉樹遍歷
前序遍歷 :通俗的說就是從二叉樹的根結點出發,當第一次到達結點時就輸出結點資料,按照先向左再向右的方向訪問。
中序遍歷 :就是從二叉樹的根結點出發,當第二次到達結點時就輸出結點資料,按照先向左再向右的方向訪問。
後序遍歷 :就是從二叉樹的根結點出發,當第三次到達結點時就輸出結點資料,按照先向左再向右的方向訪問。
層序遍歷 :層次遍歷就是按照樹的層次自上而下的遍歷二叉樹。
*雖然二叉樹的遍歷過程看似繁瑣,但是由於二叉樹是一種遞迴定義的結構,故採用遞迴方式遍歷二叉樹的程式碼十分簡單。
void PreOrderTraverse(BiTree T) { if(T==NULL) return; printf("%c", T->data); /*顯示結點資料,可以更改為其他對結點操作*/ PreOrderTraverse(T->lchild); /*再先序遍歷左子樹*/ PreOrderTraverse(T->rchild); /*最後先序遍歷右子樹*/ } /*二叉樹的中序遍歷遞迴演算法*/ void InOrderTraverse(BiTree T) { if(T==NULL) return; InOrderTraverse(T->lchild); /*中序遍歷左子樹*/ printf("%c", T->data); /*顯示結點資料,可以更改為其他對結點操作*/ InOrderTraverse(T->rchild); /*最後中序遍歷右子樹*/ } /*二叉樹的後序遍歷遞迴演算法*/ void PostOrderTraverse(BiTree T) { if(T==NULL) return; PostOrderTraverse(T->lchild); /*先後序遍歷左子樹*/ PostOrderTraverse(T->rchild); /*再後續遍歷右子樹*/ printf("%c", T->data); /*顯示結點資料,可以更改為其他對結點操作*/ }
將二叉樹按中序遍歷得到一個有序的陣列結果,某個節點元素的前後相鄰的節點即為前驅節點,後區節點
前驅節點
1:如果當前節點的左子樹不為空,那麼該點的前驅節點為該點左子樹中最右的節點。
2:如果當前節點的左子樹為空,那麼該點的前驅節點為從該點往上延伸,如果延伸到的點為其父親節點的右孩子,那麼這個父親節點就是該點的前驅節點。
後驅節點
1:如果當前節點的右子樹不為空,那麼該點的後驅節點為該點右子樹中最左的節點。
2:如果當前節點的右子樹為空,那麼該點的後驅節點為從該點往上延伸,如果延伸到的點為其父親節點的左孩子,那麼這個父親節點就是該點的後驅節點。
struct node { node left;//左孩子 node right;//右孩子 node parent;//父親節點 int value; }; node getfristornode(node heap)//heap代表當前要找前驅節點的節點 { if(heap==null)//如果當前節點為空,返回空 return heap; if(heap.left!=null)//如果當前節點左子樹不為空,那麼該節點的後繼節點為左子樹中最右的節點 return getrightmost(heap.left);//找到左子數樹中最右的節點,並返回 else //如果程式到達這裡,說明當前節點的左子數為空 { node parent=heap.parent; //第一個條件就是判斷那種特殊情況的,一直延伸到當前節點沒有父親節點時,那麼parent為空,這個條件不滿足,函式返回空 //第二個條件是判斷當前節點是否為該父親節點的右孩子,如果不是,繼續執行下面的程式碼,如果是,說明這個父親節點就是heap節點的前驅節點 while (parent!=null&&heap!=parent.right) { heap=parent; parent=heap.parent; } return parent; } } //這個函式是求左子樹中最右的節點的函式 getrightmost(node heap) { while (heap!=null) heap=heap.right; return heap.parent; }
上面是前驅節點的查詢方式,後區節點基本相同,左右換下。