二叉树介绍与代码实现
文章目錄
- 1 樹(shù)的基本概念
- 1.1 樹(shù)的形式定義
- 1.2 樹(shù)的遞歸定義
- 1.3 樹(shù)的基本術(shù)語(yǔ)
- 1.4 二叉樹(shù)的遞歸定義
- 1.5 存儲(chǔ)方法
- 1.6 滿二叉樹(shù)VS完全二叉樹(shù)
- 2 二叉樹(shù)的性質(zhì)
- 3 代碼實(shí)現(xiàn)
1 樹(shù)的基本概念
1.1 樹(shù)的形式定義
T={D,R}- D為樹(shù)T中包含n個(gè)結(jié)點(diǎn)的有限集合,R為樹(shù)中結(jié)點(diǎn)之間關(guān)系的集合。
- 當(dāng)n=0時(shí),樹(shù)為空樹(shù);當(dāng)n>0時(shí),R是D上某個(gè)二元關(guān)系的集合,滿足以下條件:
- 有且僅有一個(gè)結(jié)點(diǎn),稱為根結(jié)點(diǎn),該結(jié)點(diǎn)沒(méi)有直接前驅(qū)結(jié)點(diǎn);
- 除根結(jié)點(diǎn)外,每個(gè)結(jié)點(diǎn)有且僅有一個(gè)前驅(qū)結(jié)點(diǎn);
- D中每個(gè)結(jié)點(diǎn)可以有零個(gè)或多個(gè)后繼結(jié)點(diǎn);
1.2 樹(shù)的遞歸定義
- 樹(shù)是由n(n≥0)個(gè)結(jié)點(diǎn)組成的有限集T。
- 當(dāng)n=0時(shí),它是一個(gè)空樹(shù);當(dāng)n>0時(shí),它滿足兩個(gè)條件:
- 有且僅有一個(gè)特定的結(jié)點(diǎn),稱為根結(jié)點(diǎn)。
- 除根結(jié)點(diǎn)以外的其余結(jié)點(diǎn)分為m個(gè)(m≥0)互不相交的有限集T1、T2、……Tm,其中每個(gè)集合又都是一棵樹(shù),稱T1、T2、……Tm為根結(jié)點(diǎn)的子樹(shù)。
1.3 樹(shù)的基本術(shù)語(yǔ)
1.4 二叉樹(shù)的遞歸定義
二叉樹(shù)是結(jié)點(diǎn)的有限集合,這個(gè)有限集,或?yàn)榭占?#xff0c;或由一個(gè)根結(jié)點(diǎn)及兩棵互不相交的,分別叫作這個(gè)根的左子樹(shù)和右子樹(shù)的二叉樹(shù)組成。
【注意】二叉樹(shù)不是樹(shù)的特殊情況。
1.5 存儲(chǔ)方法
雙親表示法——求父結(jié)點(diǎn)方便
孩子表示法——求子結(jié)點(diǎn)方便
雙親孩子表示法—求父結(jié)點(diǎn)和子結(jié)點(diǎn)方便
二叉樹(shù)表示法——把一個(gè)普通樹(shù)轉(zhuǎn)化成二叉樹(shù)來(lái)存儲(chǔ)
1.6 滿二叉樹(shù)VS完全二叉樹(shù)
滿二叉樹(shù)
- 定義:深為k且有2k?12^k-12k?1個(gè)結(jié)點(diǎn)的二叉樹(shù)。
- 編號(hào):約定編號(hào)從根開(kāi)始,自上而下,自左而右,給二叉樹(shù)中的每個(gè)結(jié)點(diǎn)一個(gè)從1開(kāi)始的連續(xù)的編號(hào)。
完全二叉樹(shù)
- 定義:深為k且有n個(gè)結(jié)點(diǎn)的二叉樹(shù),當(dāng)且僅當(dāng)其每一個(gè)結(jié)點(diǎn)都與深度為k的滿二叉樹(shù)中編號(hào)從1至n的結(jié)點(diǎn)一一對(duì)應(yīng)。
滿二叉樹(shù)是完全二叉樹(shù),反之則不一定!
2 二叉樹(shù)的性質(zhì)
證明:
(1)i=1時(shí),只有一個(gè)根結(jié)點(diǎn),2i?12^{i-1}2i?1 =202^020= 1,結(jié)論正確;
(2)假設(shè)n=k-1命題成立,即第k-1層上至多有 2k?22^{k-2}2k?2 個(gè)結(jié)點(diǎn),則當(dāng)n=k時(shí),每個(gè)結(jié)點(diǎn)至多有兩棵子樹(shù);
則k層結(jié)點(diǎn)最多為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 個(gè)結(jié)點(diǎn);
(3)由歸納法,即得證。
20+21+…+2k-1=2k-1(利用等比數(shù)列求和公式得到結(jié)果)
證明:
終端結(jié)點(diǎn)數(shù)就是葉結(jié)點(diǎn)數(shù)了,而一顆二叉樹(shù),除了葉結(jié)點(diǎn)外,剩下的就是度為 1 和 2 的結(jié)點(diǎn)數(shù)了,我們?cè)O(shè) n1n_1n1? 為度是 1 的結(jié)點(diǎn)數(shù),則樹(shù) T 的總結(jié)點(diǎn)數(shù)為
n = n0n_0n0? + n1n_1n1? + n2n_2n2?
再換一個(gè)角度,數(shù)一下二叉樹(shù)中連接線的總數(shù),由于根節(jié)點(diǎn)沒(méi)有雙親,所以一個(gè)二叉樹(shù)中,連接線數(shù)等于結(jié)點(diǎn)樹(shù)-1,n1n_1n1? 的度為 1 所以它僅有一條連接線,n2n_2n2?同理,代數(shù)表達(dá)式就是
n?1n-1n?1 = n1n_1n1? +2n22n_22n2?
再結(jié)合等式
n = n0n_0n0? + n1n_1n1? + n2n_2n2?
推導(dǎo)出
n0n_0n0? + n1n_1n1? + n2n_2n2?-1 = n1n_1n1? + 2n22n_22n2?
所以:
n0n_0n0? = n2n_2n2? + 1
證明:
1)對(duì)于滿二叉樹(shù),深度為 k 的滿二叉樹(shù)至多有2k?12^k-12k?1個(gè)節(jié)點(diǎn)(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)對(duì)于完全二叉樹(shù),它的結(jié)點(diǎn)數(shù)一定少于等于同樣深度的滿二叉樹(shù) 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
兩邊取對(duì)數(shù):
2i?1≤n<2k2^{i-1}\leq n < 2^k2i?1≤n<2k
而 k 又是整數(shù):
k=[log?2n]+1k = [\log_2 n] + 1k=[log2?n]+1
1)如果 i = 1,那么結(jié)點(diǎn) i 為該樹(shù)的根,無(wú)雙親;若 i > 1 ,則其雙親是結(jié)點(diǎn) [i/2]
2)如果 2i > n,則結(jié)點(diǎn)無(wú)左孩子(結(jié)點(diǎn) i 為葉子結(jié)點(diǎn)),否則其左孩子結(jié)點(diǎn)是 2i
3)如果 2i + 1 > n,則結(jié)點(diǎn) i 無(wú)右孩子,否則其右孩子是結(jié)點(diǎn) 2i + 1
3 代碼實(shí)現(xiàn)
創(chuàng)建二叉樹(shù):
#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; }運(yùn)行結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的二叉树介绍与代码实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 战略性基础研究的由来及国际实践研究
- 下一篇: www.sirim-global.com