二叉排序树_插入+删除+查找

原本是想写关于android分享功能的博客,但是没真机不好去测试,大白天的手机被3岁娃娃,拿去看少儿频道了,大哭,悲催撒!好啊,我还是总结下我学的C/C++相关的知识。

关于二叉排序树的定义是

二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
(4)没有键值相等的节点。
// Simple.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
using namespace std;

#include <algorithm>
#include <string.h>
#include <stdio.h>
typedef struct  BTNode{
	int key;
	struct BTNode *lchild;
	struct BTNode *rchild;
}BTNode;

//递归查找法
BTNode *BSTSearch(BTNode *bt,int key){
	if(bt==NULL){
		return NULL;
	}else{
		if (bt->key==key)return bt;
		else if(key<bt->key)
			return BSTSearch(bt->lchild,key);
		else
			return BSTSearch(bt->rchild,key);
	}
}

//非递归查找法
BTNode *NoBSTSearch(BTNode *p,int key){
	bool solve=false;
	while (p&&!solve)
	{

		if(key==p->key)
			solve=true;
		else if (key<p->key)
		{
			p=p->lchild;
		}else{
			p=p->rchild;
		}
	}
	if(p==NULL){
		cout<<"没有找到"<<key<<endl;
	}
	return p;

}

//递归插入法
int BSTInsert(BTNode *&bt,int key){
	if(bt==NULL){
		bt=(BTNode *)malloc(sizeof(BTNode));
		bt->lchild=bt->rchild=NULL;
		bt->key=key;
		return 1;
	}else{
		if (key==bt->key)
			return 0;
		else if(key<bt->key){
			return BSTInsert(bt->lchild,key);
		}else 
			return BSTInsert(bt->rchild,key);
	}
}

//非递归插入法
int BSTInsert2(BTNode *&t,int key){
	BTNode *p=(BTNode*)malloc(sizeof(BTNode));
	BTNode *q=t;
	p->key=key;
	p->lchild=p->rchild=NULL;
	if(t==NULL){
		t=p;
		return 1;
	}
	while (q->lchild!=p&&q->rchild!=p)
	{
		if (key<q->key)
		{
			if(q->lchild){
				q=q->lchild;
			}else{
				q->lchild=p;
			}
		}else{
			if (q->rchild)
			{
				q=q->rchild;
			}else{
				q->rchild=p;
			}
		}
	}
	return 1;
}

//非递归删除
bool DelBST(BTNode *&t,int x){
	 bool find = false;
    BTNode *q=t;
    BTNode *p = t;
    while(p && !find){  //寻找被删元素 
		if(x == p->key){  //找到被删元素 
            find = true;    
        }    
		else if(x < p->key){ //沿左子树找 
            q = p;
            p = p->lchild;    
        }
        else{   //沿右子树找 
            q = p;
            p = p->rchild;    
        }
    }

    if(p == NULL){   //没找到 
        cout << "没有找到" << x << endl;    
    }

	
	
	
    if(p->lchild == NULL && p->rchild == NULL)
	{  
		//p为叶子节点
		if(p == t){  //p为根节点 
            t = NULL;    
        }else if(q->lchild == p){   
			q->lchild = NULL;
        }else{
            q->rchild = NULL;    
        }
        free(p);  //释放节点p 

    }else if(p->lchild == NULL || p->rchild == NULL){ //p为单支子树 
		if(p ==t){  //p为根节点 
            if(p->lchild == NULL){
                t = p->rchild;    
            }    
            else{
                t = p->lchild;    
            }
        }else{
            if(q->lchild == p && p->lchild){ //p是q的左子树且p有左子树 
                q->lchild = p->lchild;    //将p的左子树链接到q的左指针上 
            }    
            else if(q->lchild == p && p->rchild){
                q->lchild = p->rchild;    
            }
            else if(q->rchild == p && p->lchild){
                q->rchild = p->lchild;    
            }
            else{
                q->rchild = p->rchild;
            }
        }
        free(p);
    }else{ //p的左右子树均不为空 
		BTNode *t = p;
        BTNode *s = p->lchild;  //从p的左子节点开始 
        while(s->rchild){  //找到p的前驱,即p左子树中值最大的节点 
            t = s;   
            s = s->rchild;    
        }
		p->key = s->key;   //把节点s的值赋给p 
        if(t == p){
            p->lchild = s->lchild;    
        }    
        else{
            t->rchild = s->lchild;    
        }
        free(s); 
    }
    return find;

}

int main()
{
	BTNode *T;
	T=NULL;
	BSTInsert2(T,15);
	BSTInsert2(T,5);
	BSTInsert2(T,3);
	BSTInsert2(T,12);
	BSTInsert2(T,10);
	BSTInsert2(T,13);
	BSTInsert2(T,6);
	BSTInsert2(T,7);
	BSTInsert2(T,16);
	BSTInsert2(T,20);
	BSTInsert2(T,18);
	BSTInsert2(T,23);
	DelBST(T,5);
	BTNode *a=NoBSTSearch(T,16);

	system("pause");
    return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值