数据结构之树的操作大全

 

目录

 1、树的类型定义

 2、创建二叉树

 3、三种遍历方式

              ①、先序遍历

              ②、中序遍历

              ③、后序遍历

              ④、层次遍历

4、二叉树的复制

5、计算树的深度

6、统计结点个数

               ①、统计结点总数

               ②、统计叶子节点个数

               ③、统计度数为1的结点个数

               ④ 、统计度数为2的结点个数

7、树的反转

8、主函数的测试代码段

9、效果图                

  我们事先定义如果树结点的数据域为‘#’时,则这个结点为叶子节点,没有左右孩子,当然也可以直接把这个结点定义为NULL。

  如果对树中进行增加或删除结点的操作,需要对函数形参中的树名用引用的方式传入,因为形参在函数调用结束后编译器会自动对形参释放空间,即使用指针进行传入,释放后也会对原树增加或删除结点的操作无效。

 1、树的类型定义

typedef struct tree
{
	char date;
	struct tree* lchild;
	struct tree* rchild;
}*pnode,node;

 2、创建二叉树

//创建二叉树
int creattree(pnode &tree, string s,unsigned int n)
{
	char c = s[n];
	n = n + 1;
	if (c != '\0')
	{
		if (c == '#')
		{
			tree = new node;
			tree->date = '#';
			tree->lchild = NULL;
			tree->rchild = NULL;
		}
		else
		{
			tree = new node;
			tree->date = c;
			n = creattree(tree->lchild, s, n);
			n = creattree(tree->rchild, s, n);
		}
	}
	return n;
	
}

 3、三种遍历方式

              ①、先序遍历

//先序输出
void preorder(pnode tree)
{
	if (tree->date != '#')
	{
		cout << tree->date;
		preorder(tree->lchild);
		preorder(tree->rchild);
	}
}

              ②、中序遍历

//中序输出
void inorder(pnode tree)
{
	if (tree->date != '#')
	{
		inorder(tree->lchild);
		cout << tree->date;
		inorder(tree->rchild);
	}
}

              ③、后序遍历

//后序输出
void postorder(pnode tree)
{
	if (tree->date != '#')
	{
		postorder(tree->lchild);
		postorder(tree->rchild);
		cout << tree->date;
	}
}

              ④、层次遍历

void leveloutput(pnode tree)
{
	queue<pnode>q;
	if (tree->date != '#')
	{
		q.push(tree);
	}
	while (!q.empty())
	{
		cout << q.front()->date;
		q.pop();
		if (tree->lchild->date != '#')
		{
			q.push(tree->lchild);
			
		}
		if (tree->rchild->date != '#')
		{
			q.push(tree->rchild);
		
		}
		if (!q.empty())
		{
			tree = q.front();
		}
		
	}
}

4、二叉树的复制

//复制二叉树
void copytree(pnode &tree, pnode &newtree)
{
	if (tree == NULL)
	{
		newtree = NULL;
	}
	else
	{
		newtree = new node;
		newtree->date = tree->date;
		copytree(tree->lchild, newtree->lchild);
		copytree(tree->rchild, newtree->rchild);
	}
}

5、计算树的深度

//计算树的深度
int depth(pnode tree)
{
	int ld = 0, rd;
	if (tree->date == '#')
	{
		return 0;
	}
	else
	{
		ld = depth(tree->lchild);
		rd = depth(tree->rchild);
		return (ld > rd ? ld : rd) + 1;
	}
}

6、统计结点个数

               ①、统计结点总数

//统计树的结点个数
int nodenum(pnode tree)
{
	if (tree->date == '#')
	{
		return 0;
	}
	else
	{
		return nodenum(tree->lchild) + nodenum(tree->rchild) + 1;
	}
}

               ②、统计叶子节点个数

//统计叶子节点个数
int nodenum0(pnode tree)
{
	int count;
	if (tree->date == '#')
	{
		count = 0;
	}
	else
	{
		if (tree->lchild->date == '#'&&tree->rchild->date == '#')
		{
			count = 1;
		}
		else
		{
			count = nodenum0(tree->lchild) + nodenum0(tree->rchild);
		}
	}
	return count;
}

               ③、统计度数为1的结点个数

//统计度数为1的结点个数
int nodenum1(pnode tree)
{
	int count;
	if (tree->date == '#')
	{
		count = 0;
	}
	else
	{
		if ((tree->lchild->date == '#'&&tree->rchild->date != '#')
			|| (tree->lchild->date != '#'&&tree->rchild->date == '#'))
		{
			count = 1;
		}
		else
		{
			count = nodenum1(tree->lchild) + nodenum1(tree->rchild);
		}
	}
	return count;
}

               ④ 、统计度数为2的结点个数

//统计度数为2的结点个数
int nodenum2(pnode &tree)
{
	int count;
	if (tree->date == '#')
	{
		count = 0;
	}
	else
	{
		if (tree->lchild->date != '#'&&tree->rchild->date != '#')
		{
			count = 1;
		}
		else
		{
			count = nodenum1(tree->lchild) + nodenum1(tree->rchild);
		}
	}
	return count;
}

7、树的反转

//反转树
void rotation(pnode tree, pnode &newtree)
{
	if (tree->date == '#')
	{
		newtree = new node;
		newtree->date = '#';
		newtree->lchild = NULL;
		newtree->rchild = NULL;
	}
	else
	{
		newtree = new node;
		newtree->date = tree->date;
		rotation(tree->lchild, newtree->rchild);
		rotation(tree->rchild, newtree->lchild);
	}
}

8、主函数的测试代码段

int main()
{
	//ab#f##gc###
	pnode ptree1 = NULL, ptree2 = NULL, ptree3 = NULL;
	string s;
	cout << "请输入字符串:";
	cin >> s;
	if (s.size() == creattree(ptree1, s, 0))
	{
		cout << "二叉树建立成功!" << endl;
	}
	cout << "先序遍历:";
	preorder(ptree1);
	cout << "\n中序遍历:";
	inorder(ptree1);
	cout << "\n后序遍历:";
	postorder(ptree1);
	cout << "\n层次遍历:";
	leveloutput(ptree1);
	cout << "\n树的深度:" << depth(ptree1) << endl;
	cout << "树的结点个数:" << nodenum(ptree1) << endl;
	cout << "树的叶子结点个数:" << nodenum0(ptree1) << endl;
	cout << "树的度为1的结点个数:" << nodenum1(ptree1) << endl;
	cout << "树的度为2的结点个数:" << nodenum2(ptree1) << endl;
}

9、效果图

 

 

  • 3
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

small_planet

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

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

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

打赏作者

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

抵扣说明:

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

余额充值