欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C 語(yǔ)言二叉樹(shù)幾種遍歷方法詳解及實(shí)例

 更新時(shí)間:2017年01月08日 10:45:05   作者:小_馬  
這篇文章主要介紹了C 語(yǔ)言二叉樹(shù)幾種遍歷方法詳解及實(shí)例的相關(guān)資料,二叉樹(shù)在數(shù)據(jù)結(jié)構(gòu)當(dāng)中是非常重要的知識(shí)要點(diǎn),這里對(duì)二叉樹(shù)進(jìn)行了總結(jié),需要的朋友可以參考下

二叉樹(shù)的一些概念

二叉樹(shù)就是每個(gè)結(jié)點(diǎn)最多有兩個(gè)子樹(shù)的樹(shù)形存儲(chǔ)結(jié)構(gòu)。先上圖,方便后面分析。


 1 滿(mǎn)二叉樹(shù)和完全二叉樹(shù) 

上圖就是典型的二叉樹(shù),其中左邊的圖還叫做滿(mǎn)二叉樹(shù),右邊是完全二叉樹(shù)。然后我們可以得出結(jié)論,滿(mǎn)二叉樹(shù)一定是完全二叉樹(shù),但是反過(guò)來(lái)就不一定。滿(mǎn)二叉樹(shù)的定義是除了葉子結(jié)點(diǎn),其它結(jié)點(diǎn)左右孩子都有,深度為k的滿(mǎn)二叉樹(shù),結(jié)點(diǎn)數(shù)就是2的k次方減1。完全二叉樹(shù)是每個(gè)結(jié)點(diǎn)都與深度為k的滿(mǎn)二叉樹(shù)中編號(hào)從1到n一一對(duì)應(yīng)。

 2 樹(shù)的深度

樹(shù)的最大層次就是深度,比如上圖,深度是4。很容易得出,深度為k的樹(shù),擁有的最大結(jié)點(diǎn)數(shù)是2的k次方減1。

 3 樹(shù)的孩子,兄弟,雙親

上圖中,B,C是A的孩子,B,C之間互為兄弟,A是B,C的雙親。

 二如何創(chuàng)建二叉樹(shù)

先說(shuō)說(shuō)二叉樹(shù)的存儲(chǔ)結(jié)構(gòu),跟很多其它模型一樣,也有順序和鏈?zhǔn)絻煞N方式。前者雖然使用簡(jiǎn)單,但是存在浪費(fèi)空間的問(wèn)題,舉個(gè)例子,下圖的二叉樹(shù),用順序的方式存儲(chǔ)(0表示空,沒(méi)有子樹(shù))是:

1 2 3 4 5 6 7 0 0 0 0 8 0 0 0


 是不是相當(dāng)浪費(fèi)空間呢。

 鏈?zhǔn)浇Y(jié)構(gòu)可以定義如下:

typedef struct _BiTNode 
{ 
  int data; 
  _BiTNode *leftChild; 
  _BiTNode *rightChild; 
}BiTNode, *pBiTree; 

然后就可以寫(xiě)一個(gè)函數(shù)來(lái)創(chuàng)建二叉樹(shù),過(guò)程是在控制臺(tái)輸入a表示退出當(dāng)前這一層,不再為該層創(chuàng)建左右孩子。輸入其它字母表示繼續(xù)創(chuàng)建。比如下面的輸入序列:


 創(chuàng)建了如下結(jié)構(gòu)的二叉樹(shù),


 每個(gè)結(jié)點(diǎn)里的數(shù)值是隨機(jī)生成的小于100的數(shù)字。同時(shí)我也寫(xiě)了一個(gè)自動(dòng)的命令序列函數(shù),方便測(cè)試,不用手動(dòng)輸入,非自動(dòng)和自動(dòng)創(chuàng)建的函數(shù)如下:

//創(chuàng)建二叉樹(shù), 先序順序 
int CreateBiTree(pBiTree *root) 
{ 
  char ch = 0; 
  fflush(stdin); 
  if ((ch = getchar()) == 'a')//控制樹(shù)的結(jié)構(gòu) 
  { 
    *root = NULL; 
  } 
  else 
  { 
    *root = (BiTNode *)malloc(sizeof(BiTNode)); 
    if (!(*root)) 
    { 
      return RET_ERROR; 
    } 
    (*root)->data = GetRandom(); 
    CreateBiTree(&(*root)->leftChild); 
    CreateBiTree(&(*root)->rightChild); 
  } 
  return RET_OK; 
} 
 
