数据结构课设--6二叉排序树的基本操作

6、二叉排序树的基本操作(**)

任务: 编写算法实现对依次输入的关键字序列建立二叉排序树,并能实现二叉排序树的查找、插入和删除运算。

一、算法设计

1.建立二叉树的过程实际上就是一个一个结点的插入过程,将读入的第一个结点看作是根结点,第二个来时,与第一个结点进行比较,小的话作为左孩子,大的话作为右孩子。以此类推,第三个,第四个都是如此。查找过程也与此类似,从根结点开始,与所给的关键字数值进行比较,比根结点的值大,跑向右孩子,比根结点的数值小,跑向左孩子。一直比较,直到数值匹配符合,说明查找成功。若是当前结点左右孩子都为空,则证明这个数值并没有存入二叉排序树当中。插入运算的话,对于给定的数值,需要先进行一遍查找遍历,若当前数值已经存在就直接退出功能。否则,记录下最后一个查找的结点,即为需要插入的位置(当前结点的左孩子或者是右孩子)。删除运算需要分情况讨论,若是叶子结点,直接删除没有什么好说的,其他的都不变。若当前结点有单个孩子,不管是右孩子还是左孩子,此结点被删除之后,直接由孩子来替代。如果此结点有两个孩子,这里有两种方法可以用来处理。假设被删结点有右孩子还有左孩子,那么被删除之后,可以在其左子树上遍历,找到左子树上最大的数值结点来代替该节点。或者是右子树寻找数值最小的结点来代替。数值最大、数值最小的结点必为叶子节点。这样,整个二叉树的基本运算就结束了。在此基础上,可以通过树的中序遍历对该树进行打印,打印出来的数值肯定也是按照由小到大的顺序排列的。

各个函数之间的调用关系如下图所示:

main()

mainjiemian()

InsertBST()

PrintBST()

SearchBST()

PrintBST()

DeleteBST()

PrintBST()

jieshu()

mainjiemian()

2.本程序中包含7个模块

(1)主函数:int main();

(2)主菜单函数:void mainjiemian();

(3)退出函数:void jieshu();

(4)中序遍历二叉树并进行打印:void PrintBST(BiTree T);

(5)删除结点:int DeleteBST(BiTree T, datatype value);

(6)插入节点:BiTNode * InsertBST(BiTNode *T, int kx);

(7)查找结点:int SearchBST(BiTNode *T, datatype kx);

3.元素类型、结点类型和指针类型

typedefstruct BiTNode

{

   datatype key = -1;/*关键字*/

   struct BiTNode *lchild = NULL, *rchild =NULL;/*左、右子树*/

}BiTNode,*BiTree;/*二叉排序树的结点与指向根节点的指针*/

二、实验测试



源代码:

