亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 邏輯算法 > 正文

算法系列15天速成 第六天 五大經典查找【下】

2024-09-08 23:18:39
字體:
來源:轉載
供稿:網友
大家是否感覺到,樹在數據結構中大行其道,什么領域都要沾一沾,碰一碰。
就拿我們前幾天學過的排序就用到了堆和今天講的”二叉排序樹“,所以偏激的說,掌握的樹你就是牛人了。

今天就聊聊這個”五大經典查找“中的最后一個”二叉排序樹“。

1. 概念:
     <1> 其實很簡單,若根節點有左子樹,則左子樹的所有節點都比根節點小。
                             若根節點有右子樹,則右子樹的所有節點都比根節點大。
     <2> 如圖就是一個”二叉排序樹“,然后對照概念一比較比較。

         

2.實際操作:

    我們都知道,對一個東西進行操作,無非就是增刪查改,接下來我們就聊聊其中的基本操作。

    <1> 插入:相信大家對“排序樹”的概念都清楚了吧,那么插入的原理就很簡單了。

                    比如說我們插入一個20到這棵樹中。

                                 首先:20跟50比,發現20是老小,不得已,得要歸結到50的左子樹中去比較。

                                 然后:20跟30比,發現20還是老小。

                              再然后:20跟10比,發現自己是老大,隨即插入到10的右子樹中。

                                 最后: 效果呈現圖如下:

               

               

    <2>查找:相信懂得了插入,查找就跟容易理解了。

                    就拿上面一幅圖來說,比如我想找到節點10.

                                     首先:10跟50比,發現10是老小,則在50的左子樹中找。

                                     然后:10跟30比,發現還是老小,則在30的左子樹中找。

                                  再然后:  10跟10比,發現一樣,然后就返回找到的信號。

                

     <3>刪除:刪除節點在樹中還是比較麻煩的,主要有三種情況。

                   《1》 刪除的是“葉節點20“,這種情況還是比較簡單的,刪除20不會破壞樹的結構。如圖:

                    

                      

                   《2》刪除”單孩子節點90“,這個情況相比第一種要麻煩一點點,需要把他的孩子頂上去。

                    

                       

                   《3》刪除“左右孩子都有的節點50”,這個讓我在代碼編寫上糾結了好長時間,問題很直白,

                           我把50刪掉了,誰頂上去了問題,是左孩子呢?還是右孩子呢?還是另有蹊蹺?這里我就

                           坦白吧,不知道大家可否知道“二叉樹”的中序遍歷,不過這個我會在后面講的,現在可以當

                          公式記住吧,就是找到右節點的左子樹最左孩子。

                          比如:首先 找到50的右孩子70。

                                  然后  找到70的最左孩子,發現沒有,則返回自己。

                                  最后  原始圖和最終圖如下。 

  

 

3.說了這么多,上代碼說話。

復制代碼 代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace TreeSearch
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> list = new List<int>() { 50, 30, 70, 10, 40, 90, 80 };

            //創建二叉遍歷樹
            BSTree bsTree = CreateBST(list);

            Console.Write("中序遍歷的原始數據:");

            //中序遍歷
            LDR_BST(bsTree);

            Console.WriteLine("/n---------------------------------------------------------------------------n");

            //查找一個節點
            Console.WriteLine("/n10在二叉樹中是否包含:" + SearchBST(bsTree, 10));

            Console.WriteLine("/n---------------------------------------------------------------------------n");

            bool isExcute = false;

            //插入一個節點
            InsertBST(bsTree, 20, ref isExcute);

            Console.WriteLine("/n20插入到二叉樹,中序遍歷后:");

            //中序遍歷
            LDR_BST(bsTree);

            Console.WriteLine("/n---------------------------------------------------------------------------n");

            Console.Write("刪除葉子節點 20, /n中序遍歷后:");

            //刪除一個節點(葉子節點)
            DeleteBST(ref bsTree, 20);

            //再次中序遍歷
            LDR_BST(bsTree);

            Console.WriteLine("/n****************************************************************************/n");

            Console.WriteLine("刪除單孩子節點 90, /n中序遍歷后:");

            //刪除單孩子節點
            DeleteBST(ref bsTree, 90);

            //再次中序遍歷
            LDR_BST(bsTree);

            Console.WriteLine("/n****************************************************************************/n");

            Console.WriteLine("刪除根節點 50, /n中序遍歷后:");
            //刪除根節點
            DeleteBST(ref bsTree, 50);

            LDR_BST(bsTree);

        }

        ///<summary>
/// 定義一個二叉排序樹結構
///</summary>
        public class BSTree
        {
            public int data;
            public BSTree left;
            public BSTree right;
        }

        ///<summary>
