迭代器:它的用法与指针用法相同
使用迭代器实现二叉搜索树,使用有两个指针域的头结点实现,
并且多给BSTree中加入一个双亲结点_pParent。
代码:
BSTIterator.hpp
#pragma once
#include<iostream>
using namespace std;
#include<assert.h>
template<class k,class v>
struct BSTNode
{
BSTNode(const k& key=k(),const v& value=v())
:_pLeft(NULL)
,_pRight(NULL)
,_pParent(NULL)
,_key(key)
,_value(value)
{}
BSTNode<k,v>* _pLeft;
BSTNode<k,v>* _pRight;
BSTNode<k,v>* _pParent;
k _key;
v _value;
};
template<class K, class V, class Ref, class Ptr>
class BSTIterator
{
typedef BSTNode<K, V> Node;
typedef BSTIterator<K, V, Ref, Ptr> Self;
public:
BSTIterator()
:_pNode(NULL)
{}
BSTIterator(Node* pNode)
:_pNode(pNode)
{}
BSTIterator(const Self& s)
:_pNode(s._pNode)
{}
Self& operator++()
{
Increment();
return *this;
}
Self operator++(int)
{
Self temp(*this);
Increment();
return temp;
}
Self& operator--()
{
Decrement();
return *this;
}
Self operator--(int)
{
Self temp(*this);
Decrement();
return temp;
}
Ref operator*()//解引用
{
return _pNode->_key;
}
Ptr operator->()//->
{
return &(operator*());
}
bool operator!=(const Self& s)
{
return _pNode!=s._pNode;
}
bool operator==(const Self& s)
{
return !(*this!=s);
}
protected:
// 取当前结点的下一个结点
void Increment()
{
//如果右子树存在,右子树中的最小结点就是当前结点的下一个结点
if(_pNode->_pRight)
{
_pNode=_pNode->_pRight;
while(_pNode->_pLeft)
_pNode=_pNode->_pLeft;
}
else//右子树不存在
{
Node* pParent=_pNode->_pParent;
while(pParent->_pRight==_pNode)
{
_pNode=pParent;
pParent=pParent->_pParent;
}
//特殊情况:根的右子树不存在,获取根的下一节点即为end()
if(_pNode->_pRight!=pParent)
_pNode=pParent;
}
}
// --取前一个小的结点,在left子树中
void Decrement()
{
//左子树存在
if(_pNode->_pRight)
{
_pNode=_pNode->_pLeft;
while(_pNode->_pRight)
_pNode=_pNode->_pRight;
}
else
{
Node* pParent=_pNode->_pParent;
while(_pNode==pParent->_pLeft)
{
_pNode=pParent;
pParent=pParent->_pParent;
}
_pNode=pParent;
}
}
protected:
Node* _pNode;
};
template<class k,class v>
class BSTree
{
typedef BSTNode<k,v> Node;
public:
typedef BSTIterator<k,v,k&,k*> Iterator;
public:
BSTree()
{
_pHead=new Node();
_pHead->_pLeft=_pHead;
_pHead->_pRight=_pHead;
_pHead->_pParent=NULL;
}
Iterator Begin()
{
return _pHead->_pLeft;
}
Iterator End()
{
return _pHead;
}
Node* Find(const k& key)
{
Node* pCur=GetRoot();
while(pCur)
{
if(key==pCur->_key)
return pCur;
else if(key<pCur->_key)
pCur=pCur->_pLeft;
else
pCur=pCur->_pRight;
}
return NULL;
}
bool Insert(const k& key,const v& value)
{
Node*& pRoot=_pHead->_pParent;
if(NULL==pRoot)
{
pRoot=new Node(key,value);
pRoot->_pParent=_pHead;
}
else
{
Node* pCur=pRoot;
Node* pParent=NULL;
while(pCur)
{
if(key < pCur->_key)//向左插入
{
pParent=pCur;
pCur=pCur->_pLeft;
}
else if(key > pCur->_key)//向右插入
{
pParent=pCur;
pCur=pCur->_pRight;
}
else//等于根节点,不需要插入
{
return false;
}
}
//插入到叶子结点后时
pCur=new Node(key,value);
if(key<pParent->_key)
pParent->_pLeft=pCur;
else
pParent->_pRight=pCur;
pCur->_pParent=pParent;
}
_pHead->_pLeft=LeftMost();
_pHead->_pRight=RightMost();
return true;
}
void InOrder()//中序遍历
{
cout<<"InOrder:"<<endl;
_InOrder(GetRoot());
cout<<endl;
}
const k& GetMaxKey()const//找最右结点(最大)
{
Node* pRoot=GetRoot();
assert(pRoot);
Node* pCur=pRoot;
while(pCur->_pRight)
pCur=pCur->_pRight;
return pCur->_key;
}
const k& GetMinKey()const//找最左结点(最小)
{
Node* pRoot=GetRoot();
assert(pRoot);
Node* pCur=pRoot;
while(pCur->_pLeft)
pCur=pCur->_pLeft;
return pCur->_key;
}
bool Remove(const k& key)//删除key结点
{
Node*& pRoot=GetRoot();
//树为空,不能删除结点
if(NULL==pRoot)
return false;
//只有一个根节点,要删除的结点正好是根节点
if(NULL==pRoot->_pLeft && NULL==pRoot->_pRight && key==pRoot->_key)
{
delete pRoot;
_pHead->_pParent=NULL;
}
else
{
//找待删除结点
Node* pCur=pRoot;
Node* pParent=NULL;
while(pCur)
{
if(key<pCur->_key)
{
pParent=pCur;
pCur=pCur->_pLeft;
}
else if(key>pCur->_key)
{
pParent=pCur;
pCur=pCur->_pRight;
}
else
break;//找到了该节点
}
//已找到待删除结点---》1.没有左孩子,只有右孩子
//2.没有右孩子,只有左孩子
// 3.左右孩子都没有
//4.左右孩子都存在
//可以合并1,3 或2,3
if(NULL==pCur)
return false;
else
{ //1.没有左孩子,右孩子可能存在,也可能不存在(NULL)
if(NULL==pCur->_pLeft)
{
if(pCur!=pRoot)
{
if(pCur==pParent->_pRight)
pParent->_pRight=pCur->_pRight;
else
pParent->_pLeft=pCur->_pRight;
}
else
pRoot=pCur->_pRight;
}
//2.没有右孩子,左孩子可能存在,也可能不存在(NULL)
else if(NULL==pCur->_pRight)
{
if(pCur!=pRoot)
{
if(pCur==pParent->_pRight)
pParent->_pRight=pCur->_pLeft;
else
pParent->_pLeft=pCur->_pLeft;
}
else
pRoot=pCur->_pLeft;
}
//3.左右子树都存在
else
{
//找中序遍历的第一个节点,为右子树中最小的结点
//pParnet一直是firstInOrder的双亲
pParent=pCur;//防止在找右子树中最小结点时,右子树没有左孩子,无法进入循环,pParent会一直为空
Node* firstInOrder=pCur->_pRight;
//找该节点的右子树中最左边的结点,即右子树中key最小的结点
while(firstInOrder->_pLeft)
{
pParent=firstInOrder;
firstInOrder=firstInOrder->_pLeft;
}
//交换key最小结点和根节点的值
pCur->_key=firstInOrder->_key;
pCur->_value=firstInOrder->_value;
if(pParent->_pLeft==firstInOrder)
pParent->_pLeft=firstInOrder->_pRight;
else
pParent->_pRight=firstInOrder->_pRight;
pCur=firstInOrder;
}
delete pCur;
pCur=NULL;
}
}
_pHead->_pLeft=LeftMost();
_pHead->_pRight=RightMost();
return true;
}
Node* LeftMost()
{
Node* pCur = GetRoot();
assert(pCur);
while(pCur->_pLeft)
pCur = pCur->_pLeft;
return pCur;
}
Node* RightMost()
{
Node* pCur = GetRoot();
assert(pCur);
while(pCur->_pRight)
pCur = pCur->_pRight;
return pCur;
}
Node*& GetRoot()const
{
return _pHead->_pParent;
}
Node* ToList()//转化为双向链表
{
//找链表头
Node* pHead=GetRoot();
if(NULL==pHead)
return;
while(pHead->_pLeft)
pHead=pHead->_pLeft;
Node* prev = NULL;
_ToList(GetRoot(), prev);
return pHead;
}
protected:
void _InOrder(Node* pRoot)
{
if(pRoot)
{
_InOrder(pRoot->_pLeft);
cout<<pRoot->_key<<" ";
_InOrder(pRoot->_pRight);
}
}
void _ToList(Node* pRoot, Node*& prev)
{
if(pRoot)
{
_ToList(pRoot->_pLeft, prev);
// 当前节点的左指针域
pRoot->_pLeft = prev;
// 上一个结点的右指针域
if(prev)
prev->_pRight = pRoot;
prev = pRoot;
_ToList(pRoot->_pRight, prev);
}
}
private:
Node* _pHead;
};
测试代码:
#include"BSTIterator.hpp"
void Test1()
{
BSTree<int,int> bst;
int a[]={5,3,4,1,7,8,2,6,0,9};
for(int idx=0;idx<(sizeof(a)/sizeof(a[0]));++idx)
{
bst.Insert(a[idx],idx);
}
bst.InOrder();
bst.Find(8);
cout<<bst.GetMinKey()<<endl;
cout<<bst.GetMaxKey()<<endl;
}
void Test2()//情况三①②及情况一
{
BSTree<int,int> bst;
int a[]={5,3,4,1,7,8,2,6,0,9};
//int a[]={5,3,4,1,8,2,6,7,0,9};
for(int idx=0;idx<(sizeof(a)/sizeof(a[0]));++idx)
{
bst.Insert(a[idx],idx);
}
bst.Remove(8);
bst.InOrder();
bst.Remove(6);
bst.InOrder();
}
void Test3()//情况三中的③
{
BSTree<int,int> bst;
int a[]={5,7,8,6,9};
for(int idx=0;idx<(sizeof(a)/sizeof(a[0]));++idx)
{
bst.Insert(a[idx],idx);
}
bst.Remove(5);
bst.InOrder();
}
void Test4()//情况二
{
BSTree<int,int> bst;
int a[]={5,3,4,1,7,6,0};
for(int idx=0;idx<(sizeof(a)/sizeof(a[0]));++idx)
{
bst.Insert(a[idx],idx);
}
bst.Remove(1);
bst.InOrder();
bst.Remove(7);
bst.InOrder();
}
void Test5()//情况四
{
BSTree<int,int> bst;
int a[]={5,3,4,1,7,8,2,6,0,9};
for(int idx=0;idx<(sizeof(a)/sizeof(a[0]));++idx)
{
bst.Insert(a[idx],idx);
}
bst.Remove(5);
bst.InOrder();
bst.Remove(7);
bst.InOrder();
}
void Test6()//情况四
{
BSTree<int,int> bst;
int a[]={5,3,4,1,7,8,2,0,9};
for(int idx=0;idx<(sizeof(a)/sizeof(a[0]));++idx)
{
bst.Insert(a[idx],idx);
}
bst.Remove(5);
bst.InOrder();
}
int main()
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
return 0;
}