zoukankan      html  css  js  c++  java
  • 二叉查找树

    1、什么是二叉查找树

    二叉查找树就是空树或者是每一个结点都有作为查找的依据,并且所有的做左子树的依据都比根结点的小,所有右子树的依据都比根结点的小

    这就是一棵二叉查找树

    同时我们可以看到假如对一棵这样的树进行中序遍历时,可以发现所有依据都将按照从小到大排名

    中序遍历:1 3 4 6 7 8 10 13 14

    同时我们也可以看到最左的结点的依据是最小的,最右的结点是最大的

    2、如何构建?

    1)数据类型

    其实就是二叉树加上个依据而已

    typedef struct {int key;} ElemType;
    typedef struct BitTNode
    {
    	ElemType data;
    	struct BitTNode *lchild, *rchild;
    }BitTNode, *BitTree;
    

    2)如何构建呢?

    从空树出发,依次插入数据

    (1)如果是空树则插入结点就是二叉查找树的根结点

    (2)如果非空,则插入值与根结点比较,若小于根结点则进入左子树,若大于则进入右子树,递归比较。

    对于一棵二叉查找树最重要的是查找,查找就是按照二叉树的定义查找

    有了查找算法后我们可以定义插入算法,有以结点方式插入,有以依据方式插入

    // Insert node
    void Insert_BitTree_1(BitTree &T, BitTree S)
    {
       BitTree p; //use to find the place to insert
       BitTree q; //use to store the parent
    
       if(!T) T=S;  //空树直接插入
       else
       {
       	p=T;
       	while(p)
       	{
       		q=p;    //记录父母
       		if(S->data.key < p->data.key)
       		{
       			p=p->lchild;
       		}
       		else p=p->rchild;
       	}
       	if(S->data.key < q->data.key)
       		q->lchild = S;
       	else
       		q->rchild = S;
       }
    }
    
    // Insert node
    void Insert_BitTree_2(BitTree &T, int key)
    {
    	BItTree p;
    	BitTree q;
        BitTree S = new BitTNode();
    
    	if(!T)      //空结点
    	{
    		S->data.key = key;
    		S->lchild = NULL;
    		S->rchild = NULL;
    		T=S;
    	}
    	else
    	{
    		p = T;
    		while(p)
    		{
    			q=p;
    			if(key > p->data.key)
    			{
    				p=p->rchild;
    			}
    			else p=p->lchild;
    		}
    		if(q->data.key < key)
            {
            	S->data = key;
    		    S->lchild = NULL;
    		    S->rchild = NULL;
                q->rchild = S;
            }
            else
            {
                S->data.key = key;
    		    S->lchild = NULL;
    		    S->rchild = NULL;
                q->lchild = S;	
            }
    	}
    }
    

      

    有插入之后我们需要删除

    删除二叉查找树有两种情况

    一、删除叶子结点

    直接删除

    二、删除根结点

    (1)如果有两个孩子

    选择根结点的左子树中最大的结点作为新的根结点

    或者选择根结点的右子树最小的结点作为新的根结点

    (2)如果只有一个孩子

    则直接把他的孩子作为根结点

    void Delete_BST(BitTree &T, int key)
    {
    	BitTree p, f;
    	p = T;      //p为要删除的结点
    	f = NULL;   //用f储存要删除的结点的父母
    	while(p)
    	{
    		if(p->data.key == key)
    		{
    			delNode(T, p ,f);      // 找到要删除的结点,传入删除函数进行删除
    		}
    		else if(p->data.key < key)
    		{
    			f=p;
    			p=p->rchild;
    		}
    		else if(p->data.key>key)
    		{
    			f=p;
    			p=p->lchild;
    		}
    	}
    }
    
    void delNode(BitTree &T, BitTree p, BitTree f)
    {
    	BitTree s, q;   //用s储存要删除的结点的孩子结点
    	int tag;
    	tag=0;
    
    	if(!p->lchild) s=p->rchild;  //没有左孩子则记录右孩子
    	else if(!p->rchild) s=p->lchild;  //没有右孩子则记录左孩子
    	else   // 有两个孩子
    	{
           //要找左子树中最大的结点做根
    		q=p;
    		s=p->lchild;
    		while(s->rchild)
    		{
    			q=s;        //s储存要做根的结点,q储存s的父母
    			s=s->rchild;
    		}
    		p->data=s->data;
    		if(q==p)q->lchild=s->lchild;
    		else q->rchild=s->lchild;
    		delete s;
    		tag=1;
    	}
    	if(!tag)   //有1个孩子
    	{
            if(!f)T=s;    //删除的是根结点
            else if(f->lchild==p)f->lchild=s;
            else f->rchild=s;
            delete p;
    	}
    }
    

      

  • 相关阅读:
    boost开发指南
    boost bind function用法说明
    boost库 bind/function的使用
    OpenCV——PS滤镜, 碎片特效
    pthread_join()
    基于用例点来度量软件规模并管理进度 之中的一个
    tomcat的JK和JK2
    rackup工具
    ORACLE EXP命令
    很好的理解遗传算法的样例
  • 原文地址:https://www.cnblogs.com/KennyRom/p/6080998.html
Copyright © 2011-2022 走看看