数据结构-----二叉树建立及其遍历

目录

                  二叉树

建立二叉树

      先序遍历

      中序遍历

      后序遍历

      层序遍历


二叉树

        二叉树是树形结构的一种特殊形式,它的特点是每个结点至多只有两颗子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。如图1所示:

                                                                      

另外还有完全二叉树,满二叉树等,它们只是二叉树的特例。这里不作重点介绍,想了解的读者可以翻阅相关资料。

建立二叉树

       若要深入了解如何建立二叉树,则我们首先需要了解二叉树的几种遍历方式,它们分别为先序遍历、中序遍历,后续遍历以及层序遍历。我们知道二叉树是由根结点、左子树和右子树三个基本单元组成。因此若能依次遍历这三部分,便是遍历了整个二叉树。对于创建二叉树亦是如此,我们可以采用递归的方式,按照这几种的遍历方式,依次对这三部分开辟结点,并初始化,最终完成二叉树的创建。对于几种遍历方式在后面将进行介绍。

按照先序遍历顺序创建二叉树:

代码实现:

status createBiTree(BiTree &T)
{
	char ch;
	scanf("%c",&ch);
	if(ch == ' ')
	{T = nullptr;}
	else
	{
		T = (BiTNode*)malloc(sizeof(BiTNode));
		if(nullptr == T)
		{return ERROR;}
		T->_mdata = ch;              //生成根节点
		createBiTree(T->_mplchild);  //构造左子树
		createBiTree(T->_mprchild);  //构造右子树
	}

	return OK;
}

先序遍历

先序遍历的基本操作是:

若二叉树为空,则空操作;否则

<1>访问根节点;

<2>先序遍历左子树;

<3>先序遍历右子树。

代码实现(递归版本):

status preOrderTraverse(BiTree T,status (*visit)(ElemType))   //前序递归遍历
{
	if(NULL == T)
		return ERROR;
	(*visit)(T->_mdata);
	preOrderTraverse(T->_mplchild,visit);
	preOrderTraverse(T->_mprchild,visit);
}

代码实现(非递归版本)

status preOrderTraverses(BiTree T,status (*visit)(ElemType))  //前序非递归遍历
{
	BiTree p = T;
	std::stack<BiTree> stack;
	while(p != nullptr || !stack.empty())
	{
		while(p != nullptr)
		{
			if(!(*visit)(p->_mdata))
				return ERROR;
			stack.push(p);
			p = p->_mplchild;
		}

		if(!stack.empty())
		{
			p = stack.top();
			stack.pop();
			p = p->_mprchild;
		}
	}
	return OK;
}

 中序遍历

中序遍历的基本操作是:

若二叉树为空,则空操作;否则

<1>中序遍历左子树;

<2>访问根节点;

<3>中序遍历右子树。

代码实现(递归版本):

status inOrderTraverse(BiTree T,status (*visit)(ElemType))   //中序递归遍历
{
	if(NULL == T)
		return ERROR;
	inOrderTraverse(T->_mplchild,visit);
	(*visit)(T->_mdata);
	inOrderTraverse(T->_mprchild,visit);
}

代码实现(非递归版本)

status inOrderTraverses(BiTree T,status (*visit)(ElemType))   //中序非递归遍历
{
	BiTree p = T;
	std::stack<BiTree> stack;
	while(p != nullptr || !stack.empty())
	{
		if(p != nullptr)
		{
			stack.push(p);
			p = p->_mplchild;
		}
		else
		{
			p = stack.top();
			stack.pop();
			if(!(*visit)(p->_mdata))
				return ERROR;
			p = p->_mprchild;
		}
	}
	return OK;
}

后序遍历

后序遍历的基本操作是:

若二叉树为空,则空操作;否则

<1>后序遍历左子树;

<2>后序遍历右子树

<3>访问根节点。

代码实现(递归版本):

status postOrderTraverse(BiTree T,status (*visit)(ElemType))   //后序递归遍历
{
	if(NULL == T)
		return ERROR;
	postOrderTraverse(T->_mplchild,visit);
	postOrderTraverse(T->_mprchild,visit);
	(*visit)(T->_mdata);
}

代码实现(非递归版本)

status postOrderTraverses(BiTree T,status (*visit)(ElemType))  //后序非递归遍历
{
	BiTree p = T;
	std::stack<BiTree> stack;
	while(p != NULL || !stack.empty())
	{
		while(p != nullptr)
		{
			p->count = 1;
			stack.push(p);
			p = p->_mplchild;
		}
		if(!stack.empty())
		{
			p = stack.top();
			stack.pop();
			if(p->count == 1)
			{
				p->count++;
				stack.push(p);
				p = p->_mprchild;
			}
			else if(p->count == 2)
			{
				if(!(*visit)(p->_mdata))
					return ERROR;
				p = nullptr;
			}
		}
	}
	return OK;
}

层序遍历

        除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。

代码实现:

status levelTraverses(BiTree T,status (*visit)(ElemType))
{
	BiTree p = T;
	std::queue<BiTree> queue;
	queue.push(p);
	while(!queue.empty())
	{
		p = queue.front();
		queue.pop();
		if(!(*visit)(p->_mdata))
			return ERROR;

		if(p->_mplchild != nullptr)
		{
			queue.push(p->_mplchild);
		}
		
		if(p->_mprchild != nullptr)
		{
			queue.push(p->_mprchild);
		}
	}
	return OK;
}