/// 二叉排序樹的插入操作
///</summary>
///<param name="bsTree">排序樹</param>
///<param name="key">插入數</param>
///<param name="isExcute">是否執行了if語句</param>
        static void InsertBST(BSTree bsTree, int key, ref bool isExcute)
        {
            if (bsTree == null)
                return;

            //如果父節點大于key,則遍歷左子樹
            if (bsTree.data > key)
                InsertBST(bsTree.left, key, ref isExcute);
            else
                InsertBST(bsTree.right, key, ref isExcute);

            if (!isExcute)
            {
                //構建當前節點
                BSTree current = new BSTree()
                  {
                      data = key,
                      left = null,
                      right = null
                  };

                //插入到父節點的當前元素
                if (bsTree.data > key)
                    bsTree.left = current;
                else
                    bsTree.right = current;

                isExcute = true;
            }

        }

        ///<summary>
/// 創建二叉排序樹
///</summary>
///<param name="list"></param>
        static BSTree CreateBST(List<int> list)
        {
            //構建BST中的根節點
            BSTree bsTree = new BSTree()
            {
                data = list[0],
                left = null,
                right = null
            };

            for (int i = 1; i < list.Count; i++)
            {
                bool isExcute = false;
                InsertBST(bsTree, list[i], ref isExcute);
            }
            return bsTree;
        }

        ///<summary>
/// 在排序二叉樹中搜索指定節點
///</summary>
///<param name="bsTree"></param>
///<param name="key"></param>
///<returns></returns>
        static bool SearchBST(BSTree bsTree, int key)
        {
            //如果bsTree為空,說明已經遍歷到頭了
            if (bsTree == null)
                return false;

            if (bsTree.data == key)
                return true;

            if (bsTree.data > key)
                return SearchBST(bsTree.left, key);
            else
                return SearchBST(bsTree.right, key);
        }

        ///<summary>
/// 中序遍歷二叉排序樹
///</summary>
///<param name="bsTree"></param>
///<returns></returns>
        static void LDR_BST(BSTree bsTree)
        {
            if (bsTree != null)
            {
                //遍歷左子樹
                LDR_BST(bsTree.left);

                //輸入節點數據
                Console.Write(bsTree.data + "");

                //遍歷右子樹
                LDR_BST(bsTree.right);
            }
        }

        ///<summary>
/// 刪除二叉排序樹中指定key節點
///</summary>
///<param name="bsTree"></param>
///<param name="key"></param>
        static void DeleteBST(ref BSTree bsTree, int key)
        {
            if (bsTree == null)
                return;

            if (bsTree.data == key)
            {
                //第一種情況:葉子節點
                if (bsTree.left == null && bsTree.right == null)
                {
                    bsTree = null;
                    return;
                }
                //第二種情況:左子樹不為空
                if (bsTree.left != null && bsTree.right == null)
                {
                    bsTree = bsTree.left;
                    return;
                }
                //第三種情況,右子樹不為空
                if (bsTree.left == null && bsTree.right != null)
                {
                    bsTree = bsTree.right;
                    return;
                }
                //第四種情況,左右子樹都不為空
                if (bsTree.left != null && bsTree.right != null)
                {
                    var node = bsTree.right;

                    //找到右子樹中的最左節點
                    while (node.left != null)
                    {
                        //遍歷它的左子樹
                        node = node.left;
                    }

                    //交換左右孩子
                    node.left = bsTree.left;

                    //判斷是真正的葉子節點還是空左孩子的父節點
                    if (node.right == null)
                    {
                        //刪除掉右子樹最左節點
                        DeleteBST(ref bsTree, node.data);

                        node.right = bsTree.right;
                    }
                    //重新賦值一下
                    bsTree = node;

                }
            }

            if (bsTree.data > key)
            {
                DeleteBST(ref bsTree.left, key);
            }
            else
            {
                DeleteBST(ref bsTree.right, key);
            }
        }
    }
}

運行結果:

值的注意的是:二叉排序樹同樣采用“空間換時間”的做法。

突然發現,二叉排序樹的中序遍歷同樣可以排序數組,呵呵,不錯!

