非指针 BST 练手

本代码基于POJ 2823  来实现,基本上该有的都有了。实际BST做这题会超时。

(好吧是我逗比的想用BST去写,然后tle又不想把代码删掉只能扔这里了)

题目大意就不说了,BST写起来就是建一棵大小为K的树,然后不停找最大最小值,然后删掉一个点,加入一个点。

然后直接扔代码,要说的都在代码里

#include<stdio.h>
#include<string.h>
#include<string>
#include<iostream>
#include<time.h>

using namespace std;

const int N=1000000+100;

struct node{   
	int r ,l ,fa;//左右子节点,父亲节点 
	int key;//点的值 
	int temp;//用来标记有几个这样的值&&temp=0表示这个点不存在; 
};

node tree[N];
int s[N];
int minn[N];
int mann[N];
int root =1,n,tot;

void BST(int k,int  x) 
{
  if(tree[k].temp==0)
  {
  	tree[k].key=x;
  	tree[k].temp=1;
  	return ;
  } 
 else if(x==tree[k].key)
  {
  	tree[k].temp++;
  	return ;
  }
  else if((x>tree[k].key)&&(tree[tree[k].r].temp==0))//一开始默认所有tree的左右节点都指向0,0节点的temp一直等于0;来表示左右节点不存在。 
  {                                                   //然后用tot覆盖 0来表示子节点的指向。 
  	tot++;
  	tree[k].r=tot;                                   //其他没什么好说的。 
  	tree[tot].temp=1;
  	tree[tot].key=x;
  	tree[tot].fa=k;
  	return ;
  }
  
  else if((x<tree[k].key)&&(tree[tree[k].l].temp==0))
  {
  	tot++;
  	tree[k].l=tot;
  	tree[tot].temp=1;
  	tree[tot].key=x;
  	tree[tot].fa=k;
  	return ;
  }
   if(x<tree[k].key) BST(tree[k].l, x);
  else BST(tree[k].r,x);
  return;
}

int searchmin(int k)
{
	if(tree[k].l == 0)return tree[k].key;
	return searchmin(tree[k].l);
}

int searchmax(int k)
{
	if(tree[k].r== 0 )return tree[k].key;
	return searchmax(tree[k].r);
}


void del(int k ,int x)//删除操作 
{
	if(tree[k].temp==0)return ;
	 else if(x>tree[k].key)del(tree[k].r,x);
	else if(x<tree[k].key)del(tree[k].l,x);
	else if(tree[k].temp>1)
	{
		tree[k].temp--;
		return;
	}
	
	else if(tree[k].r == 0&& tree[k].l == 0)
	{
		tree[k].temp=0;
		int fa = tree[k].fa;
		if(x<tree[fa].key)tree[fa].l=0;
		else tree[fa].r=0;
		tree[k].key=0;
		return ;
	}
	else if((tree[k].r==0&&tree[k].l != 0)||(tree[k].r!=0&&tree[k].l == 0))
	{
		int fa = tree[k].fa;
		if(tree[k].l!=0)
		{
			if(x < tree[fa].key)tree[fa].l = tree[k].l;
			else tree[fa].r=tree[k].l;
			if(tree[k].fa==0)root=tree[k].l;//这里需要特判,如果你删掉的是root节点的话需要更新root的值 
		}                                   //渣渣就是因为这里跪了一天。 
		else
		{
			if(x < tree[fa].key)tree[fa].l = tree[k].r;
			else tree[fa].r=tree[k].r;
			if(tree[k].fa==0)root=tree[k].r;//同上 
		}
		tree[k].temp=0;
	     return ;
	}
	
	int tp = searchmin(tree[k].r);
	tree[k].key=tp;
	del(tree[k].r,tp);
	
   return ;
}



int main()
{//以下可以无视 
	int k;
	while(~scanf("%d%d",&n,&k))
	{
		root=1;
		for(int i  = 0;i<= n;i++)
		{
			tree[i].temp=0;
			tree[i].r=0;
			tree[i].l=0;
			tree[i].fa=0;
			tree[i].key=0;
		}
		
		tot=1;
		int cnt=0;
	
		    for(int i = 1;i <= n; i++)
		  {
			scanf("%d",&s[i]);
			if(i < k)
			{
				
				BST(root,s[i]);
			}
			else 
			{
				
				BST(root,s[i]);
				minn[cnt]=searchmin(root);
		    	mann[cnt]=searchmax(root);
				cnt++;
                
				del(root,s[i-k+1]);
				//printf("%d%c",s[i-k+1],i==n?'\n':' ');
				
				
			}
	    	}
		
		for(int i = 0;i < cnt; i++)
		{
			printf("%d%c",minn[i],i==cnt-1?'\n':' ');
		}
		for(int i = 0;i < cnt; i++)
		{
			printf("%d%c",mann[i],i==cnt-1?'\n':' ');
		}
		
	}
	
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值