2-3树的实现初探

前面的2-3树实现分析已经分析了2-3树的遍历(traverse),检索(retrieve),插入(insert)和删除(delete)的算法,经过三天的努力,我在分析的基础上采用回溯的方式实现了2-3树,由于还在初级阶段,肯定会出现不少的问题,请多赐教。但经过测试,运行还算正确。下面是代码实现:

2-3树的异常处理类

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//         two_three_tree_exception.h
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifndef TWO_THREE_TREE_EXCEPTION_H_
#define TWO_THREE_TREE_EXCEPTION_H_
#include<stdexcept>
#include<string>
class TTTException :public std::logic_error
{
	public:
		TTTException(const std::string &message="")
			:std::logic_error(message.c_str())
		{}
};
#endif


2-3树的item类,每个节点的数据的存储在这里,包含了一个关键字keyword和相关的值 tel。

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//              two_three_tree_item.h
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifndef TWO_THREE_TREE_ITEM_H_
#define TWO_THREE_TREE_ITEM_H_
#include<string>
typedef std::string KeyType;
class ItemType
{
	public:
		ItemType(){}
		ItemType(const KeyType &_key,const std::string &_tel)
			:keyword(_key),tel(_tel)
		{}
		//get key word keyword;
		const KeyType & getKey()const
		{
			return keyword;
		}
		//set value tel;
		void setTel(const std::string &_tel)
		{
			tel=_tel;
		}
		//get value tel;
		std::string getTel()const
		{
			return tel;
		}
	private:
		KeyType keyword;
		std::string tel;
};
#endif

2-3树的节点类,实现树的完整连接,其中包含两个item,三个孩子:左孩子,中孩子,右孩子

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//             two_three_tree_node.h
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifndef TWO_THREE_TREE_NODE_H_
#define TWO_THREE_TREE_NODE_H_
#include"two_three_tree_item.h"
class Node
{
	private:
		Node(ItemType &_item,Node *_leftPtr,Node*_middlePtr)
			:fItem(_item),LeftPtr(_leftPtr)
			 ,MiddlePtr(_middlePtr),RightPtr(NULL)
		{Nitems=1;}
		//当节点中的item项数为1时,调用此函数重新整合节点
		void reSet(ItemType &_item,Node *_leftPtr,
				Node*_middlePtr)
		{
			Node *tempL=_leftPtr,*tempM=_middlePtr;
			fItem=_item;
			LeftPtr=tempL;
			MiddlePtr=tempM;
			RightPtr=NULL;
			setNumb(1);
		}
		//当节点中的item项数为2时,调用此函数重新整合节点
		void reSet( ItemType &_fitem,ItemType &_litem,Node *_leftPtr,Node *_middlePtr,Node *_rightPtr)
		{
			ItemType tempfi=_fitem,templi=_litem;
			Node *tempL=_leftPtr,*tempM=_middlePtr,*tempR=_rightPtr;
			LeftPtr=tempL;
			MiddlePtr=tempM;
			RightPtr=tempR;
			fItem=tempfi;
			lItem=templi;
			setNumb(2);
			
		}
		//设置节点中item的数目
		void setNumb(int n)
		{
			Nitems=n;
		}
		//清空当前节点中的孩子和item(items)
		void clear()
		{
			LeftPtr=MiddlePtr=RightPtr=NULL;
			setNumb(0);
		}

		ItemType fItem,lItem;
		Node *LeftPtr,*MiddlePtr,*RightPtr;
		int Nitems;
		friend class ttTree;
};

#endif

 

2-3树实现的头文件

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//             two_three_tree.h
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifndef TWO_THREE_TREE_H_
#define TWO_THREE_TREE_H_
#include"two_three_tree_exception.h"
#include"two_three_tree_node.h"
typedef void (*FuncT)(ItemType &_item);
class ttTree
{
	public:
		//默认构造函数
		ttTree();
              	//复制构造函数
		ttTree(ttTree &_tree);
		//析构函数
		virtual ~ttTree();
		

		virtual bool empty()const;
		
		//检索
		virtual void retrieve(const KeyType &_keyword,ItemType &_item)throw(TTTException);

		//遍历
		virtual void traverse(FuncT visit);
		
		//插入
		virtual void insert(const ItemType & newitem)
			throw(TTTException);
		
		//删除
		virtual void remove(const KeyType &keyword)
			throw(TTTException);

		//赋值操作符重载
		virtual ttTree &operator=(ttTree &oldtree)throw(TTTException);

	protected:

		bool insertTree(Node *&treePtr,Node *&tempPtr,ItemType &tempItem)throw(TTTException);
		bool removeTree(Node *&treePtr,Node *&tempPtr,const KeyType &_key)
			throw(TTTException);
		void retrieveTree(Node * &treePtr,const KeyType &_key,ItemType &_item)throw(TTTException);
		void traverseTree(Node *&treePtr,FuncT visit);

		//复制构造函数
		void copyTree(Node *&newtree, Node* &oldtree)throw(TTTException);

		void destroy(Node *&treePtr);

		//在插入的情况下,当当前的item数大于2时,调用此函数维护2-3的原有属性
		bool insertMaintain(Node *&treePtr,Node *&tempPtr,ItemType &tempItem,char ch)throw(TTTException);
		//在删除的情况下,当当前的item数小于1时,调用此函数维护2-3的原有属性
		bool removeMaintain(Node *&treePtr,Node *&tempPtr,char ch);
		
		//寻找当前节点treeptr中项目的中序后继,
		int processLeft(Node *&treePtr,Node*&tempPtr,ItemType &replace);

		//当前的节点treePtr中item数目为2时返回true,否侧返回false
		bool twoItem(Node *&treePtr)const;

		//当前的节点treePtr中的item数目为1时返回true,否则返回false
		bool oneItem(Node *&treePtr)const;

		//判断当前节点treePtr是否为根节点,如是则返回true,否则返回false
		bool isRoot(Node *&treePtr)const;

		//判断当前节点treePtr是否为叶节点,若是则返回true,否则返回false
		bool isLeaf(Node *&treePtr)const;

		//判断当前节点treePtr中是否存在与关键字_key相等的项
		//若存在则返回true,否则返回false
		bool equal(Node*&treePtr,const KeyType & _key)const;


		//按项中关键字的大小重新排序first,middle,last,使其满足
		//first.getkey()<=middle.getKey()<=last.getkey()
		void sort(ItemType &first,ItemType &middle,ItemType &last);

	private:
		Node *root;
};
#endif


2-3树的现实文件

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值