二叉搜索树

二叉搜索树可进行查询,插入,删除操作,不是平衡树,平均时间复杂度O(logN),还可到达O(N)

ACM竞赛也不大常用二叉搜索树,PAT还是常考

实现方法:指针和数组

指针:除了数据结构学习时,竞赛很少用到指针实现

法一:基于C++类封装实现

#include "stdafx.h"
#include <cstdio>
#include <cstring>
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
class BST {
private:
	int data;
	BST *left,*right;
public:
	BST(int te):data(te),left(NULL),right(NULL){}
	static void insert(BST *&root,int te) {
		if (root == NULL) {
			root = new BST(te);
		}
		else if(te < root->data){
			insert(root->left, te);
		}
		else {
			insert(root->right, te);
		}
	}
	BST *const &findMin() {
		return this->left == NULL ? this : this->left->findMin();
	}
	void deletes(BST *&root,int te) {
		if (root == NULL) {
			return;
		}
		else if (te < root->data) {
			deletes(root->left, te);
		}
		else if (te > root->data) {
			deletes(root->right, te);
		}
		else if (root->left && root->right) {
			BST * const t = root->right->findMin();
			root->data = t->data;
			deletes(root->right, t->data);
		}
		else {
			BST *t = root;
			if (root->left == NULL) {
				root = root->right;
			}
			else {
				root = root->left;
			}
			delete t;
		}
	}
	void postOrder() {//后序遍历
		if (this->left) {
			this->left->postOrder();
		}
		if (this->right) {
			this->right->postOrder();
		}
		cout << " " << this->data;
	}
	void dispose() {//递归释放内存
		if (this->left) {
			this->left->dispose();
		}
		if (this->right) {
			this->right->dispose();
		}
		delete this;
	}
};
int main() {
	BST *root = NULL;
	int n,te;
	cin >> n;//6
	for (int i = 0; i < n; i++) {//7 6 11 8 12 13
		cin >> te;
		BST::insert(root, te);
	}
	if (root != NULL) {
		root->postOrder();
	}
	cout << endl;
	if (root != NULL) {
		root->deletes(root,11);
	}
	if (root != NULL) {
		root->postOrder();
	}
	cout << endl;
	if (root != NULL) {
		root->dispose();
	}
	return 0;
}

感觉以上不符合C++的封装规则,又改了一下

#include "stdafx.h"
#include <cstdio>
#include <cstring>
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
class treeNode {
private:
	int data;
	treeNode *left, *right;
public:
	treeNode(int te):data(te),left(NULL),right(NULL){}
	treeNode *&findMin(treeNode *&root, int te) {
		if (root->left == NULL) {
			return root;
		}
		else
			return findMin(root->left, te);
	}
	treeNode *find(treeNode *root,int te) {
		if (root == NULL || root->data == te) {
			return root;
		}
		return te < root->data ? find(root->left, te) : find(root->right, te);
	}
	static void insert(treeNode *&root, int te) {
		if (root == NULL) {
			root = new treeNode(te);
			return;
		}
		else if (te < root->data) {
			insert(root->left, te);
		}
		else if(te > root->data){
			insert(root->right, te);
		}
		else if (te == root->data) {
			cerr << "ERROR" << endl;
		}
	}
	void deletes(treeNode *&root, int te) {
		if (root == NULL) {
			cerr << "ERROR" << endl;
			return;
		}
		else if (te < root->data) {
			deletes(root->left, te);
		}
		else if (te > root->data) {
			deletes(root->right, te);
		}
		else if(root->left && root->right){
			treeNode *&p = findMin(root->right, te);
			root->data = p->data;
			deletes(root->right, root->data);
		}
		else {
			treeNode *t = root;
			root = root->left == NULL ? root->right : root->left;
			delete t;
		}
	}
	void postOrder(treeNode *&root) {
		if (root == NULL) {
			return;
		}
		postOrder(root->left);
		postOrder(root->right);
		cout << " " << root->data;
	}
	void disPosal(treeNode *&root) {
		if (root->left) {
			disPosal(root->left);
		}
		if (root->right) {
			disPosal(root->right);
		}
		delete root;
	}
};
class BST {
private:
	treeNode *root;
public:
	BST() :root(NULL) {}
	void add(int te) {
		treeNode::insert(root, te);
	}
	void remove(int te) {
		if (root == NULL) {
			cerr << "ERROR" << endl;
			return;
		}
		root->deletes(root,te);
	}
	treeNode *query(int te) {
		if (root == NULL) {
			cerr << "ERROR" << endl;
			return NULL;
		}
		return root->find(root, te);
	}
	void postOrder() {
		if (root == NULL) {
			cerr << "ERROR" << endl;
			return;
		}
		root->postOrder(root);
	}
	void disPosal() {
		if (root == NULL) {
			return;
		}
		root->disPosal(root);
	}
};
int main() {
	int n, te;
	BST bst;
	cin >> n;//6
	for (int i = 0; i < n; i++) {//7 6 11 8 12 13
		cin >> te;
		bst.add(te);
	}
	bst.postOrder();
	cout << endl;
	bst.remove(11);
	bst.postOrder();
	cout << endl;
	bst.disPosal();
	return 0;
}