PS:  插入操作:O(LogN)。
       刪除操作:O(LogN)。
       查找操作:O(LogN)。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久精品成人欧美大片古装| 亚洲无亚洲人成网站77777| 亚洲人成网7777777国产| 国产精品99久久久久久人| 黑人狂躁日本妞一区二区三区| 亚洲2020天天堂在线观看| 欧美在线视频免费| 久热精品视频在线观看| 人体精品一二三区| 欧美性受xxx| 国产精品久久不能| 欧美精品一区二区三区国产精品| 欧美特黄级在线| 亚洲国产高清福利视频| 国产成人avxxxxx在线看| 日韩免费观看在线观看| 久久国产天堂福利天堂| 日韩国产欧美精品一区二区三区| 91久久精品在线| 亚洲男女性事视频| 日韩欧美在线中文字幕| 伊人一区二区三区久久精品| 日韩精品亚洲精品| 4p变态网欧美系列| 日本91av在线播放| 久久久www成人免费精品张筱雨| 欧美高清视频在线观看| 91在线无精精品一区二区| 久久精品电影网站| 亚洲国产精品久久久| 欧美电影在线观看高清| 亚洲日本成人女熟在线观看| 亚洲国产精品电影| 日韩极品精品视频免费观看| 伊人久久免费视频| 日韩激情视频在线播放| 深夜福利一区二区| 九九热最新视频//这里只有精品| 在线观看国产精品91| 欧美在线一级视频| 欧美激情一区二区久久久| 国产精品久久久一区| 日本欧美中文字幕| 一本一本久久a久久精品综合小说| 91欧美日韩一区| 在线午夜精品自拍| 色狠狠久久aa北条麻妃| 日韩一区二区久久久| 久久视频免费在线播放| 亚洲国产精久久久久久| 久久久久久国产精品美女| 日本a级片电影一区二区| 国产精品黄色av| 亚洲国产精品悠悠久久琪琪| 日韩欧美成人精品| 91av中文字幕| 亚洲美女www午夜| 日韩视频―中文字幕| 欧美成人精品在线观看| 国产精品久久77777| 日本精品久久中文字幕佐佐木| 2020久久国产精品| 日本人成精品视频在线| 久久这里只有精品视频首页| 亚洲激情免费观看| 91精品久久久久久久久久| 91精品国产综合久久久久久久久| 亚洲va久久久噜噜噜久久天堂| 日韩在线一区二区三区免费视频| 高清亚洲成在人网站天堂| 国产精品jizz在线观看麻豆| 欧美亚洲另类制服自拍| 韩国一区二区电影| 九九热在线精品视频| 77777少妇光屁股久久一区| 91大神福利视频在线| 国产精品国产亚洲伊人久久| 亚洲天堂av女优| 久久国产精品99国产精| 久久国产精品久久久久| 国产精品亚发布| 日韩欧美中文字幕在线播放| 国产精品久久久久久亚洲调教| 97久久超碰福利国产精品…| 九九热这里只有精品6| 国产精品视频播放| 欧美激情视频免费观看| 亚洲香蕉av在线一区二区三区| 日韩精品在线观| 欧美最猛性xxxxx亚洲精品| 欧美巨乳在线观看| 日韩在线中文字| 欧美亚洲国产另类| 久久久久久欧美| 欧美激情成人在线视频| 色综合久久天天综线观看| 97热在线精品视频在线观看| 欧美主播福利视频| 亚洲美女性生活视频| 国产91精品久久久久久久| 久热精品视频在线观看一区| 黄网动漫久久久| 国语自产精品视频在线看| 欧美人在线视频| 欧美老女人xx| 欧美日韩另类在线| 国产成人精品免高潮在线观看| 久久韩剧网电视剧| 久久韩剧网电视剧| 午夜精品久久17c| 视频在线一区二区| 一区二区三区四区在线观看视频| 欧美成人性色生活仑片| 国产成人精品a视频一区www| 国产精品久久精品| 精品一区电影国产| 亚洲风情亚aⅴ在线发布| 欧美另类xxx| 欧美另类在线播放| 中文在线不卡视频| 日韩在线播放一区| 欧美电影免费观看网站| 孩xxxx性bbbb欧美| 97色在线观看| 一本大道香蕉久在线播放29| 色哟哟亚洲精品一区二区| 国产精品一区二区久久精品| 国产精品久久久久久久久久免费| 日韩在线小视频| 日韩中文字幕在线视频播放| 亚洲欧美中文在线视频| 亚洲色图13p| 日韩精品极品视频| 久久久视频精品| 国产精品偷伦视频免费观看国产| 8x拔播拔播x8国产精品| 国产美女精品视频免费观看| 51久久精品夜色国产麻豆| 国内精品久久久久| 亚洲电影中文字幕| 亚洲精美色品网站| 孩xxxx性bbbb欧美| 欧美国产精品va在线观看| 在线亚洲男人天堂| 亚洲精品视频在线观看视频| 久久久久久有精品国产| 国产盗摄xxxx视频xxx69| 最近中文字幕2019免费| 综合136福利视频在线| 日韩免费视频在线观看| 久久久久久久久亚洲| 国产欧美婷婷中文| 亚洲japanese制服美女| 国产精品美女主播在线观看纯欲| 中文字幕精品视频| 日本19禁啪啪免费观看www| 亚洲国产精品人久久电影| 亚洲第一综合天堂另类专| 欧美日韩亚洲系列| 最近日韩中文字幕中文| 九九热精品在线| 国产欧美日韩丝袜精品一区| 国产亚洲一区二区在线| 一个人看的www久久|