二叉搜索树的根插入、选择、删除、合并、排序等操作的实现

源代码如下:

这里的Key 不当为关键字对待, 而是把Item.c作为关键字对待

#include <stdlib.h>
#include <stdio.h>
//#define Key int
typedef int Key;
struct Item{
	Key key;
	char c;
};
typedef struct STnode* link;
struct STnode{
	Item item ; link l,r; int N;
};

static link head , z ;
static struct Item NULLitem ;

Key key(Item item){
	return item.key;
}
//创建一个节点
link NEW(Item item, link l,link r, int N){
	link x = (link)malloc(sizeof *x);
	x->item = item;x->l = l;x->r = r;x->N = N;
	if(head==z)head=x; //这句话不能少!!!
	return x;
}
//初始化
void STinit(){
	head = ( z = NEW(NULLitem,0,0,0));
}
//节点个数
int STcount(){
	return head->N;
}
//搜索子程序
Item searchR(link h, char v){
	char  t = h->item.c;
	if(h==z)return NULLitem;
	if(v==t) return h->item;
	if(v<t) return searchR(h->l,v);
	else return searchR(h->r,v);
}
//搜索主程序
Item STsearch(Key v){
	return searchR(head,v);
}

//选择第K小关键值的项 K从0开始
Item selectR(link h, int k) {
	int t;
	if(h==z)return NULLitem;
	t = (h->l==z)?0:h->l->N;
	if(t>k) return selectR(h->l,k);
	if(t<k) return selectR(h->r,k-t-1);
	return h->item;
}

Item STselect(int k){
	return selectR(head,k);
}

//----------------根插入--------------------//
//右旋转 顺时针旋转
link rotR(link h){
	link x = h->l; h->l = x->r; x->r=h;
}
//左旋转 逆时针旋转
link rotL(link h){
	link x = h->r; h->r = x->l; x->l=h;
}

//插入子程序
link insertT(link h, Item item){
//	Key v = key(item), t = key(h->item);
	char v = item.c, t = h->item.c;
	if(h==z)return NEW(item,z,z,1);
	if(v<t) {h->l = insertT(h->l,item); h = rotR(h); }
	else {h->r = insertT(h->r,item); h = rotL(h);}
	(h->N)++;return h;
}
//BST根插入主程序
void STinsert(Item item){  //新插入的节点都会当作根节点
	head =  insertT(head,item);
}

//----------------根插入--------------------// 

//----------------删除一个节点----方法1-----乾坤大挪移-----------// 

link partR(link h, int k) {
	int t = h->l->N;  //为什么没有判断非空?
	if(t>k){h->l = partR(h->l,k);h=rotR(h);}
	if(t<k){h->r = partR(h->r,k-t-1);h=rotL(h);}
	return h;
}
link joinLR(link a ,link b){
	if(b==z)return a;
	b=partR(b,0);
	b->l = a;
	return b;
}

link delR(link h, char k){
	link x; char t = h->item.c;

	if(h==z)return z;
	if(t>k)h->l=delR(h->l,k);
	if(t<k)h->r=delR(h->r,k);
	if(t==k){
		x = h;h=joinLR(h->l,h->r);free(x);
	}
	return h;
}
//删除主程序
void STdelete(char v){
	 head = delR(head,v);
}
//----------------删除一个节点-----方法1-----乾坤大挪移----------// 

//----------------删除一个节点-----方法2---------------//
//删除子程序
Item deleteR(link F){
	Item tmp; link p;
	if(F->l==NULL){
		p = F;
		tmp = F->item;
		F = F->r;
		free(p);
		return tmp;
	}else return deleteR(F->l);
}
//删除子程序
void deleteRR(link h , Key v){

	if(h!=NULL){
		Key t = key(h->item);
		if(v<t) deleteRR(h->l,v);
		else if(v>t) deleteRR(h->r,v);
		else
			if(h->l==NULL) { //处理只有一颗子树或没有子树的情况  1
				link p = h->r; h=p; free(p);
			}
			else if(h->r==NULL){ //处理只有一颗子树或没有子树的情况  2
				link p = h->l; h=p; free(p);
			}
			else h->item= deleteR(h->r); //如果待删除的节点既有左子树又有右子树
										//则用该节点右子树的最左下节点替换之,维持二叉搜索树
	}
}
//删除主程序
void STdelete2(Key v){
	 deleteRR(head,v);
}
//----------------删除一个节点-----方法2---------------// 

void sortR(link h){
	if(h==z)return;
	sortR(h->l);
	if(h->item.key!=0)
		printf("%c ",h->item.c);
	sortR(h->r);
}
//二叉搜索树排序
void STsort(link h){
	sortR(h);
}
//接连两颗二叉搜索树
link STjoin(link a ,link b){
	if(b==z)return a;
	if(a==z)return b;
	b = insertT(b,a->item);
	b->l = STjoin(a->l,b->l);
	b->r=STjoin(a->r,b->r);
	free(a);
	return b;
}

void test(){
	struct Item item1 = {322,'a'};
	struct Item item2 = {23,'s'};
	struct Item item3 = {2,'e'};
	struct Item item4 = {332,'r'};
	struct Item item5 = {332,'c'};
	struct Item item6 = {332,'h'};
	struct Item item7 = {112,'i'};
	STinit();
	STinsert(item1);STinsert(item2);
	STinsert(item3);STinsert(item4);
	STinsert(item5);STinsert(item6);
	STinsert(item7);
	STsort(head);
	printf("\n");
	struct Item item11 = STselect(2);
	printf("%c\n",item11.c);
	STdelete('i');
	STsort(head);

}

