//基本的二分搜索树
#include <iostream>
#include <cstdio>
#include <stack>
#include <queue>
#include <string>
#include <sstream>
#include <ctime>
#include <cstdlib>
using namespace std;
template<typename T>
class BST
{
private:
class Node
{
public:
T e;
Node *left;
Node *right;
Node(T e):e(e),left(NULL),right(NULL){}
};
private:
Node *root;
int size;
public:
BST():root(NULL),size(0){}
int getsize(){return size;}
bool empty(){return size==0;}
public:
//向二分搜索树中添加新的元素e
void add(T e){ root=add(root,e);}
private:
//向以node为根的二分搜索树中添加新的元素e
//返回插入新节点后二分搜索树的根
Node* add(Node* node,T e){
if(node==NULL){
size++;
return new Node(e);
}
if(e < node->e)
node->left=add(node->left,e);
else if(e > node->e)
node->right=add(node->right,e);
return node;
}
public:
//看二分搜索树中是否包含e
bool contains(T e){ return contains(root,e);}
private:
//看以node为根的二分搜索树中是否包含元素e
bool contains(Node* node,T e){
if(node ==NULL) return false;
if(node->e==e) return true;
else if(node->e > e)
return contains(node->right,e);
else
return contains(node->left,e);
}
public:
//二分搜索树的前序遍历 递归
void preOrder(){ cout<<"preOrder:";preOrder(root);cout<<endl;}
private:
//前序遍历以node为根的二分搜索树
void preOrder(Node* node){
if(node==NULL) return;
cout<<node->e<<" ";
preOrder(node->left);
preOrder(node->right);
}
public:
//二分搜索树的前序遍历 循环
void preOrderNR(){
cout<<"preOrderNR:";
stack<Node*> st;
st.push(root);
while(!st.empty()){
Node* cur=st.top();
cout<<cur->e<<" ";
st.pop();
if(cur->right!=NULL)
st.push(cur->right);
if(cur->left!=NULL)
st.push(cur->left);
}
cout<<endl;
}
public:
//二分搜索树的中序遍历
void inOrder(){ cout<<"inOrder:";inOrder(root);cout<<endl;}
private:
//中序遍历以node为根的二分搜索树
void inOrder(Node* node){
if(node==NULL) return;
inOrder(node->left);
cout<<node->e<<" ";
inOrder(node->right);
}
public:
//二分搜索树的后序遍历
void postOrder(){ cout<<"postOrder:";postOrder(root);cout<<endl;}
private:
//后序遍历以node为根的二分搜索树
void postOrder(Node* node){
if(node==NULL) return;
postOrder(node->left);
postOrder(node->right);
cout<<node->e<<" ";
}
public:
//二分搜索树的层序遍历
void levelOrder(){
cout<<"levelOrder:";
queue<Node*> q;
q.push(root);
while(!q.empty()){
cout<<q.front()->e<<" ";
if(q.front()->left!=NULL)
q.push(q.front()->left);
if(q.front()->right!=NULL)
q.push(q.front()->right);
q.pop();
}
cout<<endl;
}
public:
//外部友元函数重载<<运算符
friend ostream& operator <<(ostream &os, BST &s)
{
string res;
s.generateBSTString(s.root,0,res);//外部函数调用内部函数需要通过对象调用
string::iterator it;
for (it = res.begin(); it != res.end(); it++) {
os<< *it ;
}
os << endl;
return os;
}
private:
//前序遍历以node为根的二分搜索树生成string字符串
void generateBSTString(Node* node,int depth,string &res){
if(node==NULL){
res.append(generateDepthString(depth)+"null\n");
return ;
}
stringstream ss;
ss<<node->e;
res.append(generateDepthString(depth)+ss.str()+"\n");
generateBSTString(node->left,depth+1,res);
generateBSTString(node->right,depth+1,res);
}
string generateDepthString(int depth){
string res;
for(int i= 0;i<depth;i++) res.append("--");
return res;
}
public:
//寻找二分搜索树的最小元素
T minimum(){
if(getsize()==0)
throw "BST is empty!";
return minimum(root)->e;
}
//寻找二分搜索树的最大元素
T maximum(){
if(getsize()==0)
throw "BST is empty!";
return maximum(root)->e;
}
private:
//返回以node为根的二分搜索树的最小值所在的节点
Node* minimum(Node* node) {
if(node->left==NULL)
return node;
return minimum(node->left);
}
//返回以node为根的二分搜索树的最大值所在的节点
Node* maximum(Node* node) {
if(node->right==NULL)
return node;
return maximum(node->right);
}
public:
//从二分搜索树中删除最小值所在的节点,返回最小值
T removeMin(){
T ret=minimum();
root=removeMin(root);
return ret;
}
private:
//删除掉以node为根的二分搜索树中的最小节点
//返回删除节点后新的二分搜索树的根
Node* removeMin(Node* node){
if(node->left==NULL){
Node* rightnode=node->right;
node->right=NULL;
size--;
return rightnode;
}
node->left=removeMin(node->left);
return node;
}
public:
//从二分搜索树中删除最大值所在的节点,返回最小值
T removeMax(){
T ret=maximum();
root=removeMax(root);
return ret;
}
private:
//删除掉以node为根的二分搜索树中的最大节点
//返回删除节点后新的二分搜索树的根
Node* removeMax(Node* node){
if(node->right==NULL){
Node* leftnode=node->left;
node->left=NULL;
size--;
return leftnode;
}
node->right=removeMax(node->right);
return node;
}
public:
//从二分搜索树中删除元素为e的节点
void remove(T e){
root=remove(root, e);
}
private:
//返回以node为根的二分搜索树中值为e的节点,递归
//返回删除节点后新的二分搜索树的根
Node* remove(Node* node,T e){
if(node==NULL) return NULL;
if(node->e > e){
node->left=remove(node->left,e);
return node;
}
else if(node->e < e){
node->right=remove(node->right,e);
return node;
}
else{
if(node->left==NULL){//待删除节点左子树为空
Node* rightnode=node->right;
node->right=NULL;
size--;
return rightnode;
}
if(node->right==NULL){//待删除节点右子树为空
Node* leftnode=node->left;
node->left=NULL;
size--;
return leftnode;
}
//待删除节点左右子树均不为空的情况
//找到比待删除节点大的最小节点,即待删除节点右子树的最小节点
//用这个节点顶替待删除节点的位置
Node* successor=minimum(node->right);
successor->right=removeMin(node->right);
successor->left=node->left;
node->left=node->right=NULL;
return successor;
}
}
/*
public:
//二分搜索树的中序遍历 循环
void inOrderNR(){
cout<<"inOrderNR:";
cout<<endl;
}
//二分搜索树的后序遍历 循环
void preOrderNR(){
cout<<"preOrderNR:";
cout<<endl;
}
*/
};
void TestBST(){
BST<int> bst;
int nums[]={5,3,6,8,4,2};
for(int i=0;i<6;i++)
bst.add(nums[i]);
bst.preOrder();
bst.preOrderNR();
bst.inOrder();
// bst.inOrderNR();
bst.postOrder();
bst.levelOrder();
cout<<"minimum:"<<bst.minimum()<<endl;
cout<<"maximum:"<<bst.maximum()<<endl;
bst.remove(3);
bst.levelOrder();
cout<<bst<<endl;
/
// 5 //
// / \ //
// 3 6 //
// / \ \ //
// 2 4 8 //
/
}
void TestBST_remove()
{
srand(time(0));
BST<int> bst;
for(int i=0;i<20;i++)
bst.add(rand()%1000+1);
stack<int> st;
while(!bst.empty())
st.push(bst.removeMin());
while(!st.empty()){
cout<<st.top()<<" ";
st.pop();
}
cout<<endl;
for(int i=0;i<20;i++)
bst.add(rand()%1000+1);
while(!bst.empty())
st.push(bst.removeMax());
while(!st.empty()){
cout<<st.top()<<" ";
st.pop();
}
cout<<endl;
}
int main(int argc, char *argv[])
{
TestBST();
TestBST_remove();
return 0;
}
<6> C++基本的二分搜索树 2021-05-25
猜你喜欢
转载自blog.csdn.net/lybc2019/article/details/117261516
今日推荐
周排行