1. 程式人生 > >AVL平衡樹(二叉搜尋樹 c++實現)

AVL平衡樹(二叉搜尋樹 c++實現)

                平衡查詢樹

程式碼:

指標實現

/*仿一個部落格的AVL*/
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<stack>
#include<queue>
#include<ctime>
#include<cstring>
#include<string>
#define LL __int64
#define INF 0x3f3f3f3f3f
using namespace std;
struct node
{
	int val;
	int height;
	node* l;
	node* r;
};
node root;
int max(int a, int b)
{
	return a>b;
}
int height(node *p)
{
	if(p) return p->height;
	return 0;
}
node* maximum(node* p)
{
	if(p)
	{
		while(p->r) p=p->r;
		return p;
	}
	return NULL;
}
node* minimum(node* p)
{
	if(p)
	{
		while(p->l) p=p->l;
		return p;
	}
	return NULL;
}
node* LeftRotation(node* p)
{
	node *q = p->r;
	p->r = q->l;
	q->l = p;
	p->height = max(height(p->l), height(p->r)) + 1;
	q->height = max(height(q->l), height(q->r)) + 1;
	return q;
}
node* RightRotation(node* p)
{
	node *q = p->l;
	p->l = q->r;
	q->r = p;
	p->height = max(height(p->l), height(p->r)) + 1;
	q->height = max(height(q->l), height(q->r)) + 1;
	return q;
}
node* RLeftRotation(node* p)
{
	p->r = RightRotation(p->r);
	return LeftRotation(p);
}
node* LRightRotation(node* p)
{
	p->l = LeftRotation(p->l);
	return RightRotation(p);
}
node* InsertNode(node* &p, int val)
{
	if(!p)
	{
		p = new node;
		p->height=0;
		p->l=NULL;
		p->r=NULL;
		p->val=val;
	}
	else if(val > p->val)
	{
		p->r = InsertNode(p->r, val);
		if(height(p->r) - height(p->l)==2) //插入失衡 
		{
			if(val > p->r->val) p = LeftRotation(p);
			else  				p = RLeftRotation(p);
		}
	}
	else if(val < p->val)
	{
		p->l = InsertNode(p->l, val);
		if(height(p->l) - height(p->r)==2) //插入失衡 
		{
			if(val < p->l->val) p = RightRotation(p);
			else  				p = LRightRotation(p);
		}		
	}
	p->height = max(height(p->l), height(p->r)) + 1;
	return p;
}
node* del(node* &p, int val)
{
	if(p)
	{
		if(val == p->val)
		{
			if(p->l && p->r)//左右都不為空 
			{
				if(height(p->l) > height(p->r))
				{
					node* q = maximum(p->l);
					p->val = q->val;
					p->l = del(p->l, q->val);
				}
				else
				{
					node* q = minimum(p->r);
					p->val = q->val;
					p->r = del(p->r, q->val);					
				}
			}
			else
			{
				node* q = p;
				if(p->l) p=p->l;
				else if(p->r)	p=p->r;
				return NULL;
			}
		}
		else if(val > p->val)
		{
			p->r = del(p->r, val);
			if(height(p->l) - height(p->r) == 2)
			{
				if(height(p->l->r)>height(p->l->l))
				{
					 p = LRightRotation(p);
				}
				else p = RightRotation(p);
			}
		}
		else if(val < p->val)
		{
			p->l = del(p->l, val);
			if(height(p->r) - height(p->l) ==2)
			{
				if(height(p->r->l)>height(p->r->r))
				{
					p=RLeftRotation(p);
				}
				else p = LeftRotation(p);
			}
		}
		return p;
	}
	return NULL;
}
int query(int x)
{
	node *p=root.l;
	int k=0;
	stack<node*>S;
	if(!p)  return false;
	while(p || !S.empty())
	{
		while(p)
		{
			S.push(p);
			p=p->l;
		}
		p=S.top();
		S.pop();
		k++;
		if(k==x)
		{
			return p->val;
			break;
		}
		p=p->r;
	}
	return false;
}
int main()
{
	//freopen("in.txt","r",stdin);  
    //freopen("out.txt","w",stdout);  
	int n,x;	
	char c[4];
	scanf("%d", &n);
	root.l=root.r=NULL;
	while(n--)
	{
		scanf("%s", c);
		if(c[0]=='Y') printf("Single dog!\n");
		else
		{
			scanf("%d", &x);
			if(c[0]=='J')      	InsertNode(root.l, x);
			else if(c[0]=='W') 	printf("%d\n", query(x));
			else if(c[0]=='X')	del(root.l, x);
		}
	}
	return 0;
}

