查找ing

二叉排序树

先贴代码

#include<iostream>
//二叉排序树 
using namespace std;
struct Node{
	int data;
	Node *lchild,*rchild; 
}; 

class BST{
	private:
		Node* root;
	public:
		BST(int *array,int length); 
		bool deleteBST(int key){return deleteBST(root,key); }
		void preOrder(){preOrder(root);}
		void inOrder(){inOrder(root);}
		Node* searchBST(int key){ return searchBST(root,key);}
	private:
		void insertBST(Node* &bt,int key);
		void preOrder(Node* bt);
		void inOrder(Node* bt);
		bool deleteBST(Node* &bt,int key);
		void deleteNode(Node* &bt);
		Node* searchBST(Node* bt,int key);
};
//构造
BST::BST(int *array,int length){
	root=NULL;
	for(int i=0;i<length;i++){
		insertBST(root,array[i]);
		cout<<array[i]<<endl; 
	}
} 
//插入
void BST::insertBST(Node* &bt,int key){
	if(bt==NULL){
		bt=new Node;
		bt->data=key;
		bt->lchild=NULL;
		bt->rchild=NULL;
	}
	else{
		if(bt->data>key) insertBST(bt->lchild,key);
		else insertBST(bt->rchild,key);
	}
	return;
}
void BST::preOrder(Node* bt){
	if(bt==NULL) return;
	else{
		cout<<bt->data<<" ";
		preOrder(bt->lchild);
		preOrder(bt->rchild);
	}
	return;
}

void BST::inOrder(Node* bt){
	if(bt==NULL) return;
	else{
		inOrder(bt->lchild);
		cout<<bt->data<<" ";
		inOrder(bt->rchild);
	}
	return;
}
//删除
bool BST::deleteBST(Node* &bt,int key){
	if(bt==NULL) return false;
	else{
		if(bt->data==key) deleteNode(bt);
		else if(key<bt->data) deleteBST(bt->lchild,key);
		else deleteBST(bt->rchild,key);
		return true;
	}
} 
void BST::deleteNode(Node* &bt){
	Node *p,*pre;
	if(bt->lchild==NULL&&bt->rchild==NULL){
		bt=NULL;
	}
	else if(bt->lchild==NULL){
		p=bt;
		bt=bt->rchild;
		delete p;
	}
	else if(bt->rchild==NULL){
		p=bt;
		bt=bt->lchild;
		delete p;
	}
	else{
		p=bt;
		pre=bt->lchild;
		while(pre->rchild){
			p=pre;
			pre=pre->rchild;
		}
		bt->data=pre->data;
		if(p!=bt) p->rchild=pre->lchild;
		else p->lchild=pre->lchild;
	}
}

//查找
Node* BST::searchBST(Node* bt,int key){
	if(bt==NULL) return NULL;
	else{
		if(bt->data==key) return bt;
		else if(key<bt->data) return searchBST(bt->lchild,key);
		else return searchBST(bt->rchild,key);
	}
} 

int main(){
	int array[6]={8,1,3,9,11,4};
	BST t(array,6);
	t.inOrder();
	cout<<endl;
	Node* p=t.searchBST(3);
	cout<<p->data<<endl;
	t.deleteBST(9);
	t.inOrder();
	return 0;
}

概念

二叉排序树(也称二叉查找树):或者是一棵空的二叉树,或者是具有下列性质的二叉树:

⑴ 若它的左子树不空,则左子树上所有结点的值均小于根结点的值;

⑵ 若它的右子树不空,则右子树上所有结点的值均大于根结点的值;

⑶ 它的左右子树也都是二叉排序树。

这是内含递归思想的定义,应该比较好理解。

我这里贴一个图:

之前学过的二叉树不是有前序、中序、后序、层序遍历嘛。这里我们可以通过中序遍历得到这个二叉排序树拍好的序。

储存结构

本质上就是一个二叉树,只不过在构造的时候有了一些规定,所以储存结构就是一个结构体指针代表根节点

struct Node{
	int data;
	Node *lchild,*rchild; 
}; 
Node* root;

代码实现

插入

为什么会把插入写在构造之前呢?

因为构造是多次的插入啊hhhhh

1.思路:从根节点出发,如果为空,直接插入;如果不为空,作比较,若当前key小于扫描节点,就往左边走,若当前key大扫描到的节点,就往右边走。

2.代码:

void insert(Node* bt,int key){
    if(bt==NULL){
        bt=new Node;
        bt->data=key;
        bt->lchild=NULL;
        bt->rchild=NULL;
    }
    else{
        if(key<bt->data) insert(bt->lchild,key);
        else insert(bt->rchild,key);
    }
    return;
}

3.注意:

每一次新增结点时都需要new一下。

这里用的是封装的思想,写了一堆public和private,因为外界无法访问root。当然你也可以自己写一个getRoot()函数。 其他的函数也是同样的道理。

构造

1.思路: 传一个数组,然后依次插入。

2.代码:

BST::BST(int *array,int length){
    root=NULL;
    for(int i=0;i<lehgth;i++) insert(root,array[i]);
}

查找

也很简单。

跟插入类似。

直接代码

Node* BST::searchBST(Node* bt,int key){
	if(bt==NULL) return NULL;
	else{
		if(bt->data==key) return bt;
		else if(key<bt->data) return searchBST(bt->lchild,key);
		else return searchBST(bt->rchild,key);
	}
} 

删除

为了防止我的文章过于水,决定在这里写一些删除的内容,这个有一些难度。

1.思路: 先找到要删除的结点位置,再删除结点(废话哒咩!)

这里重点讲一下删除结点的情况,根据待删除的结点拥有左右孩子的情况分为四个类型:

1°没有左右孩子(即为叶节点):直接delete该结点

2°只有一个左(右)孩子:讲该结点的孩子全部托付给双亲,然后delete

3°有两个孩子:

找到待删除结点K左孩子M的最右孩子N,将他覆盖K,这时候就需要处理遗留问题了:N如果有左孩子嘞?(肯定只可能有左孩子)

根据上面只有一个孩子的做法,托付给双亲O。并且有两种情况:

左孩子M有右孩子时   将N的左孩子给O的右边

左孩子M没有右孩子时  直接将左边就覆盖上去

(会不会没讲明白啊,我待会画一个图,不水吧)

	else{
		p=bt;
		pre=bt->lchild;
		while(pre->rchild){
			p=pre;
			pre=pre->rchild;
		}
		bt->data=pre->data;
		if(p!=bt) p->rchild=pre->lchild;
		else p->lchild=pre->lchild;
	}

 所以这里可以好好看看while()循环,嘻嘻。

明天就是高考了,祝大家手摘星辰!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值