二叉树的建立、遍历

这个程序有参考了网上的程序,谢谢。

这个程序自己重新参考数据结构,重新栈和队列的模板类,并参考网上的程序写出了二叉树的建立和三种遍历方式(包括递归和非递归的实现):

队列的实现:

#ifndef __BT_QUEUE__
#define __BT_QUEUE__

/************************************************************************/
/*队列的简单实现,包括入队、出对、判断是否对空                          */
/*记住模板类,声明和实现必须在同一个文件中								*/
/************************************************************************/

#include <iostream>

template<typename T>
class BT_Queue
{
public:
	BT_Queue(void);
	~BT_Queue(void){}
	typedef struct qnode{
		T data;
		struct qnode *next;
	}QTYPE;
	QTYPE *front, *rear;
	void initQueue();
	void push(T t);
	void pop();
	int empty();
};

template<typename T>
BT_Queue<T>::BT_Queue(void)
{
	initQueue();
}

template<class T>
void BT_Queue<T>::initQueue()
{
	QTYPE *p;
	p = (QTYPE*)malloc(sizeof(QTYPE));
	p->next = NULL;
	front = rear = p;
}

template<class T>
void BT_Queue<T>::push(T t)
{
	QTYPE *s;
	s = (QTYPE*)malloc(sizeof(QTYPE));
	s->data = t;
	s->next = rear->next;
	rear->next = s;
	rear = s;
}

template<class T>
int BT_Queue<T>::empty()
{
	return front == rear ? 1 : 0;
}

template<class T>
void BT_Queue<T>::pop()
{
	QTYPE *p;
	if(empty())
	{
		printf("queue is free");
		return;
	}
	p = front->next;
	front->next = p->next;
	if(front->next == NULL)
		rear = front;
	free(p);
}

#endif


注意模板类的声明和实现必须放在同一文件中。

栈的实现:

#ifndef __BT_STACK__
#define __BT_STACK__

#include <iostream>

template<class T>
class BT_Stack
{
public:
	BT_Stack();
	~BT_Stack(){}
	typedef struct snode{
		T data;
		struct snode *next;
	}LinkStack;
	LinkStack *top;
	
	void initStack();
	void push(T t);
	void pop();
	int empty();
	T getTop();
};

template<class T>
BT_Stack<T>::BT_Stack()
{
	initStack();
}

template<class T>
void BT_Stack<T>::initStack()
{
	top = (LinkStack*)malloc(sizeof(LinkStack));
	(top)->next = NULL;
}

template<class T>
void BT_Stack<T>::push(T t)
{
	LinkStack* s;
	s = (LinkStack*)malloc(sizeof(LinkStack));
	s->data = t;
	s->next = (top)->next;
	(top)->next = s;
}

template<class T>
int BT_Stack<T>::empty()
{
	return (top)->next == NULL ? 1 : 0;
}

template<class T>
void BT_Stack<T>::pop()
{
	LinkStack *s;
	if(empty())
	{
		printf("stack is free");
		return;
	}
	s = (top)->next;
	(top)->next = s->next;
	free(s);
}

template<class T>
T BT_Stack<T>::getTop()
{
	if(empty())
	{
		printf("stack is free");
		return NULL;
	}
	return (top)->next->data;
}
#endif


 

二叉树代码部分:

#include <stdio.h>
#include <malloc.h>
#include <time.h>
// #include <stack>
// #include <queue>
#include <assert.h>
#include "BT_Queue.h"
#include "BT_Stack.h"

using namespace std;

#define MAX_CNT 10
#define BASE  100

typedef int ElemType;

typedef struct treeT
{
	ElemType key;
	struct treeT* left;
	struct treeT* right;
}treeT, *pTreeT;

//二叉树的访问
static void visit(pTreeT root)
{
	if (NULL != root)
	{
		printf(" %d\n", root->key);
	}
}


//创建二叉树节点
static pTreeT BT_MakeNode(ElemType target)
{
	pTreeT pNode = (pTreeT) malloc(sizeof(treeT));

	assert( NULL != pNode ); 

	pNode->key   = target;
	pNode->left  = NULL;
	pNode->right = NULL;

	return pNode;
}