陣列實現:

/***************
Problem from :資料結構 
Problem describe :平衡樹的應用 
****************/

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<stack>
#include<queue>
#include<ctime>
#include<cstring>
#include<string>
#define LL __int64
#define INF 0x3f3f3f3f3f
using namespace std;
struct Tree{
	int key, l, r, size;
}node[111111];
int root=0, top=0;
void left_rotation(int &x)
{
	int y = node[x].r;
	node[x].r = node[y].l;
	node[y].l = x;
	node[y].size = node[x].size;
	node[x].size = node[node[x].l].size + node[node[x].r].size+1;
	x = y;
}
void right_rotation(int &x)
{
	int y = node[x].l;
	node[x].l = node[y].r;
	node[y].r = x;
	node[y].size = node[x].size;
	node[x].size = node[node[x].l].size + node[node[x].r].size+1;
	x = y;
}
void maintain(int &root, bool flag)
{
	if(flag == false)//false => 左 
	{
		// root 的左兒子的左兒子的size>root的右兒子的size 
		if(node[node[node[root].l].l].size > node[node[root].r].size)
		{
			right_rotation(root);
		}
		// root 的左兒子的右兒子的size>root的右兒子的size 
		else if(node[node[node[root].l].r].size > node[node[root].r].size)
		{
			left_rotation(node[root].l);
			right_rotation(root);
		}
		else return ;
	}
	else 
	{
		// root 的右兒子的右兒子的size>root的左兒子的size 
		if(node[node[node[root].r].r].size > node[node[root].l].size)
		{
			left_rotation(root);
		}
		// root 的右兒子的左兒子的size>root的右兒子的size 
		else if(node[node[node[root].r].l].size > node[node[root].l].size)
		{
			right_rotation(node[root].r);
			left_rotation(root);
		}
		else return ;
	}
	maintain(node[root].l,false);
	maintain(node[root].r,true);
	maintain(root,true);
	maintain(root,false);
}
void insert(int &root, int key)
{
	if(root==0)
	{
		root=++top;
		node[root].l = node[root].r = 0;
		node[root].size = 1;
		node[root].key = key;	
	}
	else
	{
		node[root].size ++;
		if(key < node[root].key) insert(node[root].l, key);
		else insert(node[root].r, key);
		maintain(root, key>=node[root].key);
	}
	return ;
}
int remove(int &root, int key)
{
	int d_key;
	node[root].size--;
	if( key == node[root].key || (key > node[root].key&& node[root].r==0) 
		|| (key < node[root].key&& node[root].l==0))
	{
		d_key = node[root].key;
        if(node[root].l && node[root].r)
        {
            node[root].key = remove(node[root].l,node[root].key+1);
        }
        else
        {
            root = node[root].l + node[root].r; 
        }
	}
	else if(key > node[root].key)
	{
		d_key = remove(node[root].r, key);
	}
	else
	{
		d_key = remove(node[root].l, key);	
	}
	return d_key;
}
int select(int &root,int k)//求第k小數
{
    int r = node[node[root].l].size + 1;
    if(r == k) return node[root].key;
    else if(r < k) return select(node[root].r,k - r);
    else return select(node[root].l,k);
}
int main()
{
 	//freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
	int n,cnt=0,x;      
    char c[4];  
    scanf("%d", &n); 
    while(n--)  
    {  
        scanf("%s", c);  
        if(c[0]=='Y') printf("Single dog!\n");  
        else  
        {  
            scanf("%d", &x);  
            if(c[0]=='J')       insert(root, x), cnt++;  
            else if(c[0]=='W')  printf("%d\n", (x>cnt)?0:select(root, x));  
            else if(c[0]=='X')  remove(root, x), cnt--;  
        }  
    }  
	return 0;
}