1. 程式人生 > 實用技巧 >二叉樹的非遞迴遍歷

二叉樹的非遞迴遍歷

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

1、提供一個順序儲存的棧

#define  max 1024

struct sstack
{
	void * data[max];  //棧的陣列

	int m_size; //棧大小
};

typedef void * seqstack;

//初始化棧
seqstack init_seqstack()
{
	struct sstack *  mystack = (struct sstack *)malloc(sizeof(struct sstack));

	if (mystack == NULL)
	{
		return NULL;
	}

	//初始化陣列
	for(int i = 0; i<max; i++)
	{
		mystack->data[i] = 0;
	}
	//或者 
	//memset(mystack->data, 0, sizeof(void *)* max);

	//初始化棧大小
	mystack->m_size = 0;

	return mystack;
}
//入棧
void push_seqstack(seqstack stack , void * data)
{
	//入棧本質  --- 陣列尾插
	if (stack == NULL)
	{
		return;
	}
	if ( data == NULL)
	{
		return;
	}

	struct sstack * mystack = (struct sstack * )stack; //強制轉換成自己所需要的型別 
	if (mystack->m_size == max)
	{
		return;
	}

	mystack->data[mystack->m_size] = data;

	mystack->m_size++;
}
//出棧
void pop_seqstack(seqstack stack)
{
	//出棧本質  --- 陣列尾刪
	if (stack == NULL)
	{
		return;
	}

	struct sstack * mystack = (struct sstack * )stack;

	if (mystack->m_size == 0)
	{
		return;
	}

	mystack->data[mystack->m_size - 1] = NULL;

	mystack->m_size--;

}
//返回棧頂
void * top_seqstack(seqstack stack)
{
	if (stack == NULL)
	{
		return NULL;
	}

	struct sstack * mystack = (struct sstack * )stack;

	if (mystack->m_size == 0)
	{
		return NULL;
	}
	return mystack->data[mystack->m_size - 1];
}
//返回棧大小
int size_seqstack(seqstack stack)
{
	if (stack == NULL)
	{
		return -1;
	}

	struct sstack * mystack = (struct sstack * )stack;

	return mystack->m_size;

}
//判斷棧是否為空
int isempty_seqstack(seqstack stack)
{
	if (stack == NULL)
	{
		return -1;//返回-1代表真  空棧
	}

	struct sstack * mystack = (struct sstack * )stack;

	if (mystack->m_size == 0)
	{
		return 1;
	}

	return 0; //返回0 代表 不是空棧

}
//銷燬棧
void destroy_seqstack(seqstack stack)
{
	if (stack == NULL)
	{
		return;
	}

	free(stack);
	stack = NULL;
}
/* 棧的介面到此結束 */

2、構建一棵二叉樹

typedef struct BinaryNode //二叉樹結點 
{
	//資料域 
	char data;
	//指標域 
	struct BinaryNode * lChild;  //左孩子 
	struct BinaryNode * rChild;  //右孩子 
	//標誌
	int flag; 
	
}BiNode;


//二叉樹的非遞迴演算法 
void nonRecursion(BiNode * root)
{
	 //初始化棧 
	 seqstack mystack = init_seqstack();
	 
	 //1. 將根節點 入棧 
	 push_seqstack(mystack, root);
	 //2. 進入迴圈:
	 while(size_seqstack(mystack)>0)
	 {
	 	//獲取棧頂元素
		 BiNode * pTop = (BiNode * )top_seqstack(mystack);  //把void *強制轉換成所需要的型別 
	 	
	 	//出棧 
	 	pop_seqstack(mystack);
	 	
	 	if(pTop->flag == 1)
	 	{
	 		printf("%c ", pTop->data);
	 		continue;
	 	}
	 	
	 	pTop->flag = 1;
	 	
	 	//將結點右子樹 、左子樹、 根  入棧,  出棧結果:先序
	 	if(pTop->rChild != NULL)
	 	{
	 		push_seqstack(mystack, pTop->rChild);
	 	}
	 	if(pTop->lChild != NULL)
	 	{
	 		push_seqstack(mystack, pTop->lChild);
	 	}
	 	push_seqstack(mystack, pTop);
	 	
	 }
	 
	 //銷燬棧 
	 destroy_seqstack(mystack);
}
 
 
void test01()
{
	//對成員初始化 
	BiNode nodeA = {'A', NULL, NULL, 0};
	BiNode nodeB = {'B', NULL, NULL, 0};
	BiNode nodeC = {'C', NULL, NULL, 0};
	BiNode nodeD = {'D', NULL, NULL, 0};
	BiNode nodeE = {'E', NULL, NULL, 0};
	BiNode nodeF = {'F', NULL, NULL, 0};
	BiNode nodeG = {'G', NULL, NULL, 0};
	BiNode nodeH = {'H', NULL, NULL, 0};
	
	//建立關係 
	nodeA.lChild = &nodeB;
	nodeA.rChild = &nodeF;
	
	nodeB.rChild = &nodeC;
	
	nodeC.lChild = &nodeD;
	nodeC.rChild = &nodeE;
	
	nodeF.rChild = &nodeG;
	
	nodeG.lChild = &nodeH;
	
	//非遞迴遍歷
	nonRecursion(&nodeA);//傳入樹根 
	 
}
int main(){
	test01();


	system("pause");
	return 0;
}