数据结构之链表二叉树实现

数据结构之链表二叉树实现

代码及思想

//链式二叉树
/*参考 
https://www.cnblogs.com/liuzeyu12a/p/10420665.html
https://blog.csdn.net/weixin_40411915/article/details/82808227
测试数据:abd###c#e##
*/ 
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

typedef char ElemType;
typedef int Status; 
#define OK 1
#define ERROR 0

/***************结构体定义***************/
typedef struct BiTNode
{
	ElemType data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

/***************函数定义***************/
void InitBiTree(BiTree &T);//二叉树初始化
void CreateBiTree(BiTree &T);//创建二叉树
bool BiTreeEmpty(BiTree &T);//判断二叉树是否为空
int BiTreeDepth1(BiTree &T);//求树的深度
int BiTreeDepth2(BiTree &T);//求树的深度
void Visit(ElemType e);//打印某一结点
void PreOrderTraverse(BiTree &T);//二叉树递归先序遍历 
void InOrderTraverse(BiTree &T);//二叉树递归中序遍历
void PostOrderTraverse(BiTree &T);//二叉树递归后序遍历
int CountLeaf1(BiTree &T,int &count1);//计算叶子结点数
int CountLeaf2(BiTree &T);//计算叶子结点数
int CountNode(BiTree T);//计算结点数 
int max(int a,int b);//返回较大值
ElemType Parent(BiTree &T,ElemType e);//求父节点的值
BiTree FindNode(BiTree &T,ElemType e);//寻找某个结点,返回指向这个节点的指针
void LeftSibling(BiTree &T,ElemType e);//输出某个结点的左兄弟
void RightSibling(BiTree &T,ElemType e);//输出某个结点的右兄弟 
 
Status levelTraverse(BiTree T);//二叉树层次遍历
Status preOrderTraverseEX(BiTree T);//先序遍历非递归
Status InOrderTraverseEX(BiTree T);//中序遍历非递归
Status PostOrderTraverseEX(BiTree T);//后序遍历非递归
Status DestroyBiTree(BiTree T);//二叉树销毁 
//https://blog.csdn.net/weixin_40411915/article/details/82808227

//https://blog.csdn.net/baidu_38304645/article/details/82964439
Status ExchangeBiTree(BiTree &T); //将树各节点的左右孩子互换
Status DeleteChild(BiTree &T,ElemType x);//删除根结点值为x的子树

/***************函数实现***************/
void InitBiTree(BiTree &T)//二叉树初始化
{
	T = (BiTNode *)malloc(sizeof(BiTNode));//malloc()的返回值可以强制类型转换
	T -> lchild = NULL;
	T -> rchild = NULL;
}
/* 
void CreateBiTree(BiTree *T)//递归创建二叉树 
{
	ElemType ch;
	scanf("%c",&ch);
	if(ch == '#')
		*T = NULL;
	else
	{
		cout<<"126511"<<endl;
		*T = (BiTree )malloc(sizeof(BiTNode));//创建新结点加入树 
		if(!T) return;	
		(*T)->data = ch;
		CreateBiTree(&(*T)->lchild);
		CreateBiTree(&(*T)->rchild);
	}
}
*/

void CreateBiTree(BiTree &T)//递归创建二叉树 
{
	ElemType ch;
	scanf("%c",&ch);
	if(ch == '#')
		T = NULL;
	else
	{
		T = (BiTNode *)malloc(sizeof(BiTNode));//创建新结点加入树 
	//	if(!T) return;	
		T->data = ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild);
	}
}


bool BiTreeEmpty(BiTree &T)//判断二叉树是否为空
{
	if(T)
		return false;
	return true;
}

int BiTreeDepth1(BiTree &T)//求树的深度
{
	int lDepth,rDepth;
	if(BiTreeEmpty(T))
		return ERROR;
	if(T->lchild)
		lDepth = BiTreeDepth1(T->lchild);
	else
		lDepth = 0;
	if(T->rchild)
		rDepth = BiTreeDepth1(T->rchild);
	else
		rDepth = 0;
	return lDepth > rDepth ? lDepth+1 : rDepth+1;//二叉树深度为左右子树深度较大值加1 
}

int BiTreeDepth2(BiTree &T)//求树的深度
{
	int lDepth,rDepth;
	if(T == NULL)
		return 0;
	else
		return max(BiTreeDepth2(T->lchild),BiTreeDepth2(T->rchild))+1;//二叉树深度为左右子树深度较大值加1 
}

void Visit(ElemType e)//打印某一结点
{
	cout<<e<<" ";
}

void PreOrderTraverse(BiTree &T)//二叉树递归先序遍历
{
	if(T)
	{
		Visit(T->data);
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);	
	} 
} 

void InOrderTraverse(BiTree &T)//二叉树递归中序遍历
{
	if(T)
	{
		InOrderTraverse(T->lchild);
		Visit(T->data);
		InOrderTraverse(T->rchild);
	}
}

