二叉树的基本用法总结

本文总结了二叉树的基础操作,包括树的创建、删除及四种遍历方式(先序、后序、中序、层次遍历)。此外,还涵盖了节点查找、插入、寻找兄弟节点与父节点,计算树的深度、叶子数、节点数,以及树的复制、对比和满树、完全树的判断。虽然代码质量有待提高,但实现了所有基本功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面列举了二叉树的一些常用方法,水平有限 代码写的质量不怎么地,基本功能是实现了的

功能有:树的建立、删除;

先序、后序、中序、层次遍历;

节点的查找,节点的插入;

兄弟的查找,父节点的查找;

计算树的深度、叶子数、节点数;

树的拷贝;

判断两个树是否相等;

判断是否是满树、完全树;

#include<iostream>
#include<stack>
#include<stdlib.h>
#include<math.h>
#include<deque>
using namespace std;

typedef struct BTreeNode
{
  char data;
  struct BTreeNode * LeftChild;
  struct BTreeNode * RightChild;
}node,*root;

void CreateTree(root &root_node)//创建树 指针的引用 #代表空节点  先序输入  如ABD##E##CF##G##(中间不要有空格)
{
	char c='#';
	c=getchar();
	if (c=='#')
	{
		root_node=NULL;
		return ;
	}
   //否则
    root_node=(root)malloc(sizeof(node));
	root_node->data=c;
	CreateTree(root_node->LeftChild);
	CreateTree(root_node->RightChild);
	return ;

}

void PreOrder(root root_node)//先序输出
{
  if (root_node==NULL)
  {
	  return;
  }
  else
  {
	  cout<<root_node->data;
	  PreOrder(root_node->LeftChild);
	  PreOrder(root_node->RightChild);
  }
}

void InOrder(root root_node)//中序
{
	if (root_node==NULL)
	{
		return;
	}
	else
	{
		InOrder(root_node->LeftChild);
		cout<<root_node->data;
		InOrder(root_node->RightChild);
	}

}

void PostOrder(root root_node)//后序
{
  if (root_node==NULL)
  {
	  return;
  }
  else
  {
	  PostOrder(root_node->LeftChild);
	  PostOrder(root_node->RightChild);
	  cout<<root_node->data;
  }
}

void LevelOrder(root root_node)//层次遍历
{
	deque<root>node_list;
	if (root_node==NULL)
	{
		return;
	}
	else
		node_list.insert(node_list.begin(),root_node);

	while(node_list.size()!=0)
	{
		root node_temp=node_list[0];
		node_list.pop_front();
		cout<<node_temp->data;

		if (node_temp->LeftChild!=NULL)
		{
			node_list.push_back(node_temp->LeftChild);
		}
		if (node_temp->RightChild!=NULL)
		{
			node_list.push_back(node_temp->RightChild);
		}

	}
	

}

bool IsEmpty(root root_node) //判空
{
	return ((root_node==NULL)?true:false);
}

void DestoryTree(root &root_node)//删除以root_node为根的树
{
  if (root_node==NULL)
  {
	  return;
  }
  else
  {
	  DestoryTree(root_node->LeftChild);
	  DestoryTree(root_node->RightChild);
	  free(root_node);
	  root_node=NULL;
  }
}

root GetParent(root root_node,root p)//找p的双亲  root_node为树根节点
{
	root root_q;
	if (root_node==NULL || p==NULL)
	{
		root_q=NULL;
		return root_q;
	}

  if (root_node->LeftChild==p || root_node->RightChild==p)
  {
	  return root_node;
  }
  else
  {
    root_q=GetParent(root_node->LeftChild,p);
	if (root_q!=NULL)
	{
		return root_q;
	}

	root_q=GetParent(root_node->RightChild,p);
	return root_q;
  }
}

root GetPoint(root root_node,char c)//在树root_node中找到节点值为c的节点 返回其指针
{
	root q;
   if(root_node==NULL)
	   return NULL;
   if(root_node->data==c)
	   return root_node;
   else
   {
	   q=GetPoint(root_node->LeftChild,c);
	   if(q!=NULL)
		   return q;

	   q=GetPoint(root_node->RightChild,c);
		   return q;
   }
}

root GetLeftBrother(root root_node,root p)//找p的左侧兄弟
{

	if (root_node==NULL || p==NULL)
	{
		return NULL;
	}
	root pr_node=GetParent(root_node,p);
	if (pr_node==NULL || p==pr_node->LeftChild)
	{
		return NULL;
	}
	else 
	{
		return pr_node->LeftChild;
	}

}

root GetRightBrother(root root_node,root p)//找p的右侧兄弟
{
	if (root_node==NULL || p==NULL)
	{
		return NULL;
	}
	root pr_node=GetParent(root_node,p);
	if (NULL==pr_node || p==pr_node->RightChild)
	{
		return NULL;
	}
	else
		return pr_node->RightChild;

}

