91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言中二叉樹有哪些遍歷方法

發布時間:2021-07-24 14:29:55 來源:億速云 閱讀:152 作者:小新 欄目:編程語言

這篇文章將為大家詳細講解有關C語言中二叉樹有哪些遍歷方法,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

二叉樹的一些概念

二叉樹就是每個結點最多有兩個子樹的樹形存儲結構。先上圖,方便后面分析。

C語言中二叉樹有哪些遍歷方法

 1 滿二叉樹和完全二叉樹 

上圖就是典型的二叉樹,其中左邊的圖還叫做滿二叉樹,右邊是完全二叉樹。然后我們可以得出結論,滿二叉樹一定是完全二叉樹,但是反過來就不一定。滿二叉樹的定義是除了葉子結點,其它結點左右孩子都有,深度為k的滿二叉樹,結點數就是2的k次方減1。完全二叉樹是每個結點都與深度為k的滿二叉樹中編號從1到n一一對應。

 2 樹的深度

樹的最大層次就是深度,比如上圖,深度是4。很容易得出,深度為k的樹,擁有的最大結點數是2的k次方減1。

 3 樹的孩子,兄弟,雙親

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

 二如何創建二叉樹

先說說二叉樹的存儲結構,跟很多其它模型一樣,也有順序和鏈式兩種方式。前者雖然使用簡單,但是存在浪費空間的問題,舉個例子,下圖的二叉樹,用順序的方式存儲(0表示空,沒有子樹)是:

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

C語言中二叉樹有哪些遍歷方法

 是不是相當浪費空間呢。

 鏈式結構可以定義如下:

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

然后就可以寫一個函數來創建二叉樹,過程是在控制臺輸入a表示退出當前這一層,不再為該層創建左右孩子。輸入其它字母表示繼續創建。比如下面的輸入序列:

C語言中二叉樹有哪些遍歷方法

 創建了如下結構的二叉樹,

C語言中二叉樹有哪些遍歷方法

 每個結點里的數值是隨機生成的小于100的數字。同時我也寫了一個自動的命令序列函數,方便測試,不用手動輸入,非自動和自動創建的函數如下:

//創建二叉樹, 先序順序 
int CreateBiTree(pBiTree *root) 
{ 
  char ch = 0; 
  fflush(stdin); 
  if ((ch = getchar()) == 'a')//控制樹的結構 
  { 
    *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; 
//創建二叉樹,自動執行,方便測試 
int CreateBiTreeAuto(pBiTree *root) 
{ 
  char szOrder[] = "bbaabaa"; 
  char ch = 0; 
  if (szOrder[g_i++] == 'a')//控制樹的結構 
  { 
    *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; 
}

三遍歷順序

先序遍歷

先序遍歷是先訪問根結點,再左子樹,再右子樹,比如圖1中的右圖,先序遍歷的輸出如下:

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

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

//先序遍歷 
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; 
  } 
}

中序遍歷和后序遍歷

有了先序的經驗,這兩個就很好理解了,中序是先訪問左子樹, 再根結點,再右子樹, 后序是先訪問左子樹, 再右子樹,再根結點。代碼更容易,只要改一下調用順序就可以了。

不過我這里給出一種非遞歸的實現。遞歸固然是清晰明了,但是存在效率低的問題,非遞歸的方案用棧結構來存結點信息,通過出棧訪問來遍歷二叉樹。它思想是這樣的,當棧頂中的指針非空時,遍歷左子樹,也就是左子樹根的指針進棧。當棧頂指針為空時,應退至上一層,如果是從左子樹返回的,訪問當前層,也就是棧頂中的根指針結點。如果是從右子樹返回,說明當前層遍歷完畢,繼續退棧。代碼如下:

//中序遍歷, 非遞歸實現 
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; 
}

關于“C語言中二叉樹有哪些遍歷方法”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新乐市| 依安县| 古丈县| 佳木斯市| 理塘县| 武功县| 汉川市| 大洼县| 雅安市| 绥芬河市| 铜川市| 奉化市| 祥云县| 汪清县| 铁力市| 淮南市| 苏州市| 台州市| 乾安县| 仙游县| 进贤县| 孙吴县| 武邑县| 塘沽区| 久治县| 织金县| 瑞金市| 琼中| 商洛市| 龙南县| 景东| 道孚县| 静乐县| 四川省| 嘉荫县| 小金县| 鄂尔多斯市| 蓬安县| 隆化县| 金乡县| 白朗县|