main(){
	test();
}

运行结果

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

时间: 2024-08-27 05:44:08

二叉搜索树的根插入、选择、删除、合并、排序等操作的实现的相关文章

二叉搜索树建立、插入、删除、前继节点、后继节点之c++实现

一.前言 一直以来,都对树有关的东西望而却步.以前每次说要看一看,都因为惰性,时间就那么荒废掉了.今天下个决心,决定好好的数据结构中的东西看一下.不知道看这篇文章的你,是不是和我有同样的感受,空有一颗努力的心,却迟迟没有付出行动.如果是的话,如果也想好好的把树的知识巩固一下的话,就让我们一起好好儿地把知识点过一遍吧.本文争取让看完的每一个没有基础的同学,都能有所收获.在正文开始前,先给自己加个油.加油(^ω^) 二.二叉搜索树的定义 二叉搜索树是指,对于某一个节点而言,它左边的节点都小于或等于它

二叉搜索树的随机化插入和伸展插入操作(平摊法)

源码例如以下: #include <stdlib.h> #include <stdio.h> //#define Key int #define hl h->l #define hr h->r #define hlr h->l->r #define hll h->l->l #define hrr h->r->r #define hrl h->r->l typedef int Key; struct Item{ Key ke

漫谈二叉搜索树的基本算法(三种思路实现查询操作)

  前面我们说了二叉树前序中序后序遍历的递归非递归算法的实现,下面我们再来说说二叉搜索树~   二叉排序树分为静态查找(find)和动态查找(insert.delete) 二叉搜索树:一棵二叉树,可以为空:如果不为空,满足下列性质: 1.非空左子树的所有键值小于其根结点的键值. 2.非空右子树的所有键值大于其根结点的键值 3.左右子树都是二叉搜索树!! 2.以上是二叉搜索树(也叫二叉排序树)的一些基本操作,此处我们先说一下二叉树的结点定义·· 代码中判断当前结点位置情况的辅助方法以及简单的 ge

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的&#160;key&#160;对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用

一般来说,删除节点可分为两个步骤: 首先找到需要删除的节点: 如果找到了,删除它. 说明: 要求算法时间复杂度为 O(h),h 为树的高度. 示例: root = [5,3,6,2,4,null,7] key = 3 5 / 3 6 / \ 2 4 7 给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它. 一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示. 5 / 4 6 / 2 7 另一个正确答案是 [5,2,6,null,4,null,7]. 5

二叉搜索树的插入

--------------------siwuxie095 二叉树的插入 程序: BST.h: #ifndef BST_H #define BST_H #include "stdlib.h" #include <queue> //二叉搜索树 template <typename Key, typename Value> class BST { private: struct Node { Key key; Value value; Node *left; No

二叉搜索树的删除

-------------------siwuxie095 二叉搜索树的删除 程序: BST.h: #ifndef BST_H #define BST_H #include "stdlib.h" #include <queue> //二叉搜索树 template <typename Key, typename Value> class BST { private: struct Node { Key key; Value value; Node *left; N

Leetcode 450.删除二叉搜索树的节点

删除二叉搜索树的节点 给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变.返回二叉搜索树(有可能被更新)的根节点的引用. 一般来说,删除节点可分为两个步骤: 首先找到需要删除的节点: 如果找到了,删除它. 说明: 要求算法时间复杂度为 O(h),h 为树的高度. 示例: root = [5,3,6,2,4,null,7] key = 3 给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它. 一个正确的答案

数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树

在上一篇数据结构的博文<数据结构(三):非线性逻辑结构-二叉树>中已经对二叉树的概念.遍历等基本的概念和操作进行了介绍.本篇博文主要介绍几个特殊的二叉树,堆.哈夫曼树.二叉搜索树.平衡二叉搜索树.红黑树.线索二叉树,它们在解决实际问题中有着非常重要的应用.本文主要从概念和一些基本操作上进行分类和总结. 一.概念总揽 (1) 堆 堆(heap order)是一种特殊的表,如果将它看做是一颗完全二叉树的层次序列,那么它具有如下的性质:每个节点的值都不大于其孩子的值,或每个节点的值都不小于其孩子的值

【数据结构05】红-黑树基础----二叉搜索树(Binary Search Tree)

目录 1.二分法引言 2.二叉搜索树定义 3.二叉搜索树的CRUD 4.二叉搜索树的两种极端情况 5.二叉搜索树总结 前言 在[算法04]树与二叉树中,已经介绍过了关于树的一些基本概念以及二叉树的前中后序遍历,而这篇文章将是在二叉树的基础上来展开讲解的二叉搜索树,也就是说二叉搜索树建立在树的基础之上.至于博主为何要花一整篇文章来讲这个二叉搜索树呢?原因很简单,红-黑树是基于二叉搜索树的,如果对二叉搜索树不了解,那还谈何红-黑树?红-黑树的重要性我想各位没吃过佩奇肉也肯定看过宜春跑....是的,j

二叉搜索树的局限性

-------------------siwuxie095 二叉搜索树的局限性 二叉搜索树在时间性能上是具有局限性的 同样的数据,可以对应不同的二叉搜索树,如下: 二叉搜索树可能退化成链表,相应的,二叉搜索树的查找操作是和这棵树 的高度相关的,而此时这颗树的高度就是这颗树的节点数 n,同时二叉搜 索树相应的算法全部退化成 O(n) 级别 显然,说二叉搜索树的查找.插入.删除 这三个操作都是 O(lgn) 级别的, 只是一个大概的估算,具体要和二叉搜索树的形状相关 二叉搜索树并不能像堆那样,保证所