二叉树的基本操作(数据结构)

二叉树的基本操作(数据结构)

看了很多博客许多大牛的文章,发现他们的方法即巧妙又简便,果断学习并理解。结合所学的知识,把二叉树的基本操作罗列了下来。
废话不多说,直接上源码,一些不容易理解的地方会有注释,要是有问题也可以私信我QQ``:790567648交个朋友互相学习鸭~

---------头文件,宏定义以及树ADT的实现**

//头文件
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
//宏定义
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define MAXSIZE 10
//ADT
typedef int TElemType;
typedef int Status;
typedef struct BiTNode              //定义二叉树节点数据类型 
{
	TElemType data;
	struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;           //bitree为指向bitnode这种结构的指针

----------基本操作的声明

BiTree CreateTree();//按先序次序输入二叉树中结点的值(一个字符)空格字符表示空数
Status PreOrderTraverse(BiTree T, Status(*Visit)(TElemType e));//先序遍历二叉树T,对每个结点调用函数VIsit一次且仅一次
Status InOrderTraverse(BiTree T, Status(*Visit)(TElemType e));//中序。。。
Status PostOrderTraverse(BiTree T, Status(*Visit)(TElemType e));//后序。。。
Status LevelOrderTraverse(BiTree T, Status(*Visit)(TElemType e));//层序。。。
Status Deepth(BiTree T);//求树的高度
Status PreorderPrintLeaves(BiTree BT);//先序输出树的结点

----------具体的函数的实现

BiTree CreateTree()//二叉树的建立
{
	BiTree T;
	TElemType item;
	scanf("%d", &item);
	if (item == 0)              //叶节点数据标志:其后根两个0 
		T = NULL;            //若某一节点为叶子结点,则其左右子树均为NULL,0表示建空树
	else
	{
		T = (BiTree)malloc(sizeof(BiTNode));
		T->data = item;
		T->lchild = CreateTree();             //递归创建其左子树 
		T->rchild = CreateTree();            //递归创建其右子树 
	}
	return T;                              //返回根节点 
}

Status PrintElement(TElemType e)//应用函数具体实现
{
	printf("%d ", e);
	return OK;
}

Status PreOrderTraverse1(BiTree T, Status(*Visit)(TElemType e))//先序遍历递归
{
	if (T)
	{
		if (Visit(T->data))
			if (PreOrderTraverse1(T->lchild, Visit))
				if (PreOrderTraverse1(T->rchild, Visit))
					return OK;
		return ERROR;
	}
	else return OK;
}

Status InOrderTraverse1(BiTree T, Status(*Visit)(TElemType e))//中序遍历递归
{
	if (T)
	{
		if (PreOrderTraverse1(T->lchild, Visit))
			if (Visit(T->data))
				if (PreOrderTraverse1(T->rchild, Visit))
					return OK;
		return ERROR;
	}
	else return OK;
}

Status PostOrderTraverse1(BiTree T, Status(*Visit)(TElemType e))//后序遍历递归
{
	if (T)
	{
		if (PreOrderTraverse1(T->lchild, Visit))
			if (PreOrderTraverse1(T->rchild, Visit))
				if (Visit(T->data))
					return OK;
		return ERROR;
	}
	else return OK;
}


Status PreOrderTraverse2(BiTree T, Status(*Visit)(TElemType e))//先序遍历非递归
{	
	BiTree P = T;
	stack<BiTree>S;
	while (P!=NULL||!S.empty())
	{
		while (P!=NULL)
		{
			Visit(P->data);
			S.push(P);
			P = P->lchild;
		}	
	if (!S.empty())
	{
		P=S.top();
		S.pop();
		P = P->rchild;
	}
	}
	return OK;
}

Status InOrderTraverse2(BiTree T, Status(*Visit)(TElemType e))//中序遍历非递归
{
	stack<BiTree>S;
	BiTree P = T;
	while (P!=NULL||!S.empty())
	{
		while (P!=NULL)
		{
			S.push(P);
			P = P->lchild;			
		}
		if (!S.empty())
		{
			P = S.top();
			S.pop();
			Visit(P->data);		
			P=P->rchild;
		}
	}
	return OK;
}

Status PostOrderTraverse2(BiTree T, Status(*Visit)(TElemType e))//后序遍历非递归
{
	stack<BiTree>S;
	BiTNode *cur;//当前结点
	BiTNode *ptr=NULL;//之前访问的结点
	S.push(T);
	while (!S.empty())
	{
		cur = S.top();
		if ((cur->lchild==NULL&&cur->rchild==NULL)||(ptr!=NULL&&(ptr==cur->lchild||ptr==cur->rchild)))
		{
			Visit(cur->data);
			S.pop();
			ptr = cur;
		}
		else {
			if (cur->rchild!=NULL)
			{
				S.push(cur->rchild);
			}
			if (cur->lchild!=NULL)
			{
				S.push(cur->lchild);
			}
		}
	}
	return OK;
}

Status LevelOrderTraverse(BiTree T, Status(*Visit)(TElemType e))//层序遍历二叉树(借助于队列)
{
	queue<BiTree>Q;
	BiTree P = T;
	Q.push(P);
	while (!Q.empty())
	{
		BiTree temp = Q.front();
		Q.pop();
		Visit(temp->data);		
		if (temp->lchild!=NULL)
		{
			Q.push(temp->lchild);
		}
		if (temp->rchild!=NULL)
		{
			Q.push(temp->rchild);
		}
	}
	return OK;
}

Status LevelOrderTraverse(BiTree T)// 二叉树的层序遍历(数组实现)
{
	if (T == NULL) return ERROR;

	BiTree q[MAXSIZE];//树中最大的结点数为10.
	q[0] = T;

	int front = 0;
	int rear = 1;

	while (front<rear)
	{
		printf("%d ",q[front]->data);
		if (q[front]->lchild)
		{
			q[rear] = q[front]->lchild;
			rear++;
		}
		if (q[front]->rchild)
		{
			q[rear] = q[front]->rchild;
			rear++;
		}
		front++;//最后跳出循环的条件为front=rear
		//rear为除了根节点以外所有结点的总数,front为算上根节点的所有结点总数,遍历所有结点后rear=front
	}
	return OK;
}

Status Deepth(BiTree T)//求树的高度
{
	int deepthLeft = 0;
	int deepthRight = 0;
	int deepCount = 0;
	if (T == NULL) {
		deepCount = 0;
		return deepCount;
	}	
	deepthLeft = Deepth(T->lchild);
	deepthRight = Deepth(T->rchild);
	deepCount = 1 + ((deepthLeft > deepthRight) ? deepthLeft : deepthRight);//在左子树和右子树中求最高的那棵树,总树高为其加1
	return deepCount;
}

Status PreorderPrintLeaves(BiTree BT)//先序输出树的结点
{
	if (BT == NULL)
	{
		return ERROR;
	}
	else {
		if (BT->lchild == NULL&&BT->rchild == NULL) printf("%d ", BT->data);
		PreorderPrintLeaves(BT->lchild);
		PreorderPrintLeaves(BT->rchild);
	}
	return OK;
}

-----------随便写了一下主函数,,,都用的非递归的遍历,,,觉得非递归的遍历时间复杂度太高了

int main(void)
{
	BiTree T;
	printf("请输入数据先序创建一棵二叉树:(结点为空时输入0)\n");
	T = CreateTree();               //先序创建一棵二叉树 
	printf("先序遍历结果为:\n");
	PreOrderTraverse2(T, PrintElement);
	printf("\n");
	printf("中序遍历结果为:\n");
	InOrderTraverse2(T, PrintElement);
	printf("\n");
	printf("后序遍历结果为:\n");
	PostOrderTraverse2(T, PrintElement);
	printf("\n");
	printf("层序遍历结果为:\n");
	LevelOrderTraverse(T);
	printf("\n");
	LevelOrderTraverse(T, PrintElement);
	printf("\n");
	printf("此树的高度为:\n");
	printf("%d\n", Deepth(T));
	printf("其树结点为:(先序)\n");
	PreorderPrintLeaves(T);
	printf("\n");
	return 0;
}

也算是我对数据结构二叉树这一章的总结吧,记录一下自己的学习历程!冲鸭!

猜你喜欢

转载自blog.csdn.net/qq_41888422/article/details/84581891