void PostOrderTraverse(BiTree &T)//二叉树递归后序遍历
{
	if(T)
	{
		PostOrderTraverse(T->lchild);
		PostOrderTraverse(T->rchild);
		Visit(T->data);
	}
}

int CountLeaf1(BiTree &T,int &count1)//计算叶子结点数
{
	if(T)
	{
		if((T->lchild == NULL) && (T->rchild == NULL))//判断是否为叶子结点 
		{
			count1++;	
		}	
		CountLeaf1(T->lchild,count1);
		CountLeaf1(T->rchild,count1);
	}	
	return count1;
}

int CountLeaf2(BiTree &T)//计算叶子结点数
{
	if(T == NULL)
		return 0;
	if(T->lchild == NULL && T->rchild == NULL)
		return 1;
	else
	{
		return CountLeaf2(T->lchild)+CountLeaf2(T->rchild);
	}
}

int CountNode(BiTree T)//计算结点数
{
	if(T == NULL)
		return 0;
	return CountNode(T->lchild)+CountNode(T->rchild)+1;
}

int max(int a,int b)//返回较大值
{
	return a > b ? a : b;	
}

ElemType Parent(BiTree &T,ElemType e)//求父节点的值
{
	if(T)
	{
		if( T->lchild && (T->lchild->data == e) || T->rchild && (T->rchild->data == e) )
			return T->data;
		else
		{
			Parent(T->lchild,e);
			Parent(T->rchild,e);
		}
	}
	return ' ';//失败返回空字符 
}

BiTree FindNode(BiTree &T,ElemType e)//寻找某个结点,返回指向这个节点的指针
{
	if(T == NULL)
		return NULL;
	if(T->data == e)
		return T;
	BiTree node = FindNode(T->lchild,e);
	if(node != NULL)
		return node;
	else
		return FindNode(T->rchild,e);
}

void LeftSibling(BiTree &T,ElemType e)//输出某个结点的左兄弟
{
	ElemType ch = Parent(T,e);//找到父节点
	BiTree temp = FindNode(T,ch);
	if(temp->lchild != NULL)
	{
		if(temp->lchild->data != e)
		{
			cout<<"此节点的左兄弟为:"<<temp->lchild->data<<endl;	
		}	
		else
		{
			cout<<"此节点没有左兄弟"<<endl;
		}
	} 
}

void RightSibling(BiTree &T,ElemType e)//输出某个结点的右兄弟
{
	ElemType ch = Parent(T,e);
	BiTree temp = FindNode(T,ch);
	if(temp->rchild != NULL)
	{
		if(temp->rchild->data != e)
		{
			cout<<"此节点的右兄弟为:"<<temp->rchild->data<<endl;
		}
		else
		{
			cout<<"此节点没有右兄弟"<<endl;
		}
	}	
} 

typedef struct 
{
	ElemType data[100];//数据基址
	int front,rear;//队头队尾指针;
	int length;//当前分配的容量 
}Tqueue;

Status levelTraverse(BiTree T)//二叉树层次遍历,队列 
{
	BiTree Tqueue[100];
	BiTNode *p = NULL;
	int front=0,rear=0;
	if(T)
	{
		rear = (rear + 1) % 100;
		Tqueue[rear] = T;
		printf("%c",p->data);
		if(p->lchild)
		{
			rear = (rear + 1)%100;
			Tqueue[rear] = p->lchild;
		}
		if(p->rchild)
		{
			rear = (rear + 1) % 100;
			Tqueue[rear] = p->rchild;
		}
	}
	return 1;
}

Status preOrderTraverseEX(BiTree T)//先序遍历非递归
{
	BiTree arr[100];
	BiTNode *temp = NULL;
	int len = 0;
	if(T)
	{
		arr[len] = T;
		len++;
		while(len != 0)
		{
			temp = arr[len - 1];
			while(temp)
			{
				printf("%c\n",temp->data);
				arr[len] = temp->lchild;
				len++;
				temp = arr[len-1];
			}
			temp = arr[len-1];
			len--;
			if(len != 0)
			{
				temp = arr[len - 1];
				len--;
				arr[len] = temp->rchild;
				len++;
			}
		}
		return 1;
	}
	return 0;
}

Status InOrderTraverseEX(BiTree T)//中序遍历非递归
{
	BiTree arr[100];
	BiTNode* temp = NULL;
	int len = 0;
	if (T)
	{
		arr[len] = T;
		len++;
		while (len!=0)
		{
			temp = arr[len - 1];
			while (temp)
			{
				arr[len] = temp->lchild;
				len++;
				temp = arr[len - 1];
			}
			temp = arr[len - 1];
			len--;
			if (len!=0)
			{
				temp = arr[len - 1];
				len--;
				printf("%c\n", temp->data);
				arr[len] = temp->rchild;
				len++;
			}
		}
		return 1;
	}
	return 0;
}

