<6> C++基本的二分搜索树 2021-05-25

//基本的二分搜索树 
#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;
}

 

Supongo que te gusta

Origin blog.csdn.net/lybc2019/article/details/117261516
Recomendado
Clasificación