法二:普通指针实现

#include <stdio.h>  
#include <string.h>  
#include <stdlib.h>  
//插入和删除函数必须都得以返回指针的形式实现  
//对于插入,看其最后的NULL时插入就能看出  
//对于删除,本质删除的是只有一个儿子和没有儿子的节点,想其删除没有儿子的节点的情况  
//若不返回指针,此节点的父亲就有个指针指向非法区了  
struct TreeNode{  
    int Element;  
    struct TreeNode* Left;  
    struct TreeNode* Right;  
};  
struct TreeNode* Init(){//初始化  
    return NULL;  
}  
void PreTraversal(struct TreeNode* BinSearchTree)//前序遍历    
{    
    if(BinSearchTree!=NULL){    
         printf("%d ",BinSearchTree->Element);    
         PreTraversal(BinSearchTree->Left);    
         PreTraversal(BinSearchTree->Right);    
    }  
    return;    
}    
struct TreeNode* Find(int data,struct TreeNode* BinSearchTree)//查找  
{  
    if(BinSearchTree==NULL)  
        return NULL;  
    else if(BinSearchTree->Left!=NULL&&data<BinSearchTree->Element)  
        return BinSearchTree->Left;  
    else if(BinSearchTree->Right!=NULL&&data>BinSearchTree->Element)  
        return BinSearchTree->Right;  
    else   
        return BinSearchTree;  
}  
struct TreeNode* FindMax(struct TreeNode* BinSearchTree)//查找最大值所在的节点  
{  
    if(BinSearchTree==NULL)  
        return NULL;  
    else if(BinSearchTree->Right!=NULL)  
        return FindMax(BinSearchTree->Right);  
    else  
        return BinSearchTree;  
}  
struct TreeNode* FindMin(struct TreeNode* BinSearchTree)//查找最小值所在的节点  
{  
    if(BinSearchTree==NULL)  
        return NULL;  
    else if(BinSearchTree->Left!=NULL)  
        return FindMin(BinSearchTree->Left);  
    else  
        return BinSearchTree;  
}  
struct TreeNode* Insert(int data,struct TreeNode* BinSearchTree)//插入  
{  
    if(BinSearchTree==NULL){  
        BinSearchTree=(struct TreeNode*)malloc(sizeof(struct TreeNode));  
        BinSearchTree->Element=data;  
        BinSearchTree->Left=NULL;  
        BinSearchTree->Right=NULL;  
        return BinSearchTree;  
    }  
    else if(data<BinSearchTree->Element)  
        BinSearchTree->Left=Insert(data,BinSearchTree->Left);  
    else if(data>BinSearchTree->Element)  
        BinSearchTree->Right=Insert(data,BinSearchTree->Right);  
    else  
        printf("ERROR\n");  
    return BinSearchTree;  
}  
struct TreeNode* Delete(int data,struct TreeNode* BinSearchTree)//删除  
{  
    if(BinSearchTree==NULL)  
        return NULL;  
    else if(data>BinSearchTree->Element)  
        BinSearchTree->Right=Delete(data,BinSearchTree->Right);  
    else if(data<BinSearchTree->Element)  
        BinSearchTree->Left=Delete(data,BinSearchTree->Left);  
    else if(BinSearchTree->Left&&BinSearchTree->Right){//删除有两个孩子的节点,可找左树最大与右树最小代替其,本质删除没有儿子的节点  
        struct TreeNode* Temp=FindMin(BinSearchTree->Right);  
        BinSearchTree->Element=Temp->Element;  
        BinSearchTree->Right=Delete(Temp->Element,BinSearchTree->Right);  
    }  
    else{//删除有一个/零个孩子的节点  
        struct TreeNode* Temp;  
        Temp=BinSearchTree;  
        if(BinSearchTree->Left!=NULL)  
            BinSearchTree=BinSearchTree->Left;  
        else//此处包含了右儿子也为空的情况,即零个孩子  
            BinSearchTree=BinSearchTree->Right;  
        free(Temp);  
    }  
    return BinSearchTree;  
  
}  
int main(){  
    struct TreeNode* BinSearchTree;  
    //初始化  
    BinSearchTree=Init();  
    //插入  
    BinSearchTree=Insert(4,BinSearchTree);  
    BinSearchTree=Insert(3,BinSearchTree);  
    BinSearchTree=Insert(6,BinSearchTree);  
    BinSearchTree=Insert(5,BinSearchTree);  
    BinSearchTree=Insert(7,BinSearchTree);  
    BinSearchTree=Insert(2,BinSearchTree);  
    //遍历一遍,便于检验代码  
    PreTraversal(BinSearchTree);  
    putchar('\n');  
    //删除有零个孩子的2节点  
    BinSearchTree=Delete(2,BinSearchTree);  
    PreTraversal(BinSearchTree);  
    putchar('\n');  
    //重新插入2  
    BinSearchTree=Insert(2,BinSearchTree);  
    //删除有一个孩子的3节点  
    Delete(3,BinSearchTree);  
    PreTraversal(BinSearchTree);  
    putchar('\n');  
    //删除有两个孩子的6节点  
    Delete(6,BinSearchTree);  
    PreTraversal(BinSearchTree);  
    putchar('\n');  
      
}  


