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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构34:二叉树前序遍历、中序遍历和后序遍历

發(fā)布時間:2024/10/12 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构34:二叉树前序遍历、中序遍历和后序遍历 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

鏈式存儲結(jié)構(gòu)存儲的二叉樹,對樹中結(jié)點進行逐個遍歷時,由于是非線性結(jié)構(gòu),需要找到一種合適的方式遍歷樹中的每個結(jié)點。

遞歸思想遍歷二叉樹

之前講過,樹是由根結(jié)點和子樹部分構(gòu)建的,對于每一棵樹來說,都可以分為 3 部分:左子樹、根結(jié)點和右子樹。所以,可以采用遞歸的思想依次遍歷每個結(jié)點。

根據(jù)訪問結(jié)點時機的不同,分為三種遍歷方式:

  • 先訪問根結(jié)點,再遍歷左右子樹,稱為“先序遍歷”;
  • 遍歷左子樹,之后訪問根結(jié)點,然后遍歷右子樹,稱為“中序遍歷”;
  • 遍歷完左右子樹,再訪問根結(jié)點,稱為“后序遍歷”。

圖1 二叉樹


三種方式唯一的不同就是訪問結(jié)點時機的不同,給出一個二叉樹,首先需要搞清楚三種遍歷方式下訪問結(jié)點的順序。


圖2 二叉樹遍歷示意圖


圖2 中,箭頭線條的走勢為遍歷結(jié)點的過程:

先序遍歷是只要線條走到該結(jié)點的左方位置時,就操作該結(jié)點。所以操作結(jié)點的順序為:

1 2 4 5 3 6 7


中序遍歷是當(dāng)線條越過結(jié)點的左子樹,到達該結(jié)點的正下方時,才操作該結(jié)點。所以操作結(jié)點的順序為:

4 2 5 1 6 3 7


后序遍歷是線條完全走過結(jié)點的左右子樹,到達該結(jié)點的右方范圍時,就開始操作該結(jié)點。所以操作結(jié)點的順序為:

4 5 2 6 7 3 1

三種遍歷方式的完整代碼實現(xiàn)

#include <stdio.h> #include <string.h> #define TElemType int //構(gòu)造結(jié)點的結(jié)構(gòu)體 typedef struct BiTNode
{TElemType data;  
//數(shù)據(jù)域struct BiTNode *lchild, *rchild;  //左右孩子指針 }BiTNode, *BiTree;
//初始化樹的函數(shù) void CreateBiTree(BiTree *T)
{
*T = (BiTNode*)malloc(sizeof(BiTNode));(*T)->data = 1;(*T)->lchild = (BiTNode*)malloc(sizeof(BiTNode));(*T)->rchild = (BiTNode*)malloc(sizeof(BiTNode));(*T)->lchild->data = 2;(*T)->lchild->lchild = (BiTNode*)malloc(sizeof(BiTNode));(*T)->lchild->rchild = (BiTNode*)malloc(sizeof(BiTNode));(*T)->lchild->rchild->data = 5;(*T)->lchild->rchild->lchild = NULL;(*T)->lchild->rchild->rchild = NULL;(*T)->rchild->data = 3;(*T)->rchild->lchild = (BiTNode*)malloc(sizeof(BiTNode));(*T)->rchild->lchild->data = 6;(*T)->rchild->lchild->lchild = NULL;(*T)->rchild->lchild->rchild = NULL;(*T)->rchild->rchild = (BiTNode*)malloc(sizeof(BiTNode));(*T)->rchild->rchild->data = 7;(*T)->rchild->rchild->lchild = NULL;(*T)->rchild->rchild->rchild = NULL;(*T)->lchild->lchild->data = 4;(*T)->lchild->lchild->lchild = NULL;(*T)->lchild->lchild->rchild = NULL; }
//模擬操作結(jié)點元素的函數(shù),輸出結(jié)點本身的數(shù)值 void displayElem(BiTNode* elem)
{printf(
"%d ", elem->data); }
//先序遍歷 void PreOrderTraverse(BiTree T)
{
if (T)
  {displayElem(T);
//調(diào)用操作結(jié)點數(shù)據(jù)的函數(shù)方法PreOrderTraverse(T->lchild);//訪問該結(jié)點的左孩子PreOrderTraverse(T->rchild);//訪問該結(jié)點的右孩子}//如果結(jié)點為空,返回上一層return; }
//中序遍歷 void INOrderTraverse(BiTree T)
{
if (T)
  {INOrderTraverse(T
->lchild);//遍歷左孩子displayElem(T);//調(diào)用操作結(jié)點數(shù)據(jù)的函數(shù)方法INOrderTraverse(T->rchild);//遍歷右孩子}//如果結(jié)點為空,返回上一層
return; }
//后序遍歷 void PostOrderTraverse(BiTree T)
{
if (T)
  {PostOrderTraverse(T
->lchild);  //遍歷左孩子PostOrderTraverse(T->rchild);  //遍歷右孩子displayElem(T);  //調(diào)用操作結(jié)點數(shù)據(jù)的函數(shù)方法}
//如果結(jié)點為空,返回上一層return; }
int main()
{BiTree Tree;CreateBiTree(
&Tree);printf("前序遍歷: \n");PreOrderTraverse(Tree);printf("\n中序遍歷算法: \n");INOrderTraverse(Tree);printf("\n后序遍歷: \n");PostOrderTraverse(Tree); }

運行結(jié)果: 前序遍歷:
1 2 4 5 3 6 7 中序遍歷算法: 4 2 5 1 6 3 7 后序遍歷: 4 5 2 6 7 3 1

?

總結(jié)

由于二叉樹就是由根結(jié)點和左右子樹構(gòu)成的,所以很容易想到使用遞歸的思想。而遞歸算法的低層實現(xiàn)實際上使用的是棧的數(shù)據(jù)結(jié)構(gòu),所以二叉樹的先序、中序和后序遍歷同樣可以使用非遞歸的算法實現(xiàn)。

非遞歸算法的具體實現(xiàn)可以查看下一節(jié)的內(nèi)容。

轉(zhuǎn)載于:https://www.cnblogs.com/ciyeer/p/9044259.html

總結(jié)

以上是生活随笔為你收集整理的数据结构34:二叉树前序遍历、中序遍历和后序遍历的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。