算法导论笔记(5)二叉搜索树

    • 二叉查找树简介
    • 集合操作
      • search搜索
      • mininum寻找子树的最小key节点
      • maxnum子树最大key节点
      • predecessor前序寻找比此节点小的最大节点
      • succesor后序
      • insert插入
      • delete删除
    • c实现

二叉查找树简介

二叉查找树(Binary Search Tree),又被称为二叉搜索树。

它是特殊的二叉树:对于二叉树,假设x为二叉树中的任意一个结点,x节点包含关键字key,节点x的key值记为key[x]。如果y是x的左子树中的一个结点,则key[y] <= key[x];如果y是x的右子树的一个结点,则key[y] >= key[x]。那么,这棵树就是二叉查找树。

集合操作

search搜索

有迭代版和递归版。

思想都是向下查找合适的值,有值会返回节点,无合适值会一直向下走直到返回null

/*
 * (递归实现)查找"二叉树x"中键值为key的节点
 */
BNode* search(BSTree x, Type key)
{
    if (x==NULL || x->key==key)
        return x;
    if (key < x->key)
        return bstree_search(x->left, key);
    else
        return bstree_search(x->right, key);
}

/*
 * (非递归实现)查找"二叉树x"中键值为key的节点
 */
    BNode* search(DataType key) const{
        BNode *p=root;
        while(p!=NULL&&p->key!=key){
            if (key<p->key)
            {
                p=p->left;
            }else{
                p=p->right;
            }
        }
        if(p!=NULL)
            printf("search %d\n",p->key);
        return p;
    }

mininum寻找子树的最小key节点

最小节点是最左子节点

maxnum子树最大key节点

最大节点是最右子节点

predecessor前序寻找比此节点小的最大节点

两种情况,

正常来说是找次节点的左子树最大节点,如果没有左子树,向上寻找根

    BNode* Predecessor(BNode *T){
        BNode *x=T;
        if (x->left!=NULL)
        {
            return maxmun(x->left);
        }
        BNode *y=x->p;
        while(y!=NULL&&x==y->left){
            x=y;
            y=y->p;
        }
        return y;
    };

succesor后序

同样两种情况,右子树的最小值,或者没有右子树的情况下,向上找根

    BNode* Successor(BNode *T){
        BNode *x=T;
        if(x->right!=NULL){
            return minmun(x->right);
        }
        BNode *y=T->p;
        while(y!=NULL&&y->right==x){
            x=y;
            y=y->p;
        }
        return y;
    }

insert插入

向下插入,

两种情况,有根和无根。注意对root的操作

delete删除

删除节点x

1。无左子树,右子树接上。

2。无右子树,左子树接上。

3。左右都有,寻找右子树最小值y

3.1如果最小值为直接右子树,直接替换接上

3.2不是直接右子树,把y右子树替换y,y再替换x

c++实现

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
typedef int DataType;
struct BNode
{
    DataType key;
    BNode *p,*left,*right;
};
class Btree
{
private:
    BNode *root;
public:
    Btree(){
        root=NULL;
    };
    ~Btree(){
        destoryNode(root);
        root=NULL;
    };
    void Insert(DataType key){
        BNode *z=new BNode;
        BNode *y=NULL;
        BNode *x=root;
        z->key=key;
        z->p=z->right=z->left=NULL;
        //初始化x,y和z
        while(x!=NULL){
            y=x;
            if (x->key>key)
            {
                x=x->left;
            }else{
                x=x->right;
            }
        }//x指向root,向下查找
        z->p=y;
        if (y==NULL)
        {
            root=z;
        }else if(y->key>key){
            y->left=z;
        }else{
            y->right=z;
        }//建立z的双亲节点y与z的联系
        printf("Node %d",z->key);
        if(y!=NULL){
            printf("p %d\n",y->key);
        }else{
            printf("\n");
        }
    };
    BNode* search(DataType key) const{
        BNode *p=root;
        while(p!=NULL&&p->key!=key){
            if (key<p->key)
            {
                p=p->left;
            }else{
                p=p->right;
            }
        }
        if(p!=NULL)
            printf("search %d\n",p->key);
        return p;
    }
    BNode* minmun(BNode *T){
        BNode *p=T;
        while(p->left!=NULL){
            p=p->left;
        }
        printf("%d‘s minmun %d\n",T->key,p->key);
        return p;
    }
    BNode* maxmun(BNode *T){
        BNode *p=T;
        while(p->right!=NULL){
            p=p->right;
        }
        printf("%d‘s maxmun %d\n",T->key,p->key);
        return p;
    }
    BNode* Successor(BNode *T){
        BNode *x=T;
        if(x->right!=NULL){
            return minmun(x->right);
        }
        BNode *y=T->p;
        while(y!=NULL&&y->right==x){
            x=y;
            y=y->p;
        }
        return y;
    }
    BNode* Predecessor(BNode *T){
        BNode *x=T;
        if (x->left!=NULL)
        {
            return maxmun(x->left);
        }
        BNode *y=x->p;
        while(y!=NULL&&x==y->left){
            x=y;
            y=y->p;
        }
        return y;
    };
    void Translate(BNode *u,BNode *v){
        if (u->p==NULL)
        {
            root=v;
        }else if(u->p->left==u){
            u->p->left=v;
        }else{
            u->p->right=v;
        }
        if (v!=NULL)
        {
            v->p=u->p;
        }
    }
    int TreeDelete(BNode *z){
        if (z->left==NULL)
        {
            printf("Translate z z->right\n");
            Translate(z,z->right);
            delete z;
        }else if(z->right==NULL){
            printf("Translate z z->left\n");
            Translate(z,z->left);
            delete z;
        }else{
            BNode *y=minmun(z->right);
            if (y->p!=z)
            {
                Translate(y,y->right);
                y->right=z->right;
                y->right->p=y;
                printf("Translate y y->right\n");
            }
            Translate(z,y);
            y->left=z->left;
            y->left->p=y;
            printf("Translate z y\n");
        }
    }
    void destoryNode(BNode *T){
        if (T->left!=NULL)
        {
            destoryNode(T->left);
        }
        if (T->right!=NULL)
        {
            destoryNode(T->right);
        }
        printf("destory %d\n",T->key);
        BNode *p=T;
        delete p;
    };
};
int main(int argc, char const *argv[])
{
    Btree *T=new Btree();
    T->Insert(3);
    T->Insert(7);
    T->Insert(1);
    T->Insert(12);
    T->Insert(8);
    BNode *t=T->search(12);
    BNode *t1=T->search(3);
    T->maxmun(t);
    T->minmun(t);
    T->TreeDelete(t);
    T->TreeDelete(t1);
    delete T;
    return 0;
}
时间: 2024-10-20 12:36:59

