二叉排序树(BST):创建、查找、插入与删除

删除结点的相关操作(左右子树均为非空的删除结点的方法):

算法分析:

下面以实例来说明二叉排序树的创建、查找、插入和删除等相关操作;

如输入关键字序列(45,24,37,12,54,93),然后对其进行相应的操作,程序如下:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct BiTNode
{
	int value;
	struct BiTNode *lchild,*rchild;
}*BiTree;

bool LT(int a,int b)  //LessThan小于
{
	if(a<b)
		return true;
	else
		return false;
}
/*
在根指针root所指向的二叉排序树中递归地查找其关键字等于data的数据元素,若查找成功,则指针p指向该数据元素结点,并返回true,
否则指针p指向查找路径上访问的最后一个结点并返回false指针,指针f指向root的双亲,其初始调用值NULL
*/
bool SearchBST(BiTree root,int data,BiTree f,BiTree &p)
{
	if(!root)
	{
		p=f;
		return false;
	}
	else if(data == root->value)   //查找成功
	{
		p=root;
		return true;
	}
	else if(data < root->value)  //在左子树继续查找
		return SearchBST(root->lchild,data,root,p);
	else if(data > root->value)  //在右子树继续查找
		return SearchBST(root->rchild,data,root,p);
}

//当二叉排序树root中不存在关键字等于data的数据元素时,插入data
inline void InsertBST(BiTree &root,int data)     //root为传引用指针
{
	BiTree p,s;
	if(!SearchBST(root,data,NULL,p))    //查找不成功
	{
		s=(struct BiTNode *)malloc(sizeof(BiTNode));
		s->value=data;
		s->lchild=s->rchild=NULL;
		if(p==NULL)    //二叉排序树为空的时候,被插入结点*s为新的根结点
			root=s;
		else if(LT(data,p->value))           //被插结点*s为左孩子
			p->lchild=s;
		else           //被插结点*s为右孩子
			p->rchild=s;
	}
	return ;
}
void PreOrderTraverse(BiTree root)    //先序遍历
{
	if(root)
	{
		printf("%d ",root->value);
		PreOrderTraverse(root->lchild);
		PreOrderTraverse(root->rchild);
	}
}
void InOrderTraverse(BiTree root)    //中序遍历
{
	if(root)
	{
		InOrderTraverse(root->lchild);
		printf("%d ",root->value);
		InOrderTraverse(root->rchild);
	}
}
void PostOrderTraverse(BiTree root)    //后序遍历
{
	if(root)
	{
		PostOrderTraverse(root->lchild);
		PostOrderTraverse(root->rchild);
		printf("%d ",root->value);
	}
}
int Delete(BiTree &p){
	BiTree q,s;
    if(!p->rchild){ //右子树空的话只需重接它的左
	   q = p; p = p->lchild; free(q);
	}
	else if (!p->lchild){   //左子树为空的话,只需重接它的右子树
	   q = p; p = p->rchild; free(q);
	}
    else{  //左右子树均不为空
	   q = p;  s = p->lchild;
	   while(s->rchild) {   //转左。然后向右走到尽头
	    q = s; s = s->rchild;
	   }
	   p->value = s->value;  //s指向被删除结点的前驱
	   if(q != p) {q->rchild = s->lchild;} //重接*q的右子树
	   else {q->lchild = s->lchild;} //重接*q的左子树
		delete s;
	}
	return true;
}
int DeleteBST(BiTree &T,int key)
{
	 if(!T) return false;
	 else{
	   if(key == T->value) return Delete(T);  //找到关键字为key的数据元素
	   else if(key < T->value) return DeleteBST(T->lchild,key);//关键字小于结点的话,即在左子树
	   else return DeleteBST(T->rchild,key); //关键字大于结点的话,即在右子树
	 }
}

