数据结构算法(十) 之 查找

一、顺序表查找

顺序查找又叫线性查找,查找过程:从第一个/最后一个元素开始查找,若找到某个元素的关键字和给定的值相等,那么查找成功,否则查到最后一个/第一个都没有匹配的,则查找不成功。

  • 栗子:for 循环查找列表

二、有序表查找

  • 1、折半查找(二分查找)

    前提:查找的集合有序

    栗子:二分法查找

  • 2、插值查找

    插值查找其实就是针对表长较大,关键字分布比较均匀的表对二分法进行优化的查找,就是将 mid 的计算方法换成了跟关键字 key 有关的算法。

    适用于表长较大,关键字分布比较均匀的表。

三、二叉排序树

二叉排序树又叫二叉查找树,它有如下性质:

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

  • 若右子树不为空,则右子树所有结点值均大于它的根结构的值

  • 它的左右子树也分别为二叉排序树

1. 二叉查找树的查找

在二叉查找树中查找 key 的过程如下:

  • 1、若二叉树是空树,则查找失败。

  • 2、若 x 等于根结点的数据,则查找成功,否则。

  • 3、若 x 小于根结点的数据,则递归查找其左子树,否则。

  • 4、递归查找其右子树。

show my code

/**
     * 判断二叉搜索树是否包含某个值
     * @param key
     * @param root
     * @return
     */
    public static boolean contains(Integer key,BinaryTreeNode root){
        
        if(root == null){
            return false;
        }
        
        int result = key.compareTo(root.value);
        
        //遍历右子树
        if(result > 0){
            return contains(key,root.rightNode);
        }else if(result < 0){
            //遍历左子树
            return contains(key,root.leftNode);
        }else{
            return true;
        }
    }

2. 二叉查找树的插入

插入其实是查找的更进一步,当找到相等的元素的时候便不做操作,直接返回找到的结点。否则根据最后找到的结点,判断要插入的结点为其左子结点还是右子结点。

show my code

/**
     * 插入元素
     * @param key
     * @param root
     * @return 要插入的结点
     */
    public static BinaryTreeNode insert(Integer key,BinaryTreeNode root){
        
        //空树 或者 遍历到了叶子结点
        if(root == null){
            return new BinaryTreeNode(key);
        }
        
        int result = key.compareTo(root.value);
        
        //在右子树遍历
        if(result > 0){
            return root.rightNode = insert(key, root.rightNode);
        }else if(result < 0){
            //在左子树遍历
            return root.leftNode =  insert(key, root.leftNode);
        }else{
            System.out.println("有一个相同的值,不再插入");
            return root;
        }
    }

3. 二叉查找树的删除

对于二叉查找树的删除操作(这里根据值删除,而非结点)分三种情况:

不过在此之前,我们应该确保根据给定的值找到了要删除的结点,如若没找到该结点,不会执行删除操作!

下面三种情况假设已经找到了要删除的结点。

1、如果结点为叶子结点(没有左、右子树),此时删除该结点不会破坏树的结构,直接删除即可,并修改其父结点指向它的引用为 null 。如下图:

情况一

2、如果其结点只包含左子树,或者右子树的话,此时直接删除该结点,并将其左子树或者右子树设置为其父结点的左子树或者右子树即可,此操作不会破坏树结构。

情况二

3、当结点的左右子树都不空的时候,一般的删除策略是用其右子树的最小数据(后继结点)代替要删除的结点数据,并递归删除后继结点,因为右子树的最小结点不可能有左孩子,所以第二次删除较为容易。

z 的左子树和右子树均不空。找到 z 的后继结点 y,因为 y 一定没有左子树,所以可以删除 y。用 y 的值代替 z 的值并让 y 的双亲结点指向 y 的右子树。如图:

情况三

show my code

/**
     * 查询出最小元素所在的结点
     * @param node
     * @return
     */
    public static BinaryTreeNode findMin(BinaryTreeNode node){ 
           
       if(node==null){
             return null;   
        }else if(node.leftNode  ==null){
             return node;  
        }
              
         return findMin(node.leftNode);//递归查找  
     }  
    
    /**
     * 删除值等于key的结点
     * @param key
     * @param root
     * @return
     */
    public static BinaryTreeNode deleteNode(Integer key,BinaryTreeNode root){
        
        if(root == null){
            System.out.println("没有找到要删除的结点,删除失败");
            return null;
        }
        
        int result = key.compareTo(root.value);
        
        if(result > 0){
            root.rightNode = deleteNode(key, root.rightNode);
        }else if(result < 0){
            root.leftNode =  deleteNode(key, root.leftNode);
        }else{
            
            System.out.println("找到了要删除的结点:"+root.value);
            //找到了要删除的结点
            if(root.leftNode != null && root.rightNode != null){
                //找到后继结点(右子树最小结点)
                root.value = findMin(root.rightNode).value;
                //删除后继结点
                deleteNode(root.value,root.rightNode);
            }else if(root.leftNode != null && root.rightNode == null){
                //左子树不为空,右子树为空
                root = root.leftNode;
            }else {
                root = root.rightNode;
            }
        }
        
        return root;
    }

四、平衡二叉树

平衡二叉树是一种二叉排序树,其中每一个结点左子树和右子树的高度差至多等于 1。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,776评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,527评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,361评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,430评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,511评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,544评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,561评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,315评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,763评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,070评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,235评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,911评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,554评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,173评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,424评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,106评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,103评论 2 352

推荐阅读更多精彩内容

  • 一些概念 数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这...
    Winterfell_Z阅读 5,741评论 0 13
  • 数据结构与算法--从平衡二叉树(AVL)到红黑树 上节学习了二叉查找树。算法的性能取决于树的形状,而树的形状取决于...
    sunhaiyu阅读 7,646评论 4 32
  • 目录 1、什么是树 2、相关术语 3、二叉树 3.1、二叉树的类型 3.2、二叉树的性质 3.3、二叉树的结构 3...
    我哈啊哈啊哈阅读 2,541评论 0 10
  • 数据结构与算法--二叉查找树 上节中学习了基于链表的顺序查找和有序数组的二分查找,其中前者在插入删除时更有优势,而...
    sunhaiyu阅读 1,852评论 0 9
  • 我不知道什么时候开始习惯在作文最后标注日期,记录下自己的心情和我的青春。假装留住了时间。 我还是喜欢在...
    Lin花满楼阅读 320评论 0 0