数组实现:

法一:基于C++类封装实现

#include "stdafx.h"
#include <cstdio>
#include <cstring>
#include <iostream>
#include <fstream>
#include <sstream>
#include <queue>
using namespace std;
#define MAXN 100005
class BST {
private:
	int len,root;
	int data[MAXN], left[MAXN], right[MAXN], book[MAXN];
public:
	BST(int te) :len(te),root(-1){
		memset(left, -1, sizeof(left));
		memset(right, -1,sizeof(right));
		memset(book, 0, sizeof(book));
	}
	void insert(int &root, int i) {//执行插入操作
		if (root == -1) {
			root = i;
			return;
		}
		if (data[i] < data[root]) {
			insert(left[root], i);
		}
		else {
			insert(right[root], i);
		}
	}
	void buildTree() {//建树
		for (int i = 0; i < len; i++) {
			cin >> data[i];
			book[i] = 1;
			insert(root, i);
		}
	}
	int query(int te) {//查询当前值的下标
		for (int i = 0; i < len; i++) {
			if (book[i] && data[i] == te) {
				return i;
			}
		}
		return -1;
	}
	void add(int te) {//增添数据
		if (query(te) != -1) {
			return;
		}
		data[len++] = te;
		insert(root, len-1);
	}
	int findMin(int i) {//查找当前节点以及其子树的最小值的下标
		if (left[i] == -1) {
			return i;
		}
		return findMin(left[i]);
	}
    void deletes(int &root, int te) {//执行删除操作
		if (root == -1) {
			return;
		}
		else if (te < data[root]) {
		    deletes(left[root], te);
		}
		else if (te > data[root]) {
			deletes(right[root], te);
		}
		else if(left[root] != -1 && right[root] != -1){
			int index = findMin(right[root]);
			data[root] = data[index];
			deletes(right[root], data[root]);
		}
		else {
			root = left[root] == -1?right[root]:left[root];
			book[root] = 0;
		}
	}
	void remove(int te) {//删除数据
		deletes(root, te);
	}
	void levelOrder() {//层序遍历
		queue<int> q;
		q.push(root);
		while (!q.empty()) {
			int t = q.front();
			cout << " " << data[t];
			q.pop();
			if (left[t] != -1) {
				q.push(left[t]);
			}
			if (right[t] != -1) {
				q.push(right[t]);
			}
		}
		cout << endl;
	}
};
int main() {
	int te,n;
	BST *tree;
	while (scanf("%d", &n) != EOF) {
		tree = new BST(n);
		tree->buildTree();
		tree->add(3);
		tree->remove(3);
		tree->levelOrder();
		delete tree;
	}
	return 0;
}


法二:普通实现

#include "stdafx.h"
#include <cstdio>
#include <cstring>
#include <iostream>
#include <fstream>
#include <sstream>
#include <queue>
using namespace std;
#define MAXN 100005
int data[MAXN], left[MAXN], right[MAXN],book[MAXN];
int root, len;
void insert(int &root, int i) {
	if (root == -1) {
		root = i;
		return;
	}
	if (::data[i] < ::data[root]) {
		insert(::left[root], i);
	}
	else {
		insert(::right[root], i);
	}
}
int findMin(int root) {
	if (::book[root] && ::left[root] == -1) {
		return root;
	}
	return findMin(::left[root]);
}
void deletes(int &root, int te) {
	if (root == -1) {
		return;
	}
	else if (te < ::data[root]) {
		deletes(::left[root], te);
	}
	else if (te > ::data[root]) {
		deletes(::right[root], te);
	}
	else if (::left[root] != -1 && ::right[root] != -1) {
		int index = findMin(::right[root]);
		::data[root] = ::data[index];
		deletes(::right[root], ::data[root]);
	}
	else {
		root = ::left[root] == -1 ? ::right[root]: ::left[root];
		::book[root] = 0;
	}
}
void levelOrder() {
	queue<int> q;
	q.push(root);
	while (!q.empty()) {
		int t = q.front();
		q.pop();
		cout << " " << ::data[t];
		if (::left[t] != -1) {
			q.push(::left[t]);
		}
		if (::right[t] != -1) {
			q.push(::right[t]);
		}
	}
	cout << endl;
}
int main() {
	int te;
	while (scanf("%d", &len) != EOF) {
		root = -1;
		memset(::left, -1, sizeof(::left));
		memset(::right, -1, sizeof(::right));
		memset(::book, 0, sizeof(::book));
		for (int i = 0; i < len; i++) {
			cin >> ::data[i];
			::book[i] = 1;
			insert(root, i);
		}
		::data[len++] = 4;
		insert(root, len - 1);
		deletes(root, 4);
		levelOrder();
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值