伸展树实现

 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;
}
	

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值