数据结构之二叉树的遍历
生活随笔
收集整理的這篇文章主要介紹了
数据结构之二叉树的遍历
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
二叉樹的遍歷分為前序遍歷,中序遍歷,后序遍歷,層序遍歷,在本文中,前三種由遞歸實現,層序遍歷由隊列實現。
#include "stdio.h" #include "stdlib.h" #include "windows.h" typedef struct Node {char data;struct Node *Left;struct Node *Right;struct Node *Next; }BT;typedef struct { /* 鏈隊列結構 */BT *rear; /* 指向隊尾結點 */BT *front; /* 指向隊頭結點 */ } LinkQueue; //入隊 LinkQueue* AddQuee(LinkQueue *PtrL,BT* item) {BT *node;node=PtrL->rear;if (PtrL->front==NULL){BT *q=(BT*)malloc(sizeof(BT));q->Left=item->Left;q->Right=item->Right;q->Next=NULL;q->data=item->data;PtrL->front=q;PtrL->rear=q;return PtrL;}else{BT *q=(BT*)malloc(sizeof(BT));q->Next=NULL;q->Left=item->Left;q->Right=item->Right;q->data=item->data;node->Next=q;PtrL->rear=q;return PtrL;} } //出隊 BT* DeleteQ ( LinkQueue *PtrQ ) {BT *firstNode;//BT* NodeItem;if (PtrQ->front==NULL){printf("queue is empty");return NULL;}firstNode=PtrQ->front;if (PtrQ->front==PtrQ->rear){PtrQ->front=PtrQ->rear=NULL;}else{PtrQ->front=PtrQ->front->Next;}//NodeItem->data=firstNode->data;//free(firstNode);return firstNode; } //判斷是否為空 int isempty(LinkQueue *PtrL) {if (PtrL->rear==NULL){return 1;}else{return 0;} }BT *CreateBiTree() {char ch;BT *T;printf("please enter tree node:");scanf("%c",&ch);if (ch=='#'){T=NULL;}else{T=(BT*)malloc(sizeof(BT));T->data=ch;T->Left=CreateBiTree();T->Right=CreateBiTree();}return T; }//先序遍歷 void PreOrderTraversal( BT* tree) {if (tree){printf("%c ",tree->data);PreOrderTraversal(tree->Left);PreOrderTraversal(tree->Right);} }//中序遍歷 void InOrderTraversal(BT* tree) {if (tree){PreOrderTraversal(tree->Left);printf("%c ",tree->data);PreOrderTraversal(tree->Right);} }//后序遍歷 void PostOderTraversal(BT *tree) {if (tree){PostOderTraversal(tree->Left);PostOderTraversal(tree->Right);printf("%c ",tree->data);} } //層序遍歷 void LevelOrderTraversal(BT *tree) {BT *bt;LinkQueue *q=(LinkQueue*)malloc(sizeof(LinkQueue));q->front=NULL;q->rear=NULL;if (!tree){return;}AddQuee(q,tree);while(isempty(q)==0){bt=DeleteQ(q);printf("%c ",bt->data);if (bt->Left) AddQuee(q,bt->Left);if (bt->Right) AddQuee(q,bt->Right);}}int PostOrderGetHeight( BT* tree ) {int HL, HR, MaxH;if( tree ) {HL = PostOrderGetHeight(tree->Left); /*求左子樹的深度*/HR = PostOrderGetHeight(tree->Right); /*求右子樹的深度*/MaxH =(HL> HR)? HL : HR;/*取左右子樹較大的深度*/return ( MaxH + 1 ); /*返回樹的深度*/}else return 0; /* 空樹深度為0 */ }void main() {BT *t;int a;t=CreateBiTree();printf("\n1.PreOrderTraversal\n");printf("2.MidOrderTraversal\n");printf("3.PostOrderTraversal\n");printf("4.EXIT\n");printf("5.LevelOrderTraversal\n");printf("6.show the hieght of the tree");while (1){printf("please enter your order:");scanf("%d",&a);switch (a){case 1:PreOrderTraversal(t);break;case 2:InOrderTraversal(t);break;case 3:PostOderTraversal(t);break;case 4:exit(0);break;case 5:LevelOrderTraversal(t);break;case 6:printf("%d",PostOrderGetHeight(t));break;default:break;}} }運行結果
C++實現二叉樹的遍歷
#include "iostream" #include "stack" #include "queue"using namespace std;//二叉樹結點 typedef struct BiTNode{//數據char data;//左右孩子指針struct BiTNode *lchild,*rchild; }BiTNode,*BiTree;//按先序序列創建二叉樹 int CreateBiTree(BiTree &T){char data;//按先序次序輸入二叉樹中結點的值(一個字符),‘#’表示空樹scanf("%c",&data);if(data == '#'){T = NULL;}else{T = (BiTree)malloc(sizeof(BiTNode));//生成根結點T->data = data;//構造左子樹CreateBiTree(T->lchild);//構造右子樹CreateBiTree(T->rchild);}return 0; } //輸出 void Visit(BiTree T){if(T->data != '#'){printf("%c ",T->data);} } //先序遍歷 void PreOrder(BiTree T){if(T != NULL){//訪問根節點Visit(T);//訪問左子結點PreOrder(T->lchild);//訪問右子結點PreOrder(T->rchild);} } //中序遍歷 void InOrder(BiTree T){ if(T != NULL){ //訪問左子結點 InOrder(T->lchild); //訪問根節點 Visit(T); //訪問右子結點 InOrder(T->rchild); } } //后序遍歷 void PostOrder(BiTree T){if(T != NULL){//訪問左子結點PostOrder(T->lchild);//訪問右子結點PostOrder(T->rchild);//訪問根節點Visit(T);} } /* 先序遍歷(非遞歸)思路:訪問T->data后,將T入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為T,出棧,再先序遍歷T的右子樹。 */ void PreOrder2(BiTree T){stack<BiTree> stack;//p是遍歷指針BiTree p = T;//棧不空或者p不空時循環while(p || !stack.empty()){if(p != NULL){//存入棧中stack.push(p);//訪問根節點printf("%c ",p->data);//遍歷左子樹p = p->lchild;}else{//退棧p = stack.top();stack.pop();//訪問右子樹p = p->rchild;}}//while } /* 中序遍歷(非遞歸)思路:T是要遍歷樹的根指針,中序遍歷要求在遍歷完左子樹后,訪問根,再遍歷右子樹。先將T入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為T,出棧,訪問T->data,再中序遍歷T的右子樹。 */ void InOrder2(BiTree T){stack<BiTree> stack;//p是遍歷指針BiTree p = T;//棧不空或者p不空時循環while(p || !stack.empty()){if(p != NULL){//存入棧中stack.push(p);//遍歷左子樹p = p->lchild;}else{//退棧,訪問根節點p = stack.top();printf("%c ",p->data);stack.pop();//訪問右子樹p = p->rchild;}}//while }//后序遍歷(非遞歸) typedef struct BiTNodePost{BiTree biTree;char tag; }BiTNodePost,*BiTreePost;void PostOrder2(BiTree T){stack<BiTreePost> stack;//p是遍歷指針BiTree p = T;BiTreePost BT;//棧不空或者p不空時循環while(p != NULL || !stack.empty()){//遍歷左子樹while(p != NULL){BT = (BiTreePost)malloc(sizeof(BiTNodePost));BT->biTree = p;//訪問過左子樹BT->tag = 'L';stack.push(BT);p = p->lchild;}//左右子樹訪問完畢訪問根節點while(!stack.empty() && (stack.top())->tag == 'R'){BT = stack.top();//退棧stack.pop();BT->biTree;printf("%c ",BT->biTree->data);}//遍歷右子樹if(!stack.empty()){BT = stack.top();//訪問過右子樹BT->tag = 'R';p = BT->biTree;p = p->rchild;}}//while } //層次遍歷 void LevelOrder(BiTree T){BiTree p = T;//隊列queue<BiTree> queue;//根節點入隊queue.push(p);//隊列不空循環while(!queue.empty()){//對頭元素出隊p = queue.front();//訪問p指向的結點printf("%c ",p->data);//退出隊列queue.pop();//左子樹不空,將左子樹入隊if(p->lchild != NULL){queue.push(p->lchild);}//右子樹不空,將右子樹入隊if(p->rchild != NULL){queue.push(p->rchild);}} } int main() {BiTree T;CreateBiTree(T);printf("先序遍歷:\n");PreOrder(T);printf("\n");printf("先序遍歷(非遞歸):\n");PreOrder2(T);printf("\n");printf("中序遍歷:\n");InOrder(T);printf("\n");printf("中序遍歷(非遞歸):\n");InOrder2(T);printf("\n");printf("后序遍歷:\n");PostOrder(T);printf("\n");printf("后序遍歷(非遞歸):\n");PostOrder2(T);printf("\n");printf("層次遍歷:\n");LevelOrder(T);printf("\n");system("pause");return 0; }總結
以上是生活随笔為你收集整理的数据结构之二叉树的遍历的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【每日SQL打卡】
- 下一篇: 【每日SQL打卡】