zoukankan      html  css  js  c++  java
  • 数据结构课设--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;
    }


  • 相关阅读:
    Shell笔记——文本操作
    Shell笔记——加密命令
    conda,pip 安装指定版本的指定包
    如何检查tensorflow环境是否能正常调用GPU
    Windows10中使用Anaconda安装keras-gpu版本(遇到的坑)
    canvas一些属性
    块级元素,行内元素,行内块级元素都有哪些
    面向对象版Tab栏切换
    注册事件的兼容性处理
    常见的移动端问题
  • 原文地址:https://www.cnblogs.com/lemonbiscuit/p/7776124.html
Copyright © 2011-2022 走看看