int g_i = 0; 
//創(chuàng)建二叉樹(shù),自動(dòng)執(zhí)行,方便測(cè)試 
int CreateBiTreeAuto(pBiTree *root) 
{ 
  char szOrder[] = "bbaabaa"; 
  char ch = 0; 
  if (szOrder[g_i++] == 'a')//控制樹(shù)的結(jié)構(gòu) 
  { 
    *root = NULL; 
  } 
  else 
  { 
    *root = (BiTNode *)malloc(sizeof(BiTNode)); 
    if (!(*root)) 
    { 
      return RET_ERROR; 
    } 
    (*root)->data = GetRandom(); 
    CreateBiTreeAuto(&(*root)->leftChild); 
    CreateBiTreeAuto(&(*root)->rightChild); 
  } 
  return RET_OK; 
} 

三遍歷順序

先序遍歷

先序遍歷是先訪(fǎng)問(wèn)根結(jié)點(diǎn),再左子樹(shù),再右子樹(shù),比如圖1中的右圖,先序遍歷的輸出如下:

A,B,D,H,I,E,J,K,C,F,G

根據(jù)上面的思想,很容易用遞歸的形式寫(xiě)出先序遍歷的代碼:

//先序遍歷 
int PreOrderVisitTree(pBiTree T, VisitType pFuncVisit) 
{ 
  if (T) 
  { 
    (*pFuncVisit)(T->data); 
    if (PreOrderVisitTree(T->leftChild, pFuncVisit) == RET_OK) 
    { 
      if (PreOrderVisitTree(T->rightChild, pFuncVisit) == RET_OK) 
      { 
        return RET_OK; 
      } 
    } 
    return RET_ERROR; 
  } 
  else 
  { 
    return RET_OK; 
  } 
} 

中序遍歷和后序遍歷

有了先序的經(jīng)驗(yàn),這兩個(gè)就很好理解了,中序是先訪(fǎng)問(wèn)左子樹(shù), 再根結(jié)點(diǎn),再右子樹(shù), 后序是先訪(fǎng)問(wèn)左子樹(shù), 再右子樹(shù),再根結(jié)點(diǎn)。代碼更容易,只要改一下調(diào)用順序就可以了。

不過(guò)我這里給出一種非遞歸的實(shí)現(xiàn)。遞歸固然是清晰明了,但是存在效率低的問(wèn)題,非遞歸的方案用棧結(jié)構(gòu)來(lái)存結(jié)點(diǎn)信息,通過(guò)出棧訪(fǎng)問(wèn)來(lái)遍歷二叉樹(shù)。它思想是這樣的,當(dāng)棧頂中的指針?lè)强諘r(shí),遍歷左子樹(shù),也就是左子樹(shù)根的指針進(jìn)棧。當(dāng)棧頂指針為空時(shí),應(yīng)退至上一層,如果是從左子樹(shù)返回的,訪(fǎng)問(wèn)當(dāng)前層,也就是棧頂中的根指針結(jié)點(diǎn)。如果是從右子樹(shù)返回,說(shuō)明當(dāng)前層遍歷完畢,繼續(xù)退棧。代碼如下:

//中序遍歷, 非遞歸實(shí)現(xiàn) 
int InOrderVisitTree(pBiTree T, VisitType pFuncVisit) 
{ 
  ponyStack binaryTreeStack; 
  InitStack(&binaryTreeStack, 4); 
  Push(&binaryTreeStack, &T); 
  pBiTree pTempNode; 
 
  while (!IsEmptyStack(binaryTreeStack)) 
  { 
    while((GetTop(binaryTreeStack, &pTempNode) == RET_OK) && (pTempNode != NULL)) 
    { 
      Push(&binaryTreeStack, &(pTempNode->leftChild)); 
    } 
    Pop(&binaryTreeStack, &pTempNode); 
    if (!IsEmptyStack(binaryTreeStack)) 
    { 
      Pop(&binaryTreeStack, &pTempNode); 
      (*pFuncVisit)(pTempNode->data); 
      Push(&binaryTreeStack, &(pTempNode->rightChild)); 
    } 
  } 
  return RET_OK; 
} 

