日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二叉树介绍与代码实现

發布時間:2024/7/5 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树介绍与代码实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

      • 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 樹的基本術語
  • 結點:樹的數據元素
  • 結點的度:該結點的分支的個數
  • 樹的度:樹中所有結點的度的最大值
  • 結點的層次:從根到該結點的層數(根結點算第一層)
  • 樹的深度:所有結點的層次的最大值
  • 根結點:在非空樹中,無前驅結點的結點
  • 分支結點:度不為0的結點
  • 葉結點:度為0的結點
  • 孩子結點:結點的子樹的根
  • 雙親結點:孩子結點的根結點
  • 兄弟結點:具有共同雙親的結點
  • 堂兄弟結點:雙親互為兄弟的結點
  • 祖先結點:從根到該結點的所經歷的所有結點
  • 子孫結點:以某結點為根的子樹中的任一結點
  • 1.4 二叉樹的遞歸定義

    二叉樹是結點的有限集合,這個有限集,或為空集,或由一個根結點及兩棵互不相交的,分別叫作這個根的左子樹和右子樹的二叉樹組成。

    【注意】二叉樹不是樹的特殊情況。

    1.5 存儲方法

    雙親表示法——求父結點方便
    孩子表示法——求子結點方便
    雙親孩子表示法—求父結點和子結點方便
    二叉樹表示法——把一個普通樹轉化成二叉樹來存儲

    1.6 滿二叉樹VS完全二叉樹

    滿二叉樹

    • 定義:深為k且有2k?12^k-12k?1個結點的二叉樹。
    • 編號:約定編號從根開始,自上而下,自左而右,給二叉樹中的每個結點一個從1開始的連續的編號。

    完全二叉樹

    • 定義:深為k且有n個結點的二叉樹,當且僅當其每一個結點都與深度為k的滿二叉樹中編號從1至n的結點一一對應。

    滿二叉樹是完全二叉樹,反之則不一定!

    2 二叉樹的性質

  • 在二叉樹的第 i 層上至多有 2i?12^{i-1}2i?1個結點 (i≥1i\geq1i1)
  • 證明:
    (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)由歸納法,即得證。


  • 深度為 k 的二叉樹至多有2k?12^k-12k?1個節點(k≥1k\geq1k1)
  • 20+21+…+2k-1=2k-1(利用等比數列求和公式得到結果)


  • 對任何一顆二叉樹 T,如果其終端結點樹為 n0n_0n0?,度為 2 的結點數為 n2n_2n2?,則 n0n_0n0? = n2n_2n2?+1
  • 證明:
    終端結點數就是葉結點數了,而一顆二叉樹,除了葉結點外,剩下的就是度為 12 的結點數了,我們設 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


  • 具有 n 個結點的完全二叉樹的深度為 [log?2n][\log_2 n][log2?n] + 1 ,([x]代表不大于 x 的最大整數)
  • 證明:
    1)對于滿二叉樹,深度為 k 的滿二叉樹至多有2k?12^k-12k?1個節點(k≥1k\geq1k1)
    那么由:

    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<n2k?1

    所以

    2i?1≤n<2k2^{i-1}\leq n < 2^k2i?1n<2k

    兩邊取對數:

    2i?1≤n<2k2^{i-1}\leq n < 2^k2i?1n<2k

    k 又是整數:

    k=[log?2n]+1k = [\log_2 n] + 1k=[log2?n]+1


  • 對于一個有 n 個結點的完全二叉樹(或滿二叉樹)的結點按層序順序從左到右編號,對任意結點 i 有:
  • 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; }

    運行結果:

    總結

    以上是生活随笔為你收集整理的二叉树介绍与代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。