int GetDepth(root root_node)//计算树的深度  
{
	int n_left;
	int n_right;
  if (root_node==NULL)
  {
	  return 0;
  }
  else
  {
	  n_left=GetDepth(root_node->LeftChild);
	  n_right=GetDepth(root_node->RightChild);
	  return (n_left>n_right?n_left:n_right)+1;

  }
}

int GetLeaves(root root_node)//计算叶子数
{
	int leaves;
	int L_leaves;
	int R_leaves;
	if(root_node==NULL)
		return 0;
	if (root_node->LeftChild ==NULL && root_node->RightChild==NULL)
	{
       return 1;
	}
	else
	{
		L_leaves=GetLeaves(root_node->LeftChild);
		R_leaves=GetLeaves(root_node->RightChild);
		leaves=L_leaves+R_leaves;
		return leaves;
	}
}

void CopyTree(root root_node1,root &root_node2)//拷贝树 root_node1拷贝到root_node2
{
	root newnode;
	if (root_node1==NULL)
	{
		root_node2=NULL;
		return;
	}
	root_node2=(root)malloc(sizeof(node));
	root_node2->data=root_node1->data;
	CopyTree(root_node1->LeftChild,root_node2->LeftChild);
	CopyTree(root_node1->RightChild,root_node2->RightChild);
   
}

void InsertLeftChild(root &node_p,char c)//为节点node_p插入一个左儿子 值为c,node_p原来的的左儿子作为新节点的左儿子
{
	if (node_p==NULL)
	{
		return;
	}

	root left_child=node_p->LeftChild;
   root newnode=(root)malloc(sizeof(node));
   node_p->LeftChild=newnode;
   newnode->LeftChild=left_child;
   newnode->data=c;
   newnode->RightChild=NULL;
}
void InsertRightChild(root &node_p,char c)//为节点node_p插入一个右儿子 值为c,node_p原来的的右儿子作为新节点的右儿子
{
	if (node_p==NULL)
	{
		return;
	}

	root right_child=node_p->RightChild;
	root newnode=(root)malloc(sizeof(node));
	node_p->RightChild=newnode;
	newnode->RightChild=right_child;
	newnode->data=c;
	newnode->LeftChild=NULL;
}

bool IsTreeEqual(root root_node1,root root_node2)//判断两个树是否相等
{
   if (root_node1==NULL && root_node2==NULL)
   {
	   return true;
   }
   if (root_node1==NULL && root_node2!=NULL)
   {
	   return false;
   }
   if (root_node1!=NULL && root_node2==NULL)
   {
	   return false;
   }

   if (root_node1->data==root_node2->data && IsTreeEqual(root_node1->LeftChild,root_node2->LeftChild)==true && IsTreeEqual(root_node1->RightChild,root_node2->RightChild)==true)
   {
	   return true;
   }
   else 
	   return false;

}

int GetNodeCount(root root_node)//计算树的节点数
{
	int L_count,R_count,ALL_count;
	if (root_node==NULL)
	{
		return 0;
	}
	else
	{
		L_count=GetNodeCount(root_node->LeftChild);
		R_count=GetNodeCount(root_node->RightChild);
        ALL_count=L_count+R_count+1;
		return ALL_count;
	}

}

bool IsCompleteTree(root root_node)//是否是完全树
{
	deque<root>node_list;
	if (root_node==NULL)
	{
		return false;
	}
	else
		node_list.insert(node_list.begin(),root_node);

	int i=0;
	root temp;
	while(i<node_list.size())//所有节点全部进入队列  包括空节点
	{
		temp=node_list[i];
		if (temp!=NULL)
		{
			node_list.push_back(temp->LeftChild);
			node_list.push_back(temp->RightChild);
		}
		i++;
	}

	i=0;
	while (i<node_list.size())//查找空节点后面是否会有非空节点  若有则说明不是完全树
	{
		if (node_list[i]==NULL)
		{
			int j=i;
			while (j<node_list.size())//查找空节点后面是否会有非空节点
			{
				if (node_list[j]!=NULL)
				{
					return false;
				}
				j++;
			}
			return true;
		}
		else
		{
			i++;
			continue;
		}
	}
   return false;
} 



bool IsFullTree(root root_node)//是否是满树
{
   int count=GetNodeCount(root_node);//节点数
   int depth=GetDepth(root_node);//深度
   double a=2.0;
   int num=(int)(pow(a,double(depth)))-1;
   if (num==count)//节点数是否等于2^k-1
   {
	   return true;
   }
   else
	   return false;

}


void EatLine()//消除回车
{
  while(getchar()!='\n')
	{
	}
}


