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

源代码如下:

#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 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));
}

//右旋转 顺时针旋转 
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;
}

//随机化插入程序 
link insertR(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(rand() < RAND_MAX / (h->N+1))
		return  insertR(h,item);  //使得新节点出现在树根的概率是1/(N+1) 
	if(v<t) {h->l = insertR(h->l,item); h = rotR(h); }
	else {h->r = insertR(h->r,item); h = rotL(h);}
	(h->N)++;return h;
}

//伸展插入
link splay(link h, Item item) {
	char v = item.c, t = h->item.c;
	if(h==z)return NEW(item,z,z,1);
	if(v<t){
		if(hl==z)return NEW(item,z,h,h->N+1);
		if(v<hl->item.c){
			hll=splay(hll,item); h = rotR(h);
		}else{
			hlr = splay(hlr,item); hl = rotL(hl);
		}
		return rotR(h);
	}
	else {
		if(hr==z)return NEW(item,h,z,h->N+1);
		if(v>hr->item.c){
			hrr=splay(hrr,item); h = rotL(h);
		}else{
			hrl = splay(hrl,item); hr = rotR(hr);
		}
		return rotL(h);
	}
}



//BST插入主程序 
void STinsert(Item item){  //新插入的节点都会当作根节点 
	head =  splay(head,item);
}

void sortR(link h){
	if(h==z)return;
	printf("%c ",h->item.c);	
	sortR(h->l);
	sortR(h->r);
}
//二叉搜索树排序 
void STsort(link h){
	sortR(h);
}

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);
}


main(){
	test();
} 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值