//创建二叉树
pTreeT BT_Insert(ElemType target, pTreeT* ppTree)
{
	pTreeT Node;

	assert( NULL != ppTree ); 

	Node = *ppTree;
	if (NULL == Node)
	{
		return *ppTree = BT_MakeNode(target);
	}

	if (Node->key == target)    //不允许出现相同的元素
	{
		return NULL;
	}
	else if (Node->key > target)    //向左
	{
		return BT_Insert(target, &Node->left);
	}
	else
	{
		return BT_Insert(target, &Node->right);
	}
}



//二叉树的前序遍历(递归)
void BT_PreOrder(pTreeT root)
{
	if (NULL != root)
	{
		visit(root);
		BT_PreOrder(root->left);
		BT_PreOrder(root->right);
	}    
}
//二叉树的前序遍历(非递归)
void BT_PreOrderNoRec(pTreeT root)
{
	BT_Stack<treeT *> s;

	while ((NULL != root) || !s.empty())
	{
		if (NULL != root)
		{
			visit(root);
			s.push(root);
			root = root->left;
		}
		else
		{
			root = s.getTop();
			s.pop();
			root = root->right;
		}
	}
}


//二叉树的中序遍历(递归)
void BT_InOrder(pTreeT root)
{
	if (NULL != root)
	{
		BT_InOrder(root->left);
		visit(root);
		BT_InOrder(root->right);
	}
}
//二叉树的中序遍历(非递归)
void BT_InOrderNoRec(pTreeT root)
{
	BT_Stack<treeT *> s;
	while ((NULL != root) || !s.empty())
	{
		if (NULL != root)
		{
			s.push(root);
			root = root->left;
		}
		else
		{
			root = s.getTop();
			visit(root);
			s.pop();
			root = root->right;
		}
	}
}


//二叉树的后序遍历(递归)
void BT_PostOrder(pTreeT root)
{
	if (NULL != root)
	{
		BT_PostOrder(root->left);
		BT_PostOrder(root->right);
		visit(root);    
	}
}
//二叉树的后序遍历(非递归)
void BT_PostOrderNoRec(pTreeT root)
{
	BT_Stack<treeT *> s; 
	pTreeT pre = NULL; 

	while ((NULL != root) || !s.empty()) 
	{ 
		if (NULL != root) 
		{ 
			s.push(root); 
			root = root->left; 
		} 
		else 
		{ 
			root = s.getTop(); 
			if (root->right != NULL && pre != root->right)
			{ 
				root = root->right; 
			} 
			else
			{ 
				root = pre = s.getTop(); 
				visit(root); 
				s.pop(); 
				root = NULL; 
			} 
		} 
	} 
}

//输出层次遍历
void BT_LevelOrder(pTreeT root)
{
	BT_Queue<treeT *> q;
	treeT *treePtr;

	assert( NULL != root ); 

	q.push(root);

	while (!q.empty())
	{
		treePtr = q.front->next->data;
		q.pop();
		visit(treePtr);

		if (NULL != treePtr->left)
		{
			q.push(treePtr->left);    
		}
		if (NULL != treePtr->right)
		{
			q.push(treePtr->right);
		}    

	}
}


int main(int argc, char *argv[])
{
	int i;
	pTreeT root = NULL;

	srand( (unsigned)time( NULL ) ); 

	for (i=0; i<MAX_CNT; i++)
	{
		BT_Insert(rand() % BASE, &root);
	}

	//前序
	printf("PreOrder:\n");
	BT_PreOrder(root);
	printf("\n");

	printf("PreOrder no recursion:\n");
	BT_PreOrderNoRec(root);
	printf("\n");

	//中序
	printf("InOrder:\n");
	BT_InOrder(root);
	printf("\n");

	printf("InOrder no recursion:\n");
	BT_InOrderNoRec(root);
	printf("\n");

	//后序
	printf("PostOrder:\n");
	BT_PostOrder(root);
	printf("\n");

	printf("PostOrder no recursion:\n");
	BT_PostOrderNoRec(root);
	printf("\n");

	//层序
	printf("LevelOrder:\n");
	BT_LevelOrder(root);
	printf("\n");
	system("pause");
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值