lwq的学习日记(7)

以下主要介绍二叉树的相关操作,有新的操作时会更新。

1:二叉树的基本存储

以结构体存储,代码如下

typedef struct elwq {
	char e;
	struct elwq *l_c, *r_c;
}elwq, *etree;

l_c和r_c分别为左右结点,e代表值;

2:创建一个二叉树

void creattree(etree &T)
{
	char sh;
	cin >> sh;
	if (sh == '#')
	{
		T = NULL;
	}
	else
	{
		T = (etree )malloc(sizeof(elwq));
		T->e = sh;
		creattree(T->l_c);
		creattree(T->r_c);
	}
	
}

 若输入"#"则代表该结点为空,需要特别注意的是,二叉树的输入需要按照二叉树的结构进行顺序输入。这里采用的是前序遍历方式。

例如

579398ca6ecf4ad3b4e159013d743e1b.png

 若实现该二叉树,则输入的数据应是123###4#5##

3:二叉树的前序遍历

void qx(etree T)
{
	if (T)
	{
		cout << T->e << " ";
		qx(T->l_c);
		qx(T->r_c);
	}
}

主要思想为递归,根据前序遍历的顺序不断递归左右结点即可。

下面两种遍历方式也是如此。

4:二叉树的中序遍历

void zx(etree T)
{
	if (T)
	{
		zx(T->l_c);
		cout << T->e << " ";
		zx(T->r_c);
	}
	
}

5:二叉树的后序遍历

void hx(etree T)
{
	if (T)
	{
		hx(T->l_c);
		hx(T->r_c);
		cout << T->e << " ";
	}
	
}

6:二叉树的层序遍历

void c_print(etree T)
{
	if (T == NULL)
	{
		cout << "当前树为空,无节点输出" << endl;
	}
	else
	{
		q.push(T);
		while (q.size())
		{
			auto t = q.front();
			q.pop();
			cout << t->e <<" ";
			if (t->l_c) q.push(t->l_c);
			if (t->r_c) q.push(t->r_c);
		}
	}
}

二叉树的层序遍历主要利用队列实现。当树非空时,先将头结点放入队列中,若队列非空,将该元素出队,同时输出该元素,若该元素的左子结点不空,则将其左子结点入队,右节点同理,以此来达到实现二叉树的层序遍历

7:二叉树的深度

int depth(etree T)
{
	if (T == NULL)  return 0;
	else
	{
		int ans1 = depth(T->l_c);
		int ans2 = depth(T->r_c);
		return ans1 > ans2 ? ans1 + 1 : ans2 + 1;
	}
}

主要思想仍为递归,不断递归遍历左右子结点,最后寻找左右子结点最深长度即可

8:二叉树的结点数

int countnode(etree T)
{
	if (T == NULL) return 0;
	else
	{
		return countnode(T->l_c) + countnode(T->r_c) + 1;
	}

}

递归遍历个个结点的子结点即可

9:二叉树的叶子结点数

int  countynode(etree T)
{
	if (T == NULL) return 0;
	else
	{
		int ans = 0;
		if (!T->l_c && !T->r_c) ans++;
		ans += countynode(T->l_c) + countynode(T->r_c);
		return ans;

	}
}

叶子结点意味着该结点无子结点,仍主要利用递归寻找左右子结点的叶子结点,若满足则ans++即可

全部代码

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
typedef long long LL;
typedef pair<int, int>PII;
const int N = 1e6 + 10;
typedef struct elwq {
	char e;
	struct elwq *l_c, *r_c;
}elwq, *etree;
queue<etree>q;
void creattree(etree &T)
{
	char sh;
	cin >> sh;
	if (sh == '#')
	{
		T = NULL;
	}
	else
	{
		T = (etree )malloc(sizeof(elwq));
		T->e = sh;
		creattree(T->l_c);
		creattree(T->r_c);
	}
	
}
void qx(etree T)
{
	if (T)
	{
		cout << T->e << " ";
		qx(T->l_c);
		qx(T->r_c);
	}
}
void zx(etree T)
{
	if (T)
	{
		zx(T->l_c);
		cout << T->e << " ";
		zx(T->r_c);
	}
	
}
void hx(etree T)
{
	if (T)
	{
		hx(T->l_c);
		hx(T->r_c);
		cout << T->e << " ";
	}
	
}
int countnode(etree T)
{
	if (T == NULL) return 0;
	else
	{
		return countnode(T->l_c) + countnode(T->r_c) + 1;
	}

}
//输出叶子节点
int  countynode(etree T)
{
	if (T == NULL) return 0;
	else
	{
		int ans = 0;
		if (!T->l_c && !T->r_c) ans++;
		ans += countynode(T->l_c) + countynode(T->r_c);
		return ans;

	}
}
int depth(etree T)
{
	if (T == NULL)  return 0;
	else
	{
		int ans1 = depth(T->l_c);
		int ans2 = depth(T->r_c);
		return ans1 > ans2 ? ans1 + 1 : ans2 + 1;
	}
}
//按层输出二叉树中所有节点
void c_print(etree T)
{
	if (T == NULL)
	{
		cout << "当前树为空,无节点输出" << endl;
	}
	else
	{
		q.push(T);
		while (q.size())
		{
			auto t = q.front();
			q.pop();
			cout << t->e <<" ";
			if (t->l_c) q.push(t->l_c);
			if (t->r_c) q.push(t->r_c);
		}
	}
}
int main()
{
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout << "1:创建一个二叉树" << endl;
	cout << "2:二叉树的前序遍历" << endl;
	cout << "3:二叉树的中序遍历" << endl;
	cout << "4:二叉树的后序遍历" << endl;
	cout << "5:二叉树的层序遍历" << endl;
	cout << "6:二叉树的深度" << endl;
	cout << "7:二叉树的结点数" << endl;
	cout << "8:二叉树的叶子结点数" << endl;
	cout << "0:退出" << endl;
	int x;
	etree T = NULL;
	while (cin >> x)
	{
		if (x == 0) return 0;
		else if (x == 1)
		{
			creattree(T);
		}
		else if (x == 2)
		{
			qx(T);
			cout << endl;
		}
		else if (x == 3)
		{
			zx(T);
			cout << endl;
		}
		else if (x == 4)
		{
			hx(T);
			cout << endl;
		}
		else if (x == 5)
		{
			c_print(T);
			cout << endl;
		}
		else if (x == 6)
		{
			cout << depth(T) << endl;
			
		}
		else if (x == 7)
		{
			cout << countnode(T) << endl;
			
		}
		else if (x == 8)
		{
			cout << countynode(T) << endl;
		}
	}

}

以上就是本文对的全部内容,多谢观看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值