#pragma warning(disable:4996)
#include<stdio.h>
#include<cstdio>
#include<string>
#include<string.h>
#include<vector>
#include<algorithm>
#include<queue>
#include<stack>
#include<math.h>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<list>
using namespace std;
typedef int datatype;
typedef struct BiTNode
{
	datatype key = -1;                                     /*关键字*/
	struct BiTNode *lchild = NULL, *rchild = NULL;         /*左、右子树*/
}BiTNode, *BiTree;                                         /*二叉排序树的结点与指向根节点的指针*/
int SearchBST(BiTNode *T, datatype kx)/*查找*/
{
	BiTNode *p;
	p = T;
	if (p == NULL)
	{
		return 0;
	}
	if (p->key == kx)
		return 1;
	else if (p->key > kx)
		return SearchBST(p->lchild, kx);
	else
		return SearchBST(p->rchild, kx);
}
BiTNode * InsertBST(BiTNode *T, int kx)/*插入*/
{
	BiTNode *parent, *node, *child;
	/*树为空,创建根结点*/
	if (T == NULL)
	{
		T = (BiTNode *)malloc(sizeof(BiTNode));
		T->key = kx;
		T->lchild = NULL;
		T->rchild = NULL;
		return T;
	}
	parent = T;/*记录下根结点的位置*/
	node = T;
	while (node != NULL)
	{
		/*待插数据存在,就返回*/
		if (node->key == kx)
		{
			cout << "数据已经存在" << endl;
			return T;
		}
		else
		{
			parent = node;
			if (node->key < kx)
				node = node->rchild;
			else
				node = node->lchild;
		}
	}
	child = (BiTNode*)malloc(sizeof(BiTNode));
	child->key = kx;
	child->lchild = NULL;
	child->rchild = NULL;
	if (kx > parent->key)
		parent->rchild = child;
	else
		parent->lchild = child;
	return T;
}
int DeleteBST(BiTree T, datatype value)/*删除*/
{
	BiTNode *p, *pre = NULL, *mid;
	p = T;
	if (T == NULL)
		return 0;
	/*找到该节点*/
	while ((p != NULL) && (p->key != value))
	{
		pre = p;
		if (p->key < value)
		{
			p = p->rchild;
		}
		else
			p = p->lchild;
	}
	if (p == NULL)
		return 0;
	/*至少有一个子节点为空*/
	if ((p->lchild == NULL) || (p->rchild == NULL))
	{
		if (pre->lchild == p)
		{
			pre->lchild = ((p->lchild == NULL) ? p->rchild : p->lchild);
		}
		else
			pre->rchild = ((p->lchild == NULL) ? p->rchild : p->lchild);
		free(p);    /*释放节点*/
	}
	else
	{
		/*删除的节点有2个子女*/
		mid = p->rchild;
		pre = p;
		/*寻找右子树上的最小值的结点*/
		while (mid->lchild != NULL)
		{
			pre = mid;
			mid = mid->lchild;
		}
		/*直接赋值,避免交换节点*/
		p->key = mid->key;
		/*将mid节点的子节点作为pre的子节点,并将mid所指向的节点删除*/
		if (pre->rchild == mid)
			pre->rchild = mid->rchild;
		else
			pre->lchild = mid->rchild;
		free(mid);
	}
	return 1;
}
void PrintBST(BiTree T)/*中序遍历输出*/
{
	if (T == NULL)
		return;
	PrintBST(T->lchild);
	printf("%d ", T->key);
	PrintBST(T->rchild);
}
void mainjiemian()
{
	cout << "                   ★-----★---------★---------★-----★" << endl;
	cout << endl;
	cout << "                   ☆          1   生成二叉排序树      ☆" << endl;
	cout << "                               2   查找数据              " << endl;
	cout << "                   ☆          3   删除数据            ☆" << endl;
	cout << "                               4   退出                  " << endl;
	cout << "                   ★-----★---------★---------★-----★" << endl;
	cout << endl;
	cout << endl;
	cout << "请选择数字命令:";
}
void jieshu()//结束显示
{
	cout << "                   ★-----★---------★---------★-----★" << endl;
	cout << endl;
	cout << "                   ☆           感谢您的使用!         ☆" << endl;
	cout << endl;
	cout << "                   ★-----★---------★---------★-----★" << endl;
	cout << endl;
}
int main()
{
	system("color 57");
	char*end;/*末端指针*/
	string order;
	mainjiemian();
	int t;
	BiTNode *T = NULL;
	while (cin >> order)
	{
		int a_order = static_cast<int>(strtol(order.c_str(), &end, 10));/*将输入进来的值转化为int类型*/
		switch (a_order + 48)
		{
		case'1':
		{
				   system("cls");
				   printf("请输入要排序的数据:(以输入-1作为结束标志)
");
				   while (scanf("%d", &t) != EOF)
				   {
					   if (t != -1)
					   {
						   T = InsertBST(T, t);
					   }
					   else
						   break;
				   }
				   PrintBST(T);
				   cout << endl;
				   system("pause");
				   system("cls");
				   mainjiemian();
				   break;
		}
		case'2':
		{
				   system("cls");
				   printf("请输入需要查找的数据:
");
				   cin >> t;
				   if (SearchBST(T, t))
				   {
					   cout << "查找成功!" << endl;
				   }
				   else
				   {
					   cout << "查找失败!" << endl;
				   }
				   PrintBST(T);
				   cout << endl;
				   system("pause");
				   system("cls");
				   mainjiemian();
				   break;
		}
		case'3':
		{
				   system("cls");
				   printf("请输入要删除的数据:
");
				   cin >> t;
				   if (DeleteBST(T, t))
				   {
					   cout << "删除成功!" << endl;
				   }
				   else
				   {
					   cout << "数据不存在,删除失败!" << endl;
				   }
				   PrintBST(T);
				   cout << endl;
				   system("pause");
				   system("cls");
				   mainjiemian();
				   break;
		}
		case'4':
		{
				   system("cls");
				   jieshu();
				   return 0;
				   break;
		}
		default:
		{
				   cin.clear();
				   cin.sync();
				   cout << "输入错误,重新返回主界面。" << endl;
				   system("pause");
				   system("cls");
				   mainjiemian();
				   break;
		}
		}
	}
	cout << endl;
	
	
	//printf("
%d %s
", T->key, SearchBST(T, 10) ? "yes" : "no");
	return 0;
}


原文地址:https://www.cnblogs.com/lemonbiscuit/p/7776124.html