int main(void)
{
	int i,a[101],n,data,findkey,menu,insertkey;
	BiTree root,pp;
	printf("二叉排序树的操作:\n");
    printf("                1:创建二叉排序树!\n");
    printf("                2:查找关键字!\n");
    printf("                3:插入关键字!\n");
	printf("                4:删除关键字!\n");
	printf("                0:退出!\n");
	//输入结点的个数
	printf("请输入相应操作:");
	scanf("%d",&menu);
	while(!(menu>=0 && menu <= 4)){
	  printf("您的输入有问题,请重新输入:");
	  scanf("%d",&menu);
	}
	while(menu != 0){/////////////////////////////////////
		switch(menu){ ///////////////////////
		case 1:{ ///////////////////
	            printf("输入初始化结点的个数:");
                scanf("%d",&n);
				root=NULL;
				printf("输入各个结点的值:");
				for(i=1;i<=n;i++)
				{
					scanf("%d",&a[i]);
					InsertBST(root,a[i]);
				}
                printf("输出先序遍历结果:");
				PreOrderTraverse(root);
				printf("\n");
				printf("输出中序遍历结果:");
				InOrderTraverse(root);
				printf("\n");
				printf("输出后序遍历结果:");
				PostOrderTraverse(root);
				printf("\n");
				break;
			 }//////////////////////////////case
		case 2:{
			    printf("输入你要查找的关键字:");
				scanf("%d",&findkey);
				if(SearchBST(root,findkey,NULL,pp)){
				printf("查找成功!\n");
				}else{
				printf("查找失败!\n");
				}
				break;
			   }
        case 3:{
			    printf("请输入你插入的关键字:");
				scanf("%d",&insertkey);
				InsertBST(root,insertkey);
              	printf("\n");
				printf("输出中序遍历结果:");
				InOrderTraverse(root);
				printf("\n");
			    break;
			   }
		case 4:{
			    printf("输入你想删除的关键字:");
				scanf("%d",&data);
				DeleteBST(root,data);
				printf("\n");
				printf("输出中序遍历结果:");
				InOrderTraverse(root);
				printf("\n");
				break;
			   }
		   /*
			while(scanf("%d",&n)!=EOF)
			{
				root=NULL;
     			printf("输入各个结点的值:");
				for(i=1;i<=n;i++)
				{
					scanf("%d",&a[i]);
					InsertBST(root,a[i]);
				}
				printf("输出先序遍历结果:");
				PreOrderTraverse(root);
				printf("\n");
				printf("输出中序遍历结果:");
				InOrderTraverse(root);
				printf("\n");
				printf("输出后序遍历结果:");
				PostOrderTraverse(root);
				printf("\n");
				printf("输入你要查找的关键字:");
				scanf("%d",&findkey);
				if(SearchBST(root,findkey,NULL,pp)){
				printf("查找成功!\n");
				}else{
				printf("查找失败!\n");
				}

				printf("输入你想删除的关键字:");
				scanf("%d",&data);
				DeleteBST(root,data);
				printf("\n");
				printf("输出中序遍历结果:");
				InOrderTraverse(root);

			}*/
		} //////switch
	 printf("请继续输入相应操作:");
    	scanf("%d",&menu);
	}//while
	return 0;
}

操作结果如下:

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-01 10:45:08

二叉排序树(BST):创建、查找、插入与删除的相关文章

二叉查找树(二叉排序树)创建,插入,删除操作。

二叉排序树 二叉排序树是一个基础的树的数据结构.应用非常多. 它的特性就是,左孩子小于parent,右孩子大于parent. 寻找节点 寻找节点就是直接根据数值的大小,从root节点开始遍历,大于当前遍历节点就向它的右子树查找,相反则查找它的左子树.然后返回. 查找最大最小节点 直接根据root节点,遍历到最右就是最大节点,遍历到最左,就是最小节点. 插入节点 插入节点我这里插入的节点都会成为叶子节点.根据大小的关系向下遍历,遍历到最后的节点,然后插入就可以了. 删除节点 这里删除节点是相对麻烦

c语言 双向链表的简单操作-创建、插入、删除

数据结构-双向链表的创建.插入和删除 双向链表是数据结构中重要的结构,也是线性结构中常用的数据结构,双向指针,方便用户从首结点开始沿指针链向后依次遍历每一个结点,结点的前驱和后继查找方便. #include <stdio.h> #include <stdlib.h> //双向链表结点的定义 typedef struct dbnode { int data; struct dbnode *prio, *next; }DbNode, linkdblist; //创建双向链表 DbNod

