二叉树介绍与代码实现
文章目錄
- 1 樹的基本概念
- 1.1 樹的形式定義
- 1.2 樹的遞歸定義
- 1.3 樹的基本術語
- 1.4 二叉樹的遞歸定義
- 1.5 存儲方法
- 1.6 滿二叉樹VS完全二叉樹
- 2 二叉樹的性質
- 3 代碼實現
1 樹的基本概念
1.1 樹的形式定義
T={D,R}- D為樹T中包含n個結點的有限集合,R為樹中結點之間關系的集合。
- 當n=0時,樹為空樹;當n>0時,R是D上某個二元關系的集合,滿足以下條件:
- 有且僅有一個結點,稱為根結點,該結點沒有直接前驅結點;
- 除根結點外,每個結點有且僅有一個前驅結點;
- D中每個結點可以有零個或多個后繼結點;
1.2 樹的遞歸定義
- 樹是由n(n≥0)個結點組成的有限集T。
- 當n=0時,它是一個空樹;當n>0時,它滿足兩個條件:
- 有且僅有一個特定的結點,稱為根結點。
- 除根結點以外的其余結點分為m個(m≥0)互不相交的有限集T1、T2、……Tm,其中每個集合又都是一棵樹,稱T1、T2、……Tm為根結點的子樹。
1.3 樹的基本術語
1.4 二叉樹的遞歸定義
二叉樹是結點的有限集合,這個有限集,或為空集,或由一個根結點及兩棵互不相交的,分別叫作這個根的左子樹和右子樹的二叉樹組成。
【注意】二叉樹不是樹的特殊情況。
1.5 存儲方法
雙親表示法——求父結點方便
孩子表示法——求子結點方便
雙親孩子表示法—求父結點和子結點方便
二叉樹表示法——把一個普通樹轉化成二叉樹來存儲
1.6 滿二叉樹VS完全二叉樹
滿二叉樹
- 定義:深為k且有2k?12^k-12k?1個結點的二叉樹。
- 編號:約定編號從根開始,自上而下,自左而右,給二叉樹中的每個結點一個從1開始的連續的編號。
完全二叉樹
- 定義:深為k且有n個結點的二叉樹,當且僅當其每一個結點都與深度為k的滿二叉樹中編號從1至n的結點一一對應。
滿二叉樹是完全二叉樹,反之則不一定!
2 二叉樹的性質
證明:
(1)i=1時,只有一個根結點,2i?12^{i-1}2i?1 =202^020= 1,結論正確;
(2)假設n=k-1命題成立,即第k-1層上至多有 2k?22^{k-2}2k?2 個結點,則當n=k時,每個結點至多有兩棵子樹;
則k層結點最多為k-1層的2倍,故s<=2?2k?2=2k?1s<=2*2^{k-2}=2^{k-1}s<=2?2k?2=2k?1,第i層至多有 2i?12^{i-1}2i?1 個結點;
(3)由歸納法,即得證。
20+21+…+2k-1=2k-1(利用等比數列求和公式得到結果)
證明:
終端結點數就是葉結點數了,而一顆二叉樹,除了葉結點外,剩下的就是度為 1 和 2 的結點數了,我們設 n1n_1n1? 為度是 1 的結點數,則樹 T 的總結點數為
n = n0n_0n0? + n1n_1n1? + n2n_2n2?
再換一個角度,數一下二叉樹中連接線的總數,由于根節點沒有雙親,所以一個二叉樹中,連接線數等于結點樹-1,n1n_1n1? 的度為 1 所以它僅有一條連接線,n2n_2n2?同理,代數表達式就是
n?1n-1n?1 = n1n_1n1? +2n22n_22n2?
再結合等式
n = n0n_0n0? + n1n_1n1? + n2n_2n2?
推導出
n0n_0n0? + n1n_1n1? + n2n_2n2?-1 = n1n_1n1? + 2n22n_22n2?
所以:
n0n_0n0? = n2n_2n2? + 1
證明:
1)對于滿二叉樹,深度為 k 的滿二叉樹至多有2k?12^k-12k?1個節點(k≥1k\geq1k≥1)
那么由:
n=2k?1n=2^k-1n=2k?1
可以倒推
k=log?2(n+1)k=\log_2(n+1)k=log2?(n+1)
2)對于完全二叉樹,它的結點數一定少于等于同樣深度的滿二叉樹 2k?12^k-12k?1,但一定多于 2i?1?12^{i-1}-12i?1?1,即:
2i?1?1<n≤2k?12^{i-1}-1<n\leq2^k-12i?1?1<n≤2k?1
所以
2i?1≤n<2k2^{i-1}\leq n < 2^k2i?1≤n<2k
兩邊取對數:
2i?1≤n<2k2^{i-1}\leq n < 2^k2i?1≤n<2k
而 k 又是整數:
k=[log?2n]+1k = [\log_2 n] + 1k=[log2?n]+1
1)如果 i = 1,那么結點 i 為該樹的根,無雙親;若 i > 1 ,則其雙親是結點 [i/2]
2)如果 2i > n,則結點無左孩子(結點 i 為葉子結點),否則其左孩子結點是 2i
3)如果 2i + 1 > n,則結點 i 無右孩子,否則其右孩子是結點 2i + 1
3 代碼實現
創建二叉樹:
#include <stdio.h> #include <stdlib.h>typedef char ElementType; typedef struct Binary {ElementType data;struct Binary *lchild;struct Binary *rchild; } *BinaryTree;/* Recursive implementation 1 */ BinaryTree CreateBinaryTree_1(void) {BinaryTree bt;char ch;scanf("%c", &ch);if (ch == '#') {bt = NULL;} else {bt = (BinaryTree)malloc(sizeof(struct Binary));bt->data = ch;bt->lchild = CreateBinaryTree_1();bt->rchild = CreateBinaryTree_1();}return bt; }/* Recursive implementation 2 */ void CreateBinaryTree_2(BinaryTree *bt) {char ch;scanf("%c", &ch);if (ch == '#') {*bt = NULL;} else {*bt = (BinaryTree)malloc(sizeof(struct Binary));(*bt)->data = ch;CreateBinaryTree_2(&((*bt)->lchild));CreateBinaryTree_2(&((*bt)->rchild));} }void PreviousOrderTraverse(BinaryTree T) {if (T == NULL) {return;}printf("%c", T->data);PreviousOrderTraverse(T->lchild);PreviousOrderTraverse(T->rchild); }int main(void) {BinaryTree bt;// bt = CreateBinaryTree_1();CreateBinaryTree_2(&bt);PreviousOrderTraverse(bt);return 0; }運行結果:
總結
以上是生活随笔為你收集整理的二叉树介绍与代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 战略性基础研究的由来及国际实践研究
- 下一篇: www.sirim-global.com