1. 程式人生 > >二叉樹的中序非遞迴遍歷c語言版

二叉樹的中序非遞迴遍歷c語言版

由於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;
}