【JS学习笔记】DOM操作应用-创建、插入和删除元素;文档碎片

一.创建.插入和删除元素 (1)创建DOM元素 createElement(标签名) 创建一个节点 appendChild(节点) 追加一个节点 例子:为ul插入li <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="htt

创建,插入,删除一个document(createing,indexing and deleteing a document)

创建,插入,删除的请求都是写操作,在把primary shard复制到相对应的replica shard之前,这些操作必须是成功的.如图: 下面将会有序列出使用crate,index,delete在primary shard和replica shard上成功操作document的必要步骤,正如上图所示一样. 1:客户端发送create,index,delete请求到node1,于是把请求转发到node3 2:node1使用document的_id判断得知这个document是在shar0上,这里

链表(创建,插入,删除和打印输出(转载)

链表(创建,插入,删除和打印输出 /*----------------------------------------------------------------------------- 文件功能:实现了动态建立一个学生信息的链表包括链表的创建.插入.删除.和打印输出学生信息包括姓名和分数本链表是带有头结点的,头结点的内容为空内容-----------------------------------------------------------------------------*//*

二叉排序树的创建,遍历和删除

Binary Sort/Search Tree 为什么会有它 数组 未排序:直接在队尾添加,速度快:查找速度慢. 排序:二分查找,查找速度快:添加新数据,需要找到插入位置移动后面的数组,速度慢 链表 添加快,查找慢: 简介 BST: (Binary Sort(Search) Tree), 对于二叉排序树的任何一个非叶子节点,要求左子节点的值比当前节点的值小,右子节点的值比当前节点的值大. 特别说明:如果有相同的值,可以将该节点放在左子节点或右子节点 比如针对前面的数据 (7,3, 10, 12,

链表的创建,插入,删除,输出基本操作

#include<stdio.h>#include<cstdlib> struct student  //定义一个学生结点,结点包括值域和指针域{ int num;//学号 char name[20];//姓名 char address[20];//地址 struct student *next;//定义结点的指针域,指向下一个结点};typedef struct student LIST;LIST *CreateList();LIST *InsertNode(LIST *h,LI

DS二叉排序树之创建和插入

题目描述 给出一个数据序列,建立二叉排序树,并实现插入功能 对二叉排序树进行中序遍历,可以得到有序的数据序列 输入 第一行输入t,表示有t个数据序列 第二行输入n,表示首个序列包含n个数据 第三行输入n个数据,都是自然数且互不相同,数据之间用空格隔开 第四行输入m,表示要插入m个数据 从第五行起,输入m行,每行一个要插入的数据,都是自然数且和前面的数据不等 以此类推输入下一个示例 输出 第一行输出有序的数据序列,对二叉排序树进行中序遍历可以得到 从第二行起,输出插入第m个数据后的有序序列,输出m

javasript 的DOM 节点操作:创建,插入,删除,复制以及查找节点

DOM 含义: DOM 是文档对象模型(Document Object Model) 是一种基于浏览器编程的一套API 接口,我W3C 出台推荐的标准.其赋予了JS 操作节点的能力,当网页被加载时,浏览器就会创建页面的文档对象模型. 节点: 根据W3C的HTML DOM 标准,HTML 文档中的所有内容都是节点. 1. 整个文档是一个文档节点 2. 每个HTML元素是元素节点 3. HTML元素内的文本是文本节点 4.每个HTML属性都是属性节点 5.每个注释都是注释节点 所以HTML DOM

js DOM节点的创建、插入、删除、查找、替换例子

五.动态创建标记 (1)传统的技术: a)Document.write:可以方便快捷的把字符串插入到文档里.如图(3) 而这种方法的缺点是,行为与表现分开,有点类似于使用<font>标签去设定字体和颜色,工作起来不够优雅.尽量少用. b)innerHTML:几乎所有浏览器都支持,可以用来读取,或者设置给定的元素里的HTML内容.把一大段HTML内容插入到网页时,innerHTML很适合,但是innerHTML属性不会返回任何刚插入内容的引用.如果想对刚插入的内容进行处理,则需要使用DOM提供的