数据结构34:二叉树前序遍历、中序遍历和后序遍历
生活随笔
收集整理的這篇文章主要介紹了
数据结构34:二叉树前序遍历、中序遍历和后序遍历
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
鏈式存儲結構存儲的二叉樹,對樹中結點進行逐個遍歷時,由于是非線性結構,需要找到一種合適的方式遍歷樹中的每個結點。
遞歸思想遍歷二叉樹
之前講過,樹是由根結點和子樹部分構建的,對于每一棵樹來說,都可以分為 3 部分:左子樹、根結點和右子樹。所以,可以采用遞歸的思想依次遍歷每個結點。
根據訪問結點時機的不同,分為三種遍歷方式:
- 先訪問根結點,再遍歷左右子樹,稱為“先序遍歷”;
- 遍歷左子樹,之后訪問根結點,然后遍歷右子樹,稱為“中序遍歷”;
- 遍歷完左右子樹,再訪問根結點,稱為“后序遍歷”。
圖1 二叉樹
三種方式唯一的不同就是訪問結點時機的不同,給出一個二叉樹,首先需要搞清楚三種遍歷方式下訪問結點的順序。
圖2 二叉樹遍歷示意圖
圖2 中,箭頭線條的走勢為遍歷結點的過程:
先序遍歷是只要線條走到該結點的左方位置時,就操作該結點。所以操作結點的順序為:
中序遍歷是當線條越過結點的左子樹,到達該結點的正下方時,才操作該結點。所以操作結點的順序為:
后序遍歷是線條完全走過結點的左右子樹,到達該結點的右方范圍時,就開始操作該結點。所以操作結點的順序為:
三種遍歷方式的完整代碼實現
#include <stdio.h> #include <string.h> #define TElemType int //構造結點的結構體 typedef struct BiTNode{TElemType data; //數據域struct BiTNode *lchild, *rchild; //左右孩子指針 }BiTNode, *BiTree;
//初始化樹的函數 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; }
//模擬操作結點元素的函數,輸出結點本身的數值 void displayElem(BiTNode* elem)
{printf("%d ", elem->data); }
//先序遍歷 void PreOrderTraverse(BiTree T)
{if (T)
{displayElem(T);//調用操作結點數據的函數方法PreOrderTraverse(T->lchild);//訪問該結點的左孩子PreOrderTraverse(T->rchild);//訪問該結點的右孩子}//如果結點為空,返回上一層return; }
//中序遍歷 void INOrderTraverse(BiTree T)
{if (T)
{INOrderTraverse(T->lchild);//遍歷左孩子displayElem(T);//調用操作結點數據的函數方法INOrderTraverse(T->rchild);//遍歷右孩子}//如果結點為空,返回上一層
return; }
//后序遍歷 void PostOrderTraverse(BiTree T)
{if (T)
{PostOrderTraverse(T->lchild); //遍歷左孩子PostOrderTraverse(T->rchild); //遍歷右孩子displayElem(T); //調用操作結點數據的函數方法}
//如果結點為空,返回上一層return; }
int main()
{BiTree Tree;CreateBiTree(&Tree);printf("前序遍歷: \n");PreOrderTraverse(Tree);printf("\n中序遍歷算法: \n");INOrderTraverse(Tree);printf("\n后序遍歷: \n");PostOrderTraverse(Tree); }
運行結果: 前序遍歷: 1 2 4 5 3 6 7 中序遍歷算法: 4 2 5 1 6 3 7 后序遍歷: 4 5 2 6 7 3 1
?
總結
由于二叉樹就是由根結點和左右子樹構成的,所以很容易想到使用遞歸的思想。而遞歸算法的低層實現實際上使用的是棧的數據結構,所以二叉樹的先序、中序和后序遍歷同樣可以使用非遞歸的算法實現。
非遞歸算法的具體實現可以查看下一節的內容。
轉載于:https://www.cnblogs.com/ciyeer/p/9044259.html
總結
以上是生活随笔為你收集整理的数据结构34:二叉树前序遍历、中序遍历和后序遍历的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为何赵国在战争的生死存亡之际
- 下一篇: 在部队工作时间玩mp4犯错检讨怎么写?