數(shù)據(jù)結(jié)構(gòu)算法(十) 之 查找

一甩挫、順序表查找

順序查找又叫線性查找椿每,查找過程:從第一個/最后一個元素開始查找,若找到某個元素的關(guān)鍵字和給定的值相等亦渗,那么查找成功汁尺,否則查到最后一個/第一個都沒有匹配的,則查找不成功搂蜓。

  • 栗子:for 循環(huán)查找列表

二、有序表查找

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

    前提:查找的集合有序

    栗子:二分法查找

  • 2殉挽、插值查找

    插值查找其實就是針對表長較大,關(guān)鍵字分布比較均勻的表對二分法進(jìn)行優(yōu)化的查找一死,就是將 mid 的計算方法換成了跟關(guān)鍵字 key 有關(guān)的算法傻唾。

    適用于表長較大,關(guān)鍵字分布比較均勻的表逛裤。

三猴抹、二叉排序樹

二叉排序樹又叫二叉查找樹,它有如下性質(zhì):

  • 若左子樹不為空蝙砌,則左子樹上所有結(jié)點(diǎn)值均小于它的根結(jié)構(gòu)的值

  • 若右子樹不為空跋理,則右子樹所有結(jié)點(diǎn)值均大于它的根結(jié)構(gòu)的值

  • 它的左右子樹也分別為二叉排序樹

1. 二叉查找樹的查找

在二叉查找樹中查找 key 的過程如下:

  • 1、若二叉樹是空樹肚邢,則查找失敗拭卿。

  • 2峻厚、若 x 等于根結(jié)點(diǎn)的數(shù)據(jù),則查找成功惠桃,否則。

  • 3劈狐、若 x 小于根結(jié)點(diǎn)的數(shù)據(jù)懈息,則遞歸查找其左子樹,否則辫继。

  • 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. 二叉查找樹的插入

插入其實是查找的更進(jìn)一步舵变,當(dāng)找到相等的元素的時候便不做操作纪隙,直接返回找到的結(jié)點(diǎn)扛或。否則根據(jù)最后找到的結(jié)點(diǎn),判斷要插入的結(jié)點(diǎn)為其左子結(jié)點(diǎn)還是右子結(jié)點(diǎn)悲伶。

show my code

/**
     * 插入元素
     * @param key
     * @param root
     * @return 要插入的結(jié)點(diǎn)
     */
    public static BinaryTreeNode insert(Integer key,BinaryTreeNode root){
        
        //空樹 或者 遍歷到了葉子結(jié)點(diǎn)
        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. 二叉查找樹的刪除

對于二叉查找樹的刪除操作(這里根據(jù)值刪除舆声,而非結(jié)點(diǎn))分三種情況:

不過在此之前媳握,我們應(yīng)該確保根據(jù)給定的值找到了要刪除的結(jié)點(diǎn),如若沒找到該結(jié)點(diǎn)忽媒,不會執(zhí)行刪除操作腋粥!

下面三種情況假設(shè)已經(jīng)找到了要刪除的結(jié)點(diǎn)隘冲。

1、如果結(jié)點(diǎn)為葉子結(jié)點(diǎn)(沒有左奥邮、右子樹)罗珍,此時刪除該結(jié)點(diǎn)不會破壞樹的結(jié)構(gòu),直接刪除即可覆旱,并修改其父結(jié)點(diǎn)指向它的引用為 null 。如下圖:

情況一

2、如果其結(jié)點(diǎn)只包含左子樹噪沙,或者右子樹的話正歼,此時直接刪除該結(jié)點(diǎn),并將其左子樹或者右子樹設(shè)置為其父結(jié)點(diǎn)的左子樹或者右子樹即可齐疙,此操作不會破壞樹結(jié)構(gòu)旭咽。

情況二

3穷绵、當(dāng)結(jié)點(diǎn)的左右子樹都不空的時候仲墨,一般的刪除策略是用其右子樹的最小數(shù)據(jù)(后繼結(jié)點(diǎn))代替要刪除的結(jié)點(diǎn)數(shù)據(jù),并遞歸刪除后繼結(jié)點(diǎn)俩由,因為右子樹的最小結(jié)點(diǎn)不可能有左孩子幻梯,所以第二次刪除較為容易。

z 的左子樹和右子樹均不空碘梢。找到 z 的后繼結(jié)點(diǎn) y,因為 y 一定沒有左子樹肛鹏,所以可以刪除 y。用 y 的值代替 z 的值并讓 y 的雙親結(jié)點(diǎn)指向 y 的右子樹恩沛。如圖:

情況三

show my code

/**
     * 查詢出最小元素所在的結(jié)點(diǎn)
     * @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的結(jié)點(diǎn)
     * @param key
     * @param root
     * @return
     */
    public static BinaryTreeNode deleteNode(Integer key,BinaryTreeNode root){
        
        if(root == null){
            System.out.println("沒有找到要刪除的結(jié)點(diǎn)在扰,刪除失敗");
            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("找到了要刪除的結(jié)點(diǎn):"+root.value);
            //找到了要刪除的結(jié)點(diǎn)
            if(root.leftNode != null && root.rightNode != null){
                //找到后繼結(jié)點(diǎn)(右子樹最小結(jié)點(diǎn))
                root.value = findMin(root.rightNode).value;
                //刪除后繼結(jié)點(diǎn)
                deleteNode(root.value,root.rightNode);
            }else if(root.leftNode != null && root.rightNode == null){
                //左子樹不為空,右子樹為空
                root = root.leftNode;
            }else {
                root = root.rightNode;
            }
        }
        
        return root;
    }

四健田、平衡二叉樹

平衡二叉樹是一種二叉排序樹佛纫,其中每一個結(jié)點(diǎn)左子樹和右子樹的高度差至多等于 1呈宇。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末存炮,一起剝皮案震驚了整個濱河市穆桂,隨后出現(xiàn)的幾起案子融虽,更是在濱河造成了極大的恐慌有额,老刑警劉巖巍佑,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件堕义,死亡現(xiàn)場離奇詭異脆栋,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舍扰,“玉大人边苹,你說我怎么就攤上這事个束〔绲祝” “怎么了阱表?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵最爬,是天一觀的道長爱致。 經(jīng)常有香客問我蒜鸡,道長逢防,這世上最難降的妖魔是什么忘朝? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任溉箕,我火速辦了婚禮肴茄,結(jié)果婚禮上羡棵,老公的妹妹穿的比我還像新娘。我一直安慰自己概说,他們只是感情好劈猿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布拍棕。 她就那樣靜靜地躺著绰播,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腰池。 梳的紋絲不亂的頭發(fā)上示弓,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機(jī)與錄音囱皿,去河邊找鬼。 笑死齿兔,一個胖子當(dāng)著我的面吹牛分苇,可吹牛的內(nèi)容都是我干的医寿。 我是一名探鬼主播靖秩,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼盆偿,長吁一口氣:“原來是場噩夢啊……” “哼事扭!你這毒婦竟也來了求橄?” 一聲冷哼從身側(cè)響起罐农,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎气筋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搀矫,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了逝薪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片董济。...
    茶點(diǎn)故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡欢搜,死狀恐怖炒瘟,靈堂內(nèi)的尸體忽然破棺而出疮装,到底是詐尸還是另有隱情廓推,我是刑警寧澤呻纹,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站太闺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏钞澳。R本人自食惡果不足惜轧粟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望履腋。 院中可真熱鬧,春花似錦延旧、人聲如沸迁沫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迫摔。三九已至句占,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間擂啥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工至扰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人翎猛。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓懊缺,卻偏偏與公主長得像遗座,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容