二叉搜索树---递归及非递归
来源:互联网 发布:佳能格式转换软件 编辑:程序博客网 时间:2024/06/08 12:21
二叉搜索树又称为二叉排序树,它为一棵空树,或者是一棵左子树所有节点的值比根节点小,右子树所有节点的值比根节点大的一棵树。
性质:
①.二叉搜索树中,最左边的结点值最小,最右边的结点值最大
②中序遍历一棵二叉搜索树,所有节点的值是按顺序排列的构造一棵二叉搜索树时,比较插入结点的key值,key小于根节点的_key时,向根节点的左边走,大于根节点的_key值时,向根节点的右边走; 删除二叉搜索树中的某个结点时,分为四种情况;
删除二叉搜索树中某个节点的情况及处理方法如下:
二叉搜索树的基本操作代码如下:
BSTree.hpp
#pragma once#include<iostream>using namespace std;#include<assert.h>template<class k,class v>struct BSNode{ BSNode(const k& key,const v& value) :_pLeft(NULL) ,_pRight(NULL) ,_key(key) ,_value(value) {} BSNode<k,v>* _pLeft; BSNode<k,v>* _pRight; k _key; v _value;};template<class k,class v>class BSTree{ typedef BSNode<k,v> Node;public: BSTree() :_pRoot(NULL) {} ~BSTree() { _DestroyBSTree(_pRoot); } BSTree<k,v>& operator=(const BSTree<k,v>& bst) { if(this!=&bst) { _DestroyBSTree(_pRoot); _pRoot=_CopyBSTree(bst._pRoot); } return *this; } Node* Find(const k& key)//查找某个节点--非递归 { Node* pCur=_pRoot; 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)//插入某个节点--非递归 { if(NULL==_pRoot) { _pRoot=new Node(key,value); return true; } 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; return true; } void InOrder()//中序遍历 { cout<<"InOrder:"<<endl; _InOrder(_pRoot); cout<<endl; } const k& GetMaxKey()const//找最右结点(最大) { assert(_pRoot); Node* pCur=_pRoot; while(pCur->_pRight) pCur=pCur->_pRight; return pCur->_key; } const k& GetMinKey()const//找最左结点(最小) { assert(_pRoot); Node* pCur=_pRoot; while(pCur->_pLeft) pCur=pCur->_pLeft; return pCur->_key; } bool Remove(const k& key)//删除key结点--非递归 { //树为空,不能删除结点 if(NULL==_pRoot) return false; //只有一个根节点,要删除的结点正好是根节点 if(NULL==_pRoot->_pLeft && NULL==_pRoot->_pRight && key==_pRoot->_key) { delete _pRoot; _pRoot=NULL; return true; } //找待删除结点 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(pCur) { //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; return true; } return false; }//递归版本 //Node* Find(const k& key)//递归找结点 //{ // Node* pCur=NULL; // pCur=_Find(_pRoot,key); // cout<<pCur->_key<<endl; // return pCur; //} // bool Insert(const k& key,const v& value)//递归插入 //{ // return _Insert(_pRoot,key,value); //} //bool Remove(const k& key)//递归删除 //{ // return _Remove(_pRoot,key); //}protected: Node* _CopyBSTree(Node* pRoot)//拷贝 { Node* pNewRoot=NULL; if(pRoot) { //拷贝根节点 pNewRoot=new Node(pRoot->_value); //拷贝左子树 pNewRoot->_pLeft=_CopyBSTree(pRoot->_pLeft); //拷贝右子树 pNewRoot->_pRight=_CopyBSTree(pRoot->_pRight); } return pNewRoot; } void _DestroyBSTree(Node* &pRoot) { if(pRoot) { _DestroyBSTree(pRoot->_pLeft); _DestroyBSTree(pRoot->_pRight); delete pRoot; pRoot=NULL; } } void _InOrder(Node* pRoot) { if(pRoot) { _InOrder(pRoot->_pLeft); cout<<pRoot->_key<<" "; _InOrder(pRoot->_pRight); } } // Node* _Find(Node* pRoot,const k& key)//递归找 //{ // if(NULL==pRoot) // return NULL; // if(key==pRoot->_key) // return pRoot; // else if(key<pRoot->_key) // return _Find(pRoot->_pLeft,key); // else // return _Find(pRoot->_pRight,key); //} //bool _Insert(Node*& pRoot,const k& key,const v& value)//递归插入 //{ // if(NULL==pRoot) // { // pRoot=new Node(key,value); // return true; // } // if(key<pRoot->_key) // return _Insert(pRoot->_pLeft,key,value); // else if(key>pRoot->_key) // return _Insert(pRoot->_pRight,key,value); // else // return false; //} //bool _Remove(Node*& pRoot,const k& key)//递归删除 //{ // if(NULL==pRoot) // return false; // else // { // if(key<pRoot->_key) // _Remove(pRoot->_pLeft,key); // else if(key>pRoot->_key) // _Remove(pRoot->_pRight,key); // else // { // Node* pDel=pRoot; // if(NULL==pRoot->_pLeft) // { // pRoot=pRoot->_pRight; // delete pDel; // return true; // } // else if(NULL==pRoot->_pRight) // { // pRoot=pRoot->_pLeft; // delete pDel; // return true; // } // else // { // Node* firstInOrder=pRoot->_pRight; // while(firstInOrder->_pLeft)//找要删除结点的右子树中最小结点进行交换 // firstInOrder=firstInOrder->_pLeft; // pDel->_key=firstInOrder->_key; // // return _Remove(pRoot->_pRight,firstInOrder->_key); // } // } // } // return false; //}private: Node* _pRoot;};
测试代码:
BST.cpp
#include"BSTree.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
- 二叉搜索树---递归及非递归
- 二叉搜索树-非递归
- 二叉树递归及非递归遍历
- 二叉搜索树(非递归)
- 非递归实现搜索二叉树
- 二叉搜索树的非递归实现
- 二叉搜索树之非递归
- 二叉搜索树 (c++非递归版)
- 二叉搜索树的基本功能的实现(递归及非递归直线插入,删除,查找)
- 深度优先搜索二叉树递归非递归
- 数据结构之搜索二叉树递归&非递归
- 二叉搜索树递归&&非递归的基本实现
- 二叉搜索树(递归和非递归分别实现)
- 【数据结构】二叉搜索树的递归与非递归实现
- 二叉搜索树的递归遍历和非递归遍历
- C++实现二叉搜索树(递归&非递归)
- 递归、非递归~二叉树
- 二叉树 递归 非递归
- 蓝桥杯java第七届决赛第一题--愤怒小鸟
- JS中的prototype原型
- 一个low到爆的快排
- 常用的 myslqi 函数 || 方法 剖析
- 线程化TCP
- 二叉搜索树---递归及非递归
- [C++笔试]类及继承的题目
- 简单了解一下JavaScript正则表达式
- JSON开发笔记(二)—— JSON Schema实战(上)
- SystemUi音量显示笔记
- W3C的理解概括
- 自定义spinner下拉框样式
- imrotate
- 次小生成树 prim求法入门