SCAU 8608 实现二叉排序树的各种算法(综合性实验)

借助了点集成好的函数和STL,仅供参考

#include <iostream>
#include "cstring"
#include<stack>
#include<queue>
using namespace std;

struct tree {
	int data;//数据域
	tree* lc, * rc;//指针域,指向左右节点
};//用链表存储树节点

//创建二叉树(递归)
void Create(tree*& T, int e)
{
	//如果指向的地址为空,则创建空间并将数据e赋值进去形成新节点
	if (!T) {
		tree* p = new tree;
		p->data = e;
		p->lc = p->rc = NULL;
		T = p;
	}
	else if (e < T->data)Create(T->lc, e);//如果数据e比当前节点的数据域小,则访问其左子树
	else if (e > T->data)Create(T->rc, e);//如果数据e比当前节点的数据域大,则访问其右子树
}

//前序遍历
void PreOrderTraverse(tree* T) {
	if (!T)return;
	cout << T->data << ' ';
	PreOrderTraverse(T->lc);
	PreOrderTraverse(T->rc);

} // PreOrderTraverse

//中序遍历
void InOrderTraverse(tree* T) {
	if (!T)return;
	InOrderTraverse(T->lc);
	cout << T->data << ' ';
	InOrderTraverse(T->rc);


} // InOrderTraverse

//后序遍历
void PostOrderTraverse(tree* T) {
	if (!T)return;
	PostOrderTraverse(T->lc);
	PostOrderTraverse(T->rc);
	cout << T->data << ' ';
} // PostOrderTraverse 

//查找要查找的数据data是否在该二叉排序树里,有返回1,没有则返回0(递归)
void Find(tree* T, int data) {
	if (!T) {
		cout << 0 << endl;
		return;
	}
	if (data < T->data)Find(T->lc, data);
	else if (data > T->data)Find(T->rc, data);
	else {
		cout << 1 << endl;
		return;
	}

}

//插入数据e到二叉排序树中(递归)
void Insert(tree*& T, int e)
{
	//原理与上面的创建差不多
	if (!T) {
		tree* p = new tree;
		p->data = e;
		p->lc = p->rc = NULL;
		T = p;
	}
	else if (e < T->data)Insert(T->lc, e);
	else if (e > T->data)Insert(T->rc, e);
}

//中序遍历(非递归,但借助栈)
void InOrderTraverse2(tree* T) {
	if (!T)
		return;
	stack<tree*> s;
	tree* p = T;//p先指向根节点
	//实际上就是用栈模拟中序遍历的遍历过程
	while (!s.empty() || p)//只要栈不空或者p不指向空,就继续运行
	{
		//利用栈先进后出的特点实现中序遍历
		while (p)//只要p非空就运行
		{
			s.push(p);//把p塞入栈
			p = p->lc;//p指向其左子树
		}
		if (!s.empty())//如果栈非空
		{
			p = s.top();//读取栈顶
			s.pop();//弹出栈顶
			cout << p->data << ' ';//输出当前节点数据域
			p = p->rc;//p指向右节点
		}
	}
}

//层序遍历(有点不熟悉)
//用到队列,可以用queue,但其实用普通的数组模拟队列就行
void LeOrder(tree* T) {
	tree* q[1000];//树的指针的队列
	int f = 0, r = 0;
	if (T)//非空树 
		q[r++] = T;
	//实际上就相当于两个指针,一个指针访问并输出数据域,
	//另外一个趁机将第一个访问的该节点的左右指针域存到队列以便于下次访问
	while (f != r)
	{
		tree* temp = q[f++];//出队
		cout << temp->data << ' ';
		if (temp->lc)
			q[r++] = temp->lc;//入队 
		if (temp->rc)
			q[r++] = temp->rc;//入队 
	}
}

//小写的swap是提供的函数,大写的Swap是自定义函数
//交换左右子树(递归)
void Swap(tree*& T) {
	if (!T)return;
	swap(T->lc, T->rc);
	Swap(T->lc);
	Swap(T->rc);
}

//得二叉树的高度(递归)
int Getheight(tree* T) {
	if (!T)return 0;
	return max(Getheight(T->lc), Getheight(T->rc)) + 1;
	//每次递归返回上一层时都将该层最大值往上传递并且+1,利用max函数得出最大值就是整个二叉树的高度

}

//得出二叉树的叶子节点数
int Getnum(tree* T) {
	if (!T)return 0;//该指针为空则表示没节点,返回0
	if (!T->lc && !T->rc)return 1;//指针指向的节点左右指针域为空,则返回1
	return Getnum(T->lc) + Getnum(T->rc);
	//将本节点的左右子树统计出来的叶子节点数得到当前节点作为根这一子树的叶子节点数,并向上一层递归传递
}

