二叉搜索树---使用迭代器
来源:互联网 发布:qq软件下载安装 编辑:程序博客网 时间:2024/06/05 00:54
迭代器:它的用法与指针用法相同
使用迭代器实现二叉搜索树,使用有两个指针域的头结点实现,
并且多给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;}
阅读全文
0 0
- 二叉搜索树---使用迭代器
- 二叉搜索树的迭代器
- 使用python实现二叉搜索树
- 【二叉搜索数】HDU3791二叉搜索树
- 二叉树--二叉搜索树
- 【二叉树】二叉搜索树
- 二叉树- 二叉搜索树
- 【搜索树】二叉搜索树
- 二叉搜索树BSTree
- 二叉搜索树
- 二叉搜索树
- 二叉搜索树
- 最优二叉搜索树
- 二叉搜索树
- 二叉搜索树
- HDOJ3791 二叉搜索树
- 二叉查找树搜索
- 二叉搜索树
- 验证数字为非负数,并强制保留两位小数。(不进行四舍五入)
- k-近邻算法
- Linux_ActiveMQ 安装笔记
- POJ 1341 The Strongest Subchains 笔记
- PHP Web开发技巧
- 二叉搜索树---使用迭代器
- jdk-AbstractQueuedSynchronizer(四)
- installshield使用教程
- sass scss区别
- 神经网络之激活函数(Activation Function)
- 【Opencv_contri】物体追踪 (部分方法需要opencv3.1及以上)
- 推荐系统文章
- Leetcode 328 Odd Even Linked List
- Sqlmap注入技巧收集整理