基本知识参考《数据结构基础》 张力 译版 及另一转载博文。
#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;
}