二叉樹的中序非遞迴遍歷c語言版
阿新 • • 發佈:2019-01-06
由於c語言沒有c++的STL庫,我們無法藉助c++的stack庫實現二叉樹的非遞迴遍歷,但是,我們完全可以自己打造一個c語言版的stack庫。本篇博文就是藉助我們之前在棧的鏈
工程專案中。
#define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include<stdio.h> #include <string.h> #include "linklist.h" #include "linkstack.h" //第一種表示方法 :二叉連結串列示法 typedef struct BiTNode { int data; struct BiTNode *lchild,*rchild; } BiTNode,* BITree; //中序遞迴遍歷 void inOrder(BiTNode*root) { if (root==NULL) { return; } inOrder(root->lchild); printf("%d ",root->data); inOrder(root->rchild); } /* 中序遍歷非遞迴演算法: 步驟1: 如果結點有左子樹,該結點入棧; 如果結點沒有左子樹,訪問該結點; 步驟2: 如果結點有右子樹,重複步驟1; 如果結點沒有右子樹(結點訪問完畢),根據棧頂指示回退,訪問棧頂元素,並訪問右子樹,重複步驟1 如果棧為空,表示遍歷結束。*/ //輔助函式 找到中序遍歷的起點 BiTNode* goLeft(BiTNode*t,LinkStack *s) { if (t==NULL) { return NULL; } //如果結點有左子樹,該結點入棧; while (t->lchild) { LinkStack_Push(s,t); t = t->lchild; } return t; } //中序遍歷非遞迴 void inOrder2(BiTNode*root) { BiTNode* t ; LinkStack* s = LinkStack_Create(); if (s==NULL) { return ; } //1.找到中序遍歷的起點 (沒有左孩子) t = goLeft(root,s); while (t) { //訪問該元素 printf("%d ",t->data); //2.如果t有右子樹 重複步驟1 if (t->rchild) { t = goLeft(t->rchild,s);//右子樹中序遍歷的起點 } //2.如果沒有右子樹 根據棧頂指示回退 else if (LinkStack_Size(s)>0) { t = LinkStack_Pop(s); } //3.如果沒有右子樹且棧為空 表示遍歷結束 else { t = NULL; } } } int main() { //建立節點 BiTNode t1,t2,t3,t4,t5,t6; memset(&t1,0,sizeof(BiTNode)); memset(&t2,0,sizeof(BiTNode)); memset(&t3,0,sizeof(BiTNode)); memset(&t4,0,sizeof(BiTNode)); memset(&t5,0,sizeof(BiTNode)); memset(&t6,0,sizeof(BiTNode)); t1.data = 1; t2.data = 2; t3.data = 3; t4.data = 4; t5.data = 5; t6.data = 6; //建立關係 t1.lchild = &t2; t1.rchild = &t3; t2.lchild = &t4; t2.rchild = &t5; t3.lchild = &t6; printf("\n中序遞迴遍歷\n"); inOrder(&t1); printf("\n中序非遞迴遍歷\n"); inOrder2(&t1); system("pause"); return 0; }