void main()//用来测试
{
    char c;
	char d;
	root root_node;
	root root_node2=NULL;

	CreateTree(root_node);
	EatLine();

	bool empty;
	empty=IsEmpty(root_node);
	if (empty==true)
	{
		cout<<"the tree is empty\n";
	}
	else
		cout<<"the tree is not empty\n";

	int depth=GetDepth(root_node);
	cout<<"the depth of tree is "<<depth<<endl;

	int leaves=GetLeaves(root_node);
	cout<<"the COUNT of leaves is "<<leaves<<endl;

	bool comlete=IsCompleteTree(root_node);
	if (comlete==true)
	{
		cout<<"the tree is comlete\n";
	}
	else
		cout<<"the tree is not comlete\n";

	bool full=IsFullTree(root_node);
	if (full==true)
	{
		cout<<"the tree is full\n";
	}
	else
		cout<<"the tree is not full\n";

	

	cout<<"pre:\n";
	PreOrder(root_node);
	cout<<endl;
	cout<<"In:\n";
	InOrder(root_node);
	cout<<endl;
	cout<<"post:\n";
	PostOrder(root_node);
	cout<<endl;
	cout<<"level:\n";
	LevelOrder(root_node);
	cout<<"\n"<<endl;

	CopyTree(root_node,root_node2);
	cout<<"copy tree in pre:\n";
	PreOrder(root_node2);
	cout<<endl;
	cout<<"copy tree in In:\n";
	InOrder(root_node2);
	cout<<endl;
	cout<<"copy tree in post:\n";
	PostOrder(root_node2);
	cout<<endl;
	cout<<"copy tree in level:\n";
	LevelOrder(root_node);
	cout<<"\n"<<endl;

	if(IsTreeEqual(root_node,root_node2)==true)
	{
		cout<<"the two tree is equal\n";
	}
	else
		cout<<"the two tree is not equal\n";



	cout<<"input the node and char wanted insert in tree root_node2(end of #)\n";//插入左儿子
	while (1)
	{
		cout<<"input node :";//在哪个节点插入
		c=getchar();
		EatLine();

		if(c=='#')
			break;
		cout<<"input char wangted insert :";//插入什么值
		d=getchar();
		EatLine();

		if(d=='#')
			break;

		root temp=GetPoint(root_node2,c);
		InsertLeftChild(temp,d);
		cout<<"InsertLeftChild "<<d<<" behead of "<<c<<" in pre:\n";
		PreOrder(root_node2);
		cout<<"\n"<<endl;

		int depth=GetDepth(root_node2);
		cout<<"the depth of tree is "<<depth<<endl;

		int leaves=GetLeaves(root_node2);
		cout<<"the COUNT of leaves is "<<leaves<<endl;

		if(IsTreeEqual(root_node,root_node2)==true)
		{
			cout<<"the two tree is equal\n";
		}
		else
			cout<<"the two tree is not equal\n";


		comlete=IsCompleteTree(root_node2);
		if (comlete==true)
		{
			cout<<"the tree is comlete\n";
		}
		else
			cout<<"the tree is not comlete\n";
 
	}

	cout<<"\n"<<endl;



	cout<<"input the char wanted delete in tree root_node2(end of #)\n";//删除子树
	while (1)
	{
		cout<<"input char wangted delete :";
		d=getchar();
		EatLine();

		if(d=='#')
			break;

		root P_delete=GetPoint(root_node2,d);//找到要删除的节点的指针
		root temp=P_delete;//备份这个指针
		root p=GetParent(root_node2,P_delete);//找到此点的父节点
		DestoryTree(P_delete);//删掉这个节点子树
		if (p->LeftChild==temp)//在树中把这个节点指针赋值为空
		{
			p->LeftChild=NULL;
		}
		else
			p->RightChild=NULL;

		cout<<"after DestoryTree "<<d<<" in pre:\n";
		PreOrder(root_node2);
		cout<<"\n";

		depth=GetDepth(root_node2);
		cout<<"the depth of tree is "<<depth<<endl;

		leaves=GetLeaves(root_node2);
		cout<<"the COUNT of leaves is "<<leaves<<endl;

		if(IsTreeEqual(root_node,root_node2)==true)
		{
			cout<<"the two tree is equal\n";
		}
		else
			cout<<"the two tree is not equal\n"<<endl;

		comlete=IsCompleteTree(root_node2);
		if (comlete==true)
		{
			cout<<"the tree is comlete\n";
		}
		else
			cout<<"the tree is not comlete\n";

		bool full=IsFullTree(root_node2);
		if (full==true)
		{
			cout<<"the tree is full\n";
		}
		else
			cout<<"the tree is not full\n";
	}
        


	cout<<"input the char wanted find in tree root_node(end of #)\n";//查找节点
	while((c=getchar())!='#')
	{
	 EatLine();
     root q_find=GetPoint(root_node,c);
	 root parent=GetParent(root_node,q_find);
	 if(parent!=NULL)
		cout<<"parent of "<<c<<" is:"<<parent->data<<endl;
	 else
		cout<<"can't find parent"<<endl;
	 
	 root left_brother=GetLeftBrother(root_node,q_find);
	 if (left_brother!=NULL)
	 {
		 cout<<"left brother of "<<c<<" is:"<<left_brother->data<<endl;
	 }
	 else
         cout<<"can't find left brother"<<endl;

	 root right_brother=GetRightBrother(root_node,q_find);
	 if (right_brother!=NULL)
	 {
		 cout<<"right brother of "<<c<<" is:"<<right_brother->data<<endl;
	 }
	 else
		 cout<<"can't find right brother"<<endl;

	}
	

	

	system("pause");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值