【模板】Splay二叉树排序

题目描述

排序(二叉树排序)

输入输出格式

输入格式:

n个数,和一个无序序列。

输出格式:

输出一行n个数字,表示原始序列排序后的结果

输入输出样例

输入样例#1:
5 3 5 2 1 4
输出样例#1:
1 2 3 4 5




说明

N,M<=100000



#include <iostream>
#include <cstdio>
using namespace std;
struct splay_tree{
	int val,lef,rig,p;
}a[1000000];

int n,x,root=0,size=1;


void left_rotate(int x){
	int y=a[x].p;a[x].p=a[y].p;
	if (a[x].p==0) root=x;
	if (y==a[a[y].p].lef) a[a[y].p].lef=x;
	   				 else a[a[y].p].rig=x;
	a[y].rig=a[x].lef;a[a[x].lef].p=y;
	a[y].p=x;a[x].lef=y;
}


void right_rotate(int x){
	int y=a[x].p;a[x].p=a[y].p;
	if (a[x].p==0) root=x;
	if (y==a[a[y].p].lef) a[a[y].p].lef=x;
	   				 else a[a[y].p].rig=x;
	a[y].lef=a[x].rig;a[a[x].rig].p=y;
	a[y].p=x;a[x].rig=y;
}


void splay(int x){
	while (x!=root) {
		int y=a[x].p;
		if (y==root&&x==a[y].lef){
			right_rotate(x);break;}else
		if (y==root&&x==a[y].rig){
			left_rotate(x);break;}
		else{
			if (y==a[a[y].p].lef){
			    if (x==a[y].rig) {
					left_rotate(x);right_rotate(x);}
				if (x==a[y].lef) {
					right_rotate(y);right_rotate(x);}
			}else
			if (y==a[a[y].p].rig){
			    if (x==a[y].lef) {
			    	right_rotate(x);left_rotate(x);}
				if (x==a[y].rig) {
					left_rotate(y);left_rotate(x);}
			}				
		}
	}
}


void st_insert(int va){
	int p=root,last=p;
	if (p==0){
		root=1;a[1].val=va;return ;
	}
	while (a[p].val!=0){
		last=p;
		if (a[p].val>va) p=a[p].lef;
		         else    p=a[p].rig;
	}
	++size;a[size].val=va;a[size].p=last;
	if (a[last].val>va) a[last].lef=size;
	              else  a[last].rig=size; 
	splay(size);
}


void dfs(int x){
	if (x==0) return ;
	dfs(a[x].lef);
	cout <<a[x].val<<' ';
	dfs(a[x].rig);
}


int main(){
	scanf("%d",&n);int flag;
	
	for (int i=1;i<=n;++i){
		scanf("%d",&x);st_insert(x);
	}

	dfs(root);

	return 0;	
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值