int main()
{
	tree* T = NULL;
	int n, e;
	cin >> n;
	while (n--) {//创建有n个节点的二叉排序树
		cin >> e;
		Create(T, e);
	}
	{//前中后序遍历
		PreOrderTraverse(T); cout << endl;
		InOrderTraverse(T); cout << endl;
		PostOrderTraverse(T); cout << endl;
	}
	{
		cin >> e; Find(T, e); //找二叉排序树中是否存在该数据
		cin >> e; Find(T, e); //找二叉排序树中是否存在该数据
		cin >> e; Insert(T, e);//插入数据e到二叉排序树中
	}
	{//插入数据e后的前中后序遍历
		PreOrderTraverse(T); cout << endl;
		InOrderTraverse(T); cout << endl;
		PostOrderTraverse(T); cout << endl;
	}
	//中序遍历(非递归)
	InOrderTraverse2(T); cout << endl;
	//层序遍历
	LeOrder(T); cout << endl;
	//交换左右子树
	Swap(T);
	{//前中后序遍历+3
		PreOrderTraverse(T); cout << endl;
		InOrderTraverse(T); cout << endl;
		PostOrderTraverse(T); cout << endl;
	}
	//交换左右子树+2
	Swap(T);
	{//前中后序遍历+4
		PreOrderTraverse(T); cout << endl;
		InOrderTraverse(T); cout << endl;
		PostOrderTraverse(T); cout << endl;
	}
	//得到二叉树高度
	cout << Getheight(T) << endl;
	//得到叶子节点数
	cout << Getnum(T) << endl;
}
描述 用函数实现如下二叉排序树算法: (1) 插入新结点 (2) 前序、中序、后序遍历二叉树 (3) 中序遍历的非递归算法 (4) 层次遍历二叉树 (5) 在二叉树中查找给定关键字(函数返回值为成功1,失败0) (6) 交换各结点的左右子树 (7) 求二叉树的深度 (8) 叶子结点数 Input 第一行:准备建树的结点个数n 第二行:输入n个整数,用空格分隔 第三行:输入待查找的关键字 第四行:输入待查找的关键字 第五行:输入待插入的关键字 Output 第一行:二叉树的先序遍历序列 第二行:二叉树的中序遍历序列 第三行:二叉树的后序遍历序列 第四行:查找结果 第五行:查找结果 第六行~第八行:插入新结点后的二叉树的先、中、序遍历序列 第九行:插入新结点后的二叉树的中序遍历序列(非递归算法) 第十行:插入新结点后的二叉树的层次遍历序列 第十一行~第十三行:第一次交换各结点的左右子树后的先、中、后序遍历序列 第十四行~第十六行:第二次交换各结点的左右子树后的先、中、后序遍历序列 第十七行:二叉树的深度 第十八行:叶子结点数 Sample Input 7 40 20 60 18 50 56 90 18 35 30 Sample Output 40 20 18 60 50 56 90 18 20 40 50 56 60 90 18 20 56 50 90 60 40 1 0 40 20 18 30 60 50 56 90 18 20 30 40 50 56 60 90 18 30 20 56 50 90 60 40 18 20 30 40 50 56 60 90 40 20 60 18 30 50 90 56 40 60 90 50 56 20 30 18 90 60 56 50 40 30 20 18 90 56 50 60 30 18 20 40 40 20 18 30 60 50 56 90 18 20 30 40 50 56 60 90 18 30 20 56 50 90 60 40 4 4
实现平衡二叉树的各种算法(如AVL树、红黑树等)可以应用在SCAU(South China Agricultural University,华南农业大学)的数据结构算法课程中。这些算法的目标是确保二叉树的左右子树高度差不超过1,从而使树的高度保持相对较小的水平,提高插入、删除和查找等操作的效率。 一种常见的平衡二叉树算法是AVL树。实现AVL树的关键是通过旋转操作来保持树的平衡。在SCAU,可以使用多种编程语言(如C++、Java等)实现AVL树算法。插入新节点时,首先按照二叉查找树的方式找到合适的插入位置,然后通过不同的旋转操作调整树的平衡。具体的实现包括左旋、右旋、左右旋和右左旋等操作。 另一种常见的平衡二叉树算法是红黑树。SCAU可以使用编程语言(如C++、Java等)实现红黑树算法。红黑树通过使用辅助信息(即节点的颜色)来维持树的平衡。红黑树的插入操作包括节点的颜色变换和旋转操作。具体实现包括左旋、右旋、颜色变换等操作。 无论是AVL树还是红黑树,它们的实现都需要处理平衡调整,在插入或删除节点时通过旋转和颜色变换等操作来保持树的平衡。实现这些算法需要对平衡树的定义和性质有深入的理解,并具备编程技巧和数据结构基础。SCAU的学生在学习数据结构算法课程时,可以通过理论学习和实践编程来掌握实现平衡二叉树的各种算法。除了课程的学习,还可以通过参考相关的教材、博客、论文等来加深对平衡二叉树算法实现的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值