1、类定义文件SPTree.h
#include <iostream>
enum ResultCode{UnderFlow,OverFlow,Success,Duplicate,Fail,NotPresent};
template <class T>
struct BTNode
{//二叉树结点类
BTNode(const T &x):element(x){lChild = rChild = NULL;}
T element;
BTNode *lChild;
BTNode *rChild;
void PreOrderTraverse(BTNode* root);//先序遍历树
};
template <class T>
class SPTree
{//伸展树类
public:
SPTree(int s = 0):size(s){root = NULL;}
ResultCode Insert(T x);
void print();
protected:
BTNode<T> *root;
int size;
private:
ResultCode Insert(BTNode<T>* &p,T x);
void LRot(BTNode<T>* &p);
void RRot(BTNode<T>* &p);
};
2、 类的实现文件SRTree.cpp
#include "SPTree.h"
#include <stack>
using namespace std;
//左旋转函数
template <class T>
void SPTree<T>::LRot(BTNode<T>* &p)
{//前置条件:p有右孩子,实现向左旋转
BTNode<T> *r = p->rChild;
p->rChild = r->lChild;
r->lChild = p;
p = r;
}
//右旋转函数
template <class T>
void SPTree<T>::RRot(BTNode<T>* &p)
{//前置条件:p有左孩子,实现向右旋转
BTNode<T> *l = p->lChild;
p->lChild = l->rChild;
l->rChild = p;
p = l;
}
//伸展树插入
template <class T>
ResultCode SPTree<T>::Insert(T x)
{
ResultCode result = Insert(root,x);
if (result == Success) size++;
return result;
}
template <class T>
ResultCode SPTree<T>::Insert(BTNode<T>* &p,T x)
{
ResultCode result = Success;
BTNode<T> *r = NULL;
if (p == NULL)//当前伸展树为空,插入元素作为根结点直接插入即可
{
p = new BTNode<T>(x);
return result;
}
if (x == p->element)//插入元素值与根结点值相等,返回Duplicate
{
result = Duplicate;
return result;
}
if (x < p->element)//插入左子树
{
r = p->lChild;
if (r == NULL)//当前结点为空,则插入元素并做右旋转
{
r = new BTNode<T>(x);
r->rChild = p;
p = r;
return result;
}
else if (x == r->element)//插入元素与当前结点左孩子相等,则做一次右旋后返回
{
result = Duplicate;
RRot(p);
return result;
}
else if (x < r->element)//插入元素小于左孩子,则插入左孩子左子树,插入后做一次右旋
{
result = Insert(r->lChild,x);
RRot(r);
p->lChild = r;
}
else
{
result = Insert(r->rChild,x);
LRot(r);
p->lChild = r;
}
RRot(p);//此时插入元素为p左孩子,做一次右旋
}
else
{
r = p->rChild;
if (r == NULL)
{
r = new BTNode<T>(x);
r->lChild = p;
p = r;
return result;
}
else if (x == r->element)
{
LRot(p);
result = Duplicate;
return result;
}
else if (x > r->element)
{
result = Insert(r->rChild,x);
LRot(r);
p->rChild = r;
}
else
{
result = Insert(r->lChild,x);
RRot(r);
p->rChild = r;
}
LRot(p);
}
return result;
}
template <class T>
void SPTree<T>::print()
{
if (this->root != NULL)root->PreOrderTraverse(root);
}
/*
* 先序遍历
* 对于任一结点P:
* 1)访问结点P,并将结点P入栈;
* 2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);
* 若不为空,则将P的左孩子置为当前的结点P;
*
* 3)直到P为NULL并且栈为空,则遍历结束。
*/
template <class T>
void BTNode<T>::PreOrderTraverse(BTNode *root)
{
stack<BTNode*> s;
BTNode *p=root;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
cout<<p->element<<" ";
s.push(p);
p=p->lChild;
}
if(!s.empty())
{
p=s.top();
s.pop();
p=p->rChild;
}
}
}
3、测试文件test.cpp
#include <iostream>
#include "3_2.cpp"
using namespace std;
int main()
{
SPTree<int> head(0);
int elem;
cout<<"please input the element:(end with -1)"<<endl;
cin>>elem;
while (elem != -1)
{
head.Insert(elem);
cout<<"print:";
head.print();
cin>>elem;
}
return 0;
}