算法导论笔记(5)二叉搜索树的相关文章

《数据结构复习笔记》--二叉搜索树

二叉搜索树:维基百科:click here 二叉查找树(Binary Search Tree),也称二叉搜索树.有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树: 若任意节点的左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值: 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 任意节点的左.右子树也分别为二叉查找树. 没有键值相等的节点(no duplicate nodes

算法导论笔记(二)二路归并排序

二路归并排序 归并排序采用了一种”分而治之“的策略:将原问题分解成N个规模较小而结构与原问题相似的子问题:递归求解这些子问题,然后合并其结果,从而得到原问题的解. 分治模式一般遵循以下三个步骤: 分解(Divide):将原问题分解成若干子问题: 解决(Conquer):递归地求解各子问题.若子问题足够小,则直接求解: 合并(Combine):将子问题的解合并成原问题的解. ”二路归并"的算法也遵循以下三个步骤: 分解:将原序列中拥有的N个元素分解各含N / 2个元素的子序列: 解决:用合并排序法

微软算法100题01 二叉搜索树转为双向链表

提高编程能力的最佳途径就是多写代码, 就让我们从现在开始吧! 1. 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向.       10      /    |   6     14 /   |     /  |4   8   12  16 转换成双向链表4=6=8=10=12=14=16. 二叉查找树的特点:任意节点的左子树都要小于当前节点:右子树都要大于当前节点.特点:查询某个值,需要的时间复杂度为O(lgN) 网上的解决方案大部分都是C

LeetCode98 树&#183;验证二叉搜索树(C++)

题目描述: 给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也是二叉搜索树. 示例 1: 输入: 2 / 1 3 输出: true 示例 2: 输入: 5 / 1 4   /   3 6 输出: false 解释: 输入为: [5,1,4,null,null,3,6].   根节点的值为 5 ,但是其右子节点值为 4 . /** * Definition f

LeetCode108 将有序数组转为二叉搜索树

将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定有序数组: [-10,-3,0,5,9], 一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树: 0 / -3 9 / / -10 5 /** * Definition for a binary tree node. * struct TreeNode { * int val; * Tr

【算法导论】学习笔记——第12章 二叉搜索树

搜索树数据结构支持多种动态集合操作,包括SEARCH.MINIMUM.MAXIMUM.PREDECESSOR.SUCCESSOR.INSRT和DELETE操作等.基本的搜索树就是一棵二叉搜索树.12.1 什么是二叉搜索树1. 二叉搜索树的性质:设x是二叉搜索树中的一个结点.如果y是x左子树中的一个结点,那么y.key<=x.key.如果y是x右子树中的一个结点,那么y.key>=x.key.三种遍历时间复杂度是O(n),这是显然的. 12.1-3 1 void Inorder_Tree_Wal

算法导论第十二章 二叉搜索树

一.二叉搜索树概览 二叉搜索树(又名二叉查找树.二叉排序树)是一种可提供良好搜寻效率的树形结构,支持动态集合操作,所谓动态集合操作,就是Search.Maximum.Minimum.Insert.Delete等操作,二叉搜索树可以保证这些操作在对数时间内完成.当然,在最坏情况下,即所有节点形成一种链式树结构,则需要O(n)时间.这就说明,针对这些动态集合操作,二叉搜索树还有改进的空间,即确保最坏情况下所有操作在对数时间内完成.这样的改进结构有AVL(Adelson-Velskii-Landis)

算法导论(Introduction to Algorithms )— 第十二章 二叉搜索树— 12.1 什么是二叉搜索树

搜索树数据结构支持许多动态集合操作,如search(查找).minmum(最小元素).maxmum(最大元素).predecessor(前驱).successor(后继).insert(插入).delete(删除),这些都是基本操作,可以使用一颗搜索树当做一个字典或者一个优先队列. 12.1.什么事二叉搜索树 二叉搜索树是以一棵二叉树来组织的,可以用一个链表数据结构来表示,也叫二叉排序树.二叉查找树: 其中的每个结点都是一个对象,每个对象含有多个属性(key:该结点代表的值大小,卫星数据:不清楚

【算法导论学习-24】二叉树专题2:二叉搜索树(Binary Search Tree,BST)

一.   二叉搜索树(Binary SearchTree,BST) 对应<算法导论>第12章.相比一般二叉树,BST满足唯一的条件:任意节点的key>左孩子的key,同时<右孩子的key. 1.     节点类: public class BinarySearchTreesNode<T> { private int key; private T satelliteData; private BinarySearchTreesNode<T> parent, l