代碼下載地址:http://xiazai.jb51.net/201701/yuanma/BinaryTreeDemo-master(jb51.net).rar

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

相關(guān)文章

  • C語(yǔ)言 奇偶排序算法詳解及實(shí)例代碼

    C語(yǔ)言 奇偶排序算法詳解及實(shí)例代碼

    這篇文章主要介紹了C語(yǔ)言 奇偶排序算法詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • C++使用泛型導(dǎo)致的膨脹問(wèn)題

    C++使用泛型導(dǎo)致的膨脹問(wèn)題

    這篇文章主要介紹了C++使用泛型導(dǎo)致的膨脹,智能家居主機(jī)的嵌入式平臺(tái)上使用C++進(jìn)行開(kāi)發(fā)。FLASH存儲(chǔ)空間有限,這是必須要考慮的因素,一定要重視,下面我們一起進(jìn)入文章看看詳細(xì)內(nèi)容
    2021-11-11
  • C語(yǔ)言實(shí)現(xiàn)撲克牌計(jì)算24點(diǎn)

    C語(yǔ)言實(shí)現(xiàn)撲克牌計(jì)算24點(diǎn)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言如何實(shí)現(xiàn)撲克牌計(jì)算24點(diǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • C語(yǔ)言實(shí)現(xiàn)從文件讀入一個(gè)3*3數(shù)組,并計(jì)算每行的平均值

    C語(yǔ)言實(shí)現(xiàn)從文件讀入一個(gè)3*3數(shù)組,并計(jì)算每行的平均值

    今天小編就為大家分享一篇C語(yǔ)言實(shí)現(xiàn)從文件讀入一個(gè)3*3數(shù)組,并計(jì)算每行的平均值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-12
  • C語(yǔ)言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用椎棧

    C語(yǔ)言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用椎棧

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用椎棧,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 關(guān)于C語(yǔ)言除0引發(fā)的思考

    關(guān)于C語(yǔ)言除0引發(fā)的思考

    很多 C 庫(kù)都提供了一組函數(shù)用來(lái)判斷一個(gè)浮點(diǎn)數(shù)是否是無(wú)窮大或 NaN。int _isnan(double x) 函數(shù)用來(lái)判斷一個(gè)浮點(diǎn)數(shù)是否是 NaN,而 int _finite(double x) 用以判斷一個(gè)浮點(diǎn)數(shù)是否是無(wú)窮大
    2013-08-08
  • C++中訪(fǎng)問(wèn)權(quán)限的示例詳解

    C++中訪(fǎng)問(wèn)權(quán)限的示例詳解

    C++通過(guò) public、protected、private 三個(gè)關(guān)鍵字來(lái)控制成員變量和成員函數(shù)的訪(fǎng)問(wèn)權(quán)限(也稱(chēng)為可見(jiàn)性),下面這篇文章主要給大家介紹了關(guān)于C++中訪(fǎng)問(wèn)權(quán)限的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • 實(shí)例詳解C++中指針與引用的區(qū)別

    實(shí)例詳解C++中指針與引用的區(qū)別

    引用是C++引入的重要機(jī)制(C語(yǔ)言沒(méi)有引用),它使原來(lái)在C中必須用指針來(lái)實(shí)現(xiàn)的功能有了另一種實(shí)現(xiàn)的選擇,在書(shū)寫(xiě)形式上更為簡(jiǎn)潔,那么引用的本質(zhì)是什么,它與指針又有什么關(guān)系呢?這篇文章主要給大家介紹了關(guān)于C++中指針與引用的區(qū)別,需要的朋友可以參考下
    2021-07-07
  • C++中實(shí)現(xiàn)fibonacci數(shù)列的幾種方法

    C++中實(shí)現(xiàn)fibonacci數(shù)列的幾種方法

    本文主要介紹了C++中實(shí)現(xiàn)fibonacci數(shù)列的幾種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 簡(jiǎn)單談?wù)凜++ 頭文件系列之(iosfwd)

    簡(jiǎn)單談?wù)凜++ 頭文件系列之(iosfwd)

    本文給大家分享的是小編關(guān)于頭文件系列的(iosfwd)的簡(jiǎn)單講解,所謂iosfwd,其實(shí)就是“input output stream forward”,下面我們來(lái)詳細(xì)看看
    2017-02-02

最新評(píng)論