Status PostOrderTraverseEX(BiTree T)//后序遍历非递归
{
	BiTree arr[100];
	BiTNode* pre = NULL,* temp = T;
	int len = 0;
	if (temp)
	{
		while (temp || !(len == 0))
		{
			while (temp)
			{
				arr[len] = temp;
				len++;
				temp = temp->lchild;
			}
			if (!(len == 0))
			{
				temp = arr[len - 1];
				if (temp->rchild != NULL && temp->rchild != pre) // 右节点存在且没有被访问过
				{
					arr[len] = temp;
					temp = temp->rchild;
				}
				else
				{
					printf("%c\n", temp->data);
					pre = temp;
					temp = NULL;
				}
			}
		}
		return 1;
	}
	return 0;
}

Status DestroyBiTree(BiTree T)//二叉树递归销毁
{
	BiTNode *TL = NULL,*TR = NULL;
	if(T == NULL)
		return 0;
	TL = T->lchild;
	TR = T->rchild;
	T->lchild = NULL;
	T->rchild = NULL;
	free(T);
	T = NULL;
	DestroyBiTree(TL);
	DestroyBiTree(TR);
	return OK;
} 


Status ExchangeBiTree(BiTree &T){
//blog.csdn.net/baidu_38304645/article/details/82964439 
    //将树各节点的左右孩子互换
    BiTNode * temp;
    if(T){//如果树存在 交换左右孩子
         temp=T->lchild;
	 T->lchild=T->rchild;
	 T->rchild=temp;
	 ExchangeBiTree(T->lchild);//递归左子树 互换左右孩子
	 ExchangeBiTree(T->rchild);//递归右子树 互换左右孩子
    }
    return OK;
}


/*
void InitBiTree(BiTree &T);//二叉树初始化
void CreateBiTree(BiTree &T);//创建二叉树
bool BiTreeEmpty(BiTree &T);//判断二叉树是否为空
int BiTreeDepth(BiTree &T);//求树的深度
void Visit(ElemType e);//打印某一结点
void PreOrderTraverse(BiTree &T);//二叉树递归先序遍历 
void InOrderTraverse(BiTree &T);//二叉树递归中序遍历
void PostOrderTraverse(BiTree &T);//二叉树递归后序遍历
int CountLeaf1(BiTree &T);//计算叶子结点数
int CountLeaf2(BiTree &T);//计算叶子结点数
int CountNode(BiTree T);//计算结点数 
int max(int a,int b);//返回较大值
ElemType Parent(BiTree &T,ElemType e);//求父节点的值
BiTree FindNode(BiTree &T,ElemType e);//寻找某个结点,返回指向这个节点的指针
void LeftSibling(BiTree &T,ElemType e);//输出某个结点的左兄弟
void RightSibling(BiTree &T,ElemType e);//输出某个结点的右兄弟 

Status levelTraverse(BiTree T);//二叉树层次遍历
Status preOrderTraverseEX(BiTree T);//先序遍历非递归
Status InOrderTraverseEX(BiTree T);//中序遍历非递归
Status PostOrderTraverseEX(BiTree T);//后序遍历非递归
Status DestroyBiTree(BiTree T);//二叉树销毁 
*/ 

/***************主函数测试***************/
int main()
{
	BiTree T;
	char B='b',C='c';
	int count1=0,count2=0; 
	
	InitBiTree(T);
	cout<<"请输入二叉树初始化数据,'#'为空结点"<<endl; 
	CreateBiTree(T);
	
	cout<<"*前序遍历为:"<<endl;
	PreOrderTraverse(T); 
	cout<<endl;
	
	cout<<"*中序遍历为:"<<endl;
	InOrderTraverse(T);
	cout<<endl;
	
	cout<<"*后序遍历为:"<<endl;
	PostOrderTraverse(T);
	cout<<endl;
	
	cout<<"#树的高度为(法一、法二):"<<BiTreeDepth1(T)<<" "<<BiTreeDepth2(T)<<endl;
	cout<<"#树的叶子结点个数为(法一、法二):"<<CountLeaf1(T,count1)<<" "<<CountLeaf2(T)<<endl;
	cout<<"#树的结点个数为:"<<CountNode(T)<<endl;
	cout<<"#元素'b'的父亲结点为:"<<Parent(T,B)<<endl;
	cout<<"#元素'b'的右兄弟结点为:"<<endl;
	RightSibling(T,B);
	cout<<"#元素'c'的左兄弟结点为:"<<endl;
	LeftSibling(T,C);
	cout<<"#元素'c'的右兄弟结点为:"<<endl;
	RightSibling(T,C);
	
	DestroyBiTree(T);
	
	return 0;
}

测试截图

在这里插入图片描述

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李霁明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值