伸展树

基本知识参考《数据结构基础》     张力  译版      及另一转载博文。

#include <iostream>
#include "splaytree.h"
using namespace std;
void main()
{
	SplayTree st;
	st.Insert(12);
	st.Insert(3);
	st.Insert(7);
	st.Insert(11);
	st.Insert(5);
	st.Insert(4);
	st.Insert(1);
	st.find(11);
	st.find(7);
	st.Delete(7);
	SplayTree s,b;
	st.Split(5,s,b);
}

//splaytree.h
#ifndef _SPLAYTREE_
#define _SPLAYTREE_
#include "splaytree.h"
#include <iostream>
#include <stack>
using namespace std;
class TreeNode
{
	friend class SplayTree;
public:
	TreeNode(int e)
	{
		key=e;
		leftchild=rightchild=0;
	}
private:
	int key;
	TreeNode* leftchild,*rightchild;
};
class SplayTree
{
public:
	SplayTree():root(0){};
	void Insert(int e);
	void splay(stack<TreeNode*> &s);
	void find(int k);
	void Delete(const int k);
	void Split(int k,SplayTree &small,SplayTree &big);
private:
	TreeNode*root;
};
	


#endif

//splaytree.cpp
#include "splaytree.h"
#include <stack>
void SplayTree::splay(stack<TreeNode*> &s)
{
/*
* s is the stack of route
	*/
	if (s.empty())
	{
		return;
	}
	TreeNode *a=0;//current node 
	TreeNode *pa=0;// a's parent 
	TreeNode *ga=0;// a's grand parent 
	a=s.top();
	s.pop();
	while(!s.empty())
	{
		if (!s.empty())
		{
			pa=s.top();s.pop();
		}
		else
		{//a==root end splay
			break;
		}
		if(s.empty())
		{// no grandparent splay onetime then end splay 
			
			if(a==pa->leftchild)
			{//a is pa's leftchild
				pa->leftchild=a->rightchild;
				a->rightchild=pa;
			}
			else
			{
				pa->rightchild=a->leftchild;
				a->leftchild=pa;
			}
			root=a;
			break;
		}
		else
		{
			ga=s.top();s.pop();
			if (pa==ga->leftchild)
			{
				if (a==pa->leftchild)//LL
				{
					ga->leftchild=pa->rightchild;
					pa->rightchild=ga;
					pa->leftchild=a->rightchild;
					a->rightchild=pa;
				} 
				else//LR
				{
					pa->rightchild=a->leftchild;
					ga->leftchild=a->rightchild;
					a->leftchild=pa;
					a->rightchild=ga;
				}
			}
			else
			{
				if (a==pa->leftchild)//RL
				{
					ga->rightchild=a->leftchild;
					pa->leftchild=a->rightchild;
					a->leftchild=ga;
					a->rightchild=pa;
				} 
				else//RR
				{
					ga->rightchild=pa->leftchild;
					pa->leftchild=ga;
					pa->rightchild=a->leftchild;
					a->leftchild=pa;
				}
			}
			if (!s.empty())//prepare for next time 
			{
				TreeNode *temp=s.top();
				if (ga==temp->leftchild)
				{
					temp->leftchild=a;
				}
				else
				{
					temp->rightchild=a;
				}
				
			}
			else
			{
				root=a;
				break;
			}
		}
	}
}
void SplayTree::Insert(int e)
{
	if (!root)
	{//tree is null 
		root=new TreeNode(e);
		return;
	}
	/*
	*	find right position to insert new node 
	*/
	TreeNode *a=root;//current node 
	stack<TreeNode*> s;//record visit route
	while(a)
	{
		s.push(a);
		if (e<a->key)
		{
			a=a->leftchild;
		}
		else if (e>a->key)
		{
			a=a->rightchild;
		}
		else
			break;
	}
	if (a){//the already exist
		// do your update operate here  
	}
	else{
		a=new TreeNode(e);
		if ((s.top())->key>e)
		{
			(s.top())->leftchild=a;
		}
		else
		{
			(s.top())->rightchild=a;
		}
		
	}
	s.push(a);
	/*
	* splay operate 
	*/
	splay(s);
}
void SplayTree::find(int k)
{
	if (!root)
	{
		cout<<"tree is null"<<endl;
	}
	TreeNode* a=root;
	TreeNode *pa=0;
	stack<TreeNode*> s;
	
	while (a)
	{
		s.push(a);
		if (k<a->key)
		{
			a=a->leftchild;
		}
		else if (k>a->key)
		{
			a=a->rightchild;
		}
		else
			break;
	}
	splay(s);
}
void SplayTree::Delete(const int k)
{
	TreeNode*node=root;//当前节点
	TreeNode*temp=0;//前一节点
	int flag=0;//-1 left 1 right
	stack<TreeNode*>s;
	
	while(1)
	{
		if(!node) 
		{
			cout<<"no this node !\n";
			splay(s);
			return;
		}
		
		if(k<node->key) {temp=node;s.push(temp);node=node->leftchild;flag=-1;}
		else if(k>node->key) {temp=node;s.push(temp);node=node->rightchild;flag=1;}
		else break;
	}
	
	if (!node->leftchild&&!node->rightchild)//是叶子节点,无子节点
	{
		if (temp)
		{
			if (flag==-1)
				temp->leftchild=0;
			else
				temp->rightchild=0;	
		}
		else
		{
			root=0;
		}
		
	}
	else if (node->leftchild&&!node->rightchild)//仅有左孩子
	{
		if (temp)
		{
			if (flag==-1)
			{
				temp->leftchild=node->leftchild;
			}
			else
			{
				temp->rightchild=node->leftchild;
			}
		}
		else
		{
			root=node->leftchild;
		}
		
	}
	else if (!node->leftchild&&node->rightchild)//仅有右孩子
	{
		if (temp)
		{
			if (flag==-1)
			{
				temp->leftchild=node->rightchild;
			}
			else
			{
				temp->rightchild=node->rightchild;
			}
		}
		else
		{
			root=node->rightchild;
		}
		
	}
	else	if (node->leftchild&&node->rightchild)//有两个孩子节点
	{
		//找左孩子的最大节点 代替要删除的节点
		TreeNode *p=node->leftchild;
		TreeNode *pp=node;//p的父节点
		
		while (p->rightchild)
		{
			pp=p;
			p=p->rightchild;
		}
		
		//最大节点替换node
		if (pp!=node)
		{
			pp->rightchild=p->leftchild;
			p->leftchild=node->leftchild;
			p->rightchild=node->rightchild;
		}
		else
		{
			if (temp)
			{
				
				TreeNode * t=p->leftchild;
				if(t)
				{
					while (t->leftchild) t=t->leftchild;
					
					t->leftchild=node->rightchild;
				}
				
				p->rightchild=node->rightchild;
			}
			else
			{
				p->rightchild=node->rightchild;
			}
		}
		
		
		if (temp)
		{
			if (flag==-1)
			{
				temp->leftchild=p;
			}
			else
			{
				temp->rightchild=p;
			}
			
		}
		else
		{
			root=p;
		}
		
	}
	delete node;
	splay(s);
	return;
}
/*
*k is the key where to split the tree
*/
void SplayTree::Split(int k,SplayTree &small,SplayTree &big)
{
	if (root)
	{
		find(k);
		small.root=root->leftchild;
		big.root=root->rightchild;
	}
	else
		cout<<"the tree is null "<<endl;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值