完整代码实现:

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<stack>
#include<queue>
#include<assert.h>
#define STACK_SIZE 20
typedef char ElemType;
enum status {OK = 1,ERROR = 0,TRUE = 1,FALSE = 0};
typedef struct BiTNode
{
	int count;         //存储结点被访问的次数
	ElemType _mdata;
	struct BiTNode *_mplchild;
	struct BiTNode *_mprchild;
}BiTNode,*BiTree;
typedef struct
{
	BiTree base[STACK_SIZE];
	int top;
}Stack;

status createBiTree(BiTree &T)
{
	char ch;
	scanf("%c",&ch);
	if(ch == ' ')
	{T = nullptr;}
	else
	{
		T = (BiTNode*)malloc(sizeof(BiTNode));
		if(nullptr == T)
		{return ERROR;}
		T->_mdata = ch;              //生成根节点
		createBiTree(T->_mplchild);  //构造左子树
		createBiTree(T->_mprchild);  //构造右子树
	}

	return OK;
}
status show_node(ElemType e)
{
	printf("%c ",e);
	return OK;
}

status preOrderTraverse(BiTree T,status (*visit)(ElemType))   //前序递归遍历
{
	if(NULL == T)
		return ERROR;
	(*visit)(T->_mdata);
	preOrderTraverse(T->_mplchild,visit);
	preOrderTraverse(T->_mprchild,visit);
}
status preOrderTraverses(BiTree T,status (*visit)(ElemType))  //前序非递归遍历
{
	BiTree p = T;
	std::stack<BiTree> stack;
	while(p != nullptr || !stack.empty())
	{
		while(p != nullptr)
		{
			if(!(*visit)(p->_mdata))
				return ERROR;
			stack.push(p);
			p = p->_mplchild;
		}

		if(!stack.empty())
		{
			p = stack.top();
			stack.pop();
			p = p->_mprchild;
		}
	}
	return OK;
}

status inOrderTraverse(BiTree T,status (*visit)(ElemType))   //中序递归遍历
{
	if(NULL == T)
		return ERROR;
	inOrderTraverse(T->_mplchild,visit);
	(*visit)(T->_mdata);
	inOrderTraverse(T->_mprchild,visit);
}
status inOrderTraverses(BiTree T,status (*visit)(ElemType))   //中序非递归遍历
{
	BiTree p = T;
	std::stack<BiTree> stack;
	while(p != nullptr || !stack.empty())
	{
		if(p != nullptr)
		{
			stack.push(p);
			p = p->_mplchild;
		}
		else
		{
			p = stack.top();
			stack.pop();
			if(!(*visit)(p->_mdata))
				return ERROR;
			p = p->_mprchild;
		}
	}
	return OK;
}

status postOrderTraverse(BiTree T,status (*visit)(ElemType))   //后序递归遍历
{
	if(NULL == T)
		return ERROR;
	postOrderTraverse(T->_mplchild,visit);
	postOrderTraverse(T->_mprchild,visit);
	(*visit)(T->_mdata);
}
status postOrderTraverses(BiTree T,status (*visit)(ElemType))  //后序非递归遍历
{
	BiTree p = T;
	std::stack<BiTree> stack;
	while(p != NULL || !stack.empty())
	{
		while(p != nullptr)
		{
			p->count = 1;
			stack.push(p);
			p = p->_mplchild;
		}
		if(!stack.empty())
		{
			p = stack.top();
			stack.pop();
			if(p->count == 1)
			{
				p->count++;
				stack.push(p);
				p = p->_mprchild;
			}
			else if(p->count == 2)
			{
				if(!(*visit)(p->_mdata))
					return ERROR;
				p = nullptr;
			}
		}
	}
	return OK;
}

status levelTraverses(BiTree T,status (*visit)(ElemType))
{
	BiTree p = T;
	std::queue<BiTree> queue;
	queue.push(p);
	while(!queue.empty())
	{
		p = queue.front();
		queue.pop();
		if(!(*visit)(p->_mdata))
			return ERROR;

		if(p->_mplchild != nullptr)
		{
			queue.push(p->_mplchild);
		}
		
		if(p->_mprchild != nullptr)
		{
			queue.push(p->_mprchild);
		}
	}
	return OK;
}
int main()
{
	BiTree tree;
	createBiTree(tree);
	printf("先序遍历:\n");
	preOrderTraverse(tree,show_node);
	printf("\n");
	preOrderTraverses(tree,show_node);
	printf("\n");
	printf("中序遍历:\n");
	inOrderTraverse(tree,show_node);
	printf("\n");
	inOrderTraverses(tree,show_node);
	printf("\n");
	printf("后序遍历:\n");
	postOrderTraverse(tree,show_node);
	printf("\n");
	postOrderTraverses(tree,show_node);
	printf("\n");
	printf("层序遍历:\n");
	levelTraverses(tree,show_node);
	printf("\n");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/FDk_LCL/article/details/89221363