日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

查找树(二级)

發(fā)布時(shí)間:2024/4/13 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 查找树(二级) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

樹的查找,大家仔細(xì)看這個(gè)名詞,看這個(gè)單詞,叫查找樹,查找樹怎么理解,誰是動(dòng)詞誰是名詞,主語是誰,那就是我要去查找這棵樹,查找是動(dòng)詞,樹是賓語,你又可以理解這是個(gè)名詞,樹的名字叫查找樹,樹是主語,不是二叉樹,不是三叉樹,是查找樹,是這樣的,有一種概念叫二叉查找樹,他也叫二叉搜索樹,查找搜索吧,那不是一個(gè)含義嗎,但是他還叫二叉排序樹,那查找和排序是兩個(gè)截然不同的內(nèi)容,這個(gè)樹怎么可能既是排序樹又是查找樹呢,兩個(gè)原因,一個(gè)原因,查找是search,排序是sort,首字母都是S,所以叫BST(binargy search tree),但是這個(gè)肯定不是最主要的原因,我們找一個(gè)以S開始的單詞,多的去了,不能隨便叫,最主要這棵樹既可以用來查找,并且他本身也是有序的,當(dāng)往里面添加元素的話,它會(huì)自動(dòng)變成有序的,按照某種規(guī)則來排列的,我們這幾個(gè)樹都是二叉查找樹,或者叫二叉排序樹,大家看一下他們有什么特點(diǎn),我來跟大家說一下,看這一個(gè),首先它是一棵二叉樹,這個(gè)是不是根,然后左邊所有的節(jié)點(diǎn),都小于8,發(fā)現(xiàn)沒,右邊所有的元素都大于8,這是根,還是遞歸的定義,這又是一個(gè)根,左子樹小于根,右子樹大于根,里面這個(gè)樹根是4,左是4,右是7,是不是還是滿足,然后10是根,左邊沒有,右邊是他,那根是14,這是13,左小于根,如果我們這個(gè)時(shí)候來了一個(gè)數(shù),它是15,你覺得他應(yīng)該加在哪兒,我們是不是可以加到這個(gè)位置,加個(gè)15,這就叫二叉查找樹,其他的也是的,7都小于7,都大于7,遞歸定義,3大于3,小于3,遞歸定義的,一直到葉子節(jié)點(diǎn),這紅色是不是也是二叉查找樹,為什么啊,根,右邊全部大于A,根,右邊全部大于B,實(shí)際上他也是一個(gè)二叉查找樹,或者是一顆空樹,或者具有以下的性質(zhì)1. 如果他的左子樹不為空,左子樹的所有節(jié)點(diǎn)都小于根2. 如果他的右子樹所有的節(jié)點(diǎn)不為空,節(jié)點(diǎn)也都大于根節(jié)點(diǎn),3. 他的左右節(jié)點(diǎn)也是二叉排序樹,是這么來的這是我們所說的一個(gè)內(nèi)容 注意;大家想一下,滿足這個(gè)條件就怎么了,滿足這個(gè)條件想一下,如果我們對(duì)于二叉樹進(jìn)行中序遍歷,什么叫中序遍歷,先遍歷左邊的,先遍歷小的,再遍歷根,再遍歷右邊的,因?yàn)槲覀儎偛攀嵌鏄涞奶攸c(diǎn),我們對(duì)他中序遍歷,先左,再根,后右,那一部分都是先左再根后右,二叉排序樹得到的中序遍歷得到的結(jié)果就是一個(gè)有序的數(shù)列,這是一個(gè),他為什么叫做二叉排序樹,對(duì)他進(jìn)行中序遍歷他就是有序的,他為什么叫二叉查找樹,當(dāng)然了,大家想一下,我要在這里找一個(gè)樹16,我要怎么找,肯定是要從根開始吧,6小于8,右邊就全部排除了,就不可能在這兒了,6再和3比,左邊是不是又全部排除了,這個(gè)和二分法折半折半查找是不是差不多啊,一下子就可以拋棄一半了,這是我們所說的一個(gè)內(nèi)容,最終和6比,找到了,我們要找一個(gè)5怎么找,先和8比,小于8,再和3比,再和6比,5是不是小于6啊,再和4比,大于4,再和右邊找,右邊有沒有,沒有,這說明什么,這說明不存在,所以查找的話,這棵樹是怎么構(gòu)建的,大家想一下,我們最早講二叉樹的時(shí)候,我們是怎么來構(gòu)建這棵樹的,看下我的代碼,我們的二叉樹是不是一個(gè)一個(gè)節(jié)點(diǎn)連接起來的,為什么,因?yàn)橹暗亩鏄錄]有規(guī)律,現(xiàn)在不用了,因?yàn)樗呀?jīng)有規(guī)律了,有規(guī)律了怎么辦,我們以這棵樹為例,我現(xiàn)在有一個(gè)值是9,因?yàn)檫@棵樹已經(jīng)構(gòu)建好了,我現(xiàn)在有個(gè)9,你給我加到這棵樹里面,你只要把這棵樹的根,同時(shí)這個(gè)8值給了,就可以把這個(gè)9加到指定的位置,為什么,因?yàn)樗怯刑攸c(diǎn)的嗎,因?yàn)樗怯幸?guī)律的,9和8比那應(yīng)該是往右邊放,他和10比應(yīng)該往左邊放,左邊是空白的,那好,就是你了,9是不是加到這兒了,這個(gè)二叉查找樹就涉及到了如何添加,可以通過算法來添加的,如何查找,查找是不是相當(dāng)于折半查找啊,還有一個(gè)如何排序,中序遍歷他就是有序的,還有一個(gè)如何更新,如何修改,我們先做一個(gè)如何刪除,如何刪除呢,這個(gè)刪除和更新就稍微復(fù)雜一點(diǎn),一堆完整的算法,叫我們來實(shí)現(xiàn)這一個(gè),比如我們要把這個(gè)10刪除了,刪除完之后還得要保證它是一棵二叉查找樹,那我們?cè)趺崔k,你要是把10刪除了,那8指向14不就行了,你8指向14,9怎么辦啊,9加到這兒?jiǎn)?這事怎么辦,我把9移除了,9放到10這個(gè)位置,9放到這兒,8連9,9再連14,他還是滿足這個(gè)規(guī)律,但是他一共有多種情況,都是有完整的算法的,那更新的時(shí)候呢,我要把6更新成15,哪能隨便更新,你更新還叫二叉查找樹嗎,就不是了,對(duì)于二叉查找樹來說,他有一套完整的實(shí)現(xiàn)算法,以及代碼實(shí)現(xiàn),這個(gè)問題該怎么解決,這個(gè)完整問題解決思路,這是我們講的二叉查找樹和二叉排序樹,二叉查找樹的好處我已經(jīng)跟大家說了,但是他有沒有缺點(diǎn),有,怎么又缺點(diǎn),比如說,我現(xiàn)在給了大家?guī)讉€(gè)數(shù),1,2,3,4,5,總共5個(gè)數(shù),但是這個(gè)數(shù)我以不同的順序來給,3,2,5,4,1,是不同的順序,我們按照不同的順序來構(gòu)建一個(gè)二叉查找樹,先來一個(gè)3來做根了,它是第一個(gè),那2怎么辦,2應(yīng)該放到這兒,5怎么辦,5應(yīng)該放到這兒,再來一個(gè)4,4大于3小于5,再來個(gè)1,1是不是應(yīng)該到這兒了,那這兒我如果再跟一個(gè)6呢,3,5,6,總體來看這棵樹比較平均的,左右是不是比較平衡的,左邊的節(jié)點(diǎn)和右邊的節(jié)點(diǎn)是不是差不多的,但是如果你是這么來給呢,1,2,3,4,5,6,按照這個(gè)順序來給,那就變成什么樣子了,先來個(gè)1,再來個(gè)2,再來個(gè)3,再來個(gè)4,再來個(gè)5,再來個(gè)6,這哪還是二叉樹啊,這純粹就是一個(gè)線性表,你覺得是這種方式好,還是這種方式好,哪種方式好啊,當(dāng)然是這種方式好啊,比如說,我要查找6的話,每層數(shù)量就加倍,這個(gè)你相當(dāng)于要找?guī)状?相當(dāng)于你在這種極端的情況下,你要找一個(gè)數(shù)的話,時(shí)間復(fù)雜度是O(n),因?yàn)槟阋欢ㄊ且粋€(gè)線性表的,花的時(shí)間是很多的,但是在這個(gè)里面呢,這個(gè)就相當(dāng)于log2 n,因?yàn)槊看卧霰?越往下就比上一層增加2,如果滿的話,所以這個(gè)效率是可以大大提升的,雖然都是二叉查找樹,都是左邊小于根,根小于右子樹,但是如果排列規(guī)則不一樣的話,這是一種極端的,完全平衡的,這是一種完全不平衡的,我們希望得到哪一種啊,我希望得到這一種,為什么,這一種對(duì)什么有好處,對(duì)查找有好處,你添加的時(shí)候也好添加,這是一個(gè) 那我們?cè)谙逻呍僦v一個(gè)名詞,這個(gè)詞叫平衡二叉樹,平衡的什么叫平衡二叉樹?他首先是一個(gè)二叉查找樹,這什么意思啊,左邊小于根,根小于右邊,并且他還是平衡的,一般我們叫平衡,別人是自平衡的,是這么來的,叫AVL樹,所以稱之為AVL算法,按照這個(gè)算法的叫AVL樹,他怎么了,這就是一顆平衡二叉樹,他為什么是一顆平衡二叉樹啊,為什么他是平衡的,這是一個(gè)根,右邊分幾層,右邊兩層吧,左邊幾層,左邊3層,做多相差不能差一層,然后你還是遞歸的,這是一個(gè)根吧,左邊幾層,左邊兩層,這是幾層,1層,7又是根,左邊幾層,1層,右邊幾層啊,1層,左邊右邊,左子樹右子樹他們的高度之差最多差一層,那基本上就相同了,最后一層有可能是不滿的,可能是不滿的,這就是循環(huán)二叉樹,那這個(gè)平衡二叉樹怎么辦呢,他就可以保證每層的節(jié)點(diǎn)盡可能的多一些,這樣來說是比較平衡的,是比較平均的,不會(huì)一會(huì)特別多,一會(huì)特別少,最大的好處是什么啊,就是為了減少二叉查找樹的層次,平衡不就是每層節(jié)點(diǎn)多,層數(shù)就少了嗎,他就不是可以避免出現(xiàn)這種情況的嗎,這是我們所說的一個(gè)內(nèi)容,從而來提高查找速度,你告訴我上面的是不是二叉平衡樹,這個(gè)是不是,你仔細(xì)看哦,這是幾層,3層,這是3層,這是幾層,1層,右邊2層,根兩層,2層,這個(gè)是不是,根幾層,3層,右子樹3層,這沒有問題,10左邊0層,右邊2層,不是二叉平衡樹,怎么就是了,比如他把10寫成13,本來是10,把10放到這兒,如果這么一移的話,知道我們所說的一個(gè)意思,那你要這么來說的話,這個(gè)肯定不是平衡的,那是絕對(duì)不平衡的,那我們下邊再來做一個(gè)操作吧,[1,2,3,4,5,6],我就按照這個(gè)順序給你,如果底層是一棵平衡樹的話,這個(gè)該怎么來構(gòu)建,第一個(gè)作為根,這是平衡的吧,就一個(gè)節(jié)點(diǎn),他左邊是0,右邊也是0,再加上一個(gè)2,平衡嗎,為什么平衡,左邊是0,右邊是1高度,是平衡的,再加一個(gè)3,再加就不平衡了,算法可以保證,它會(huì)自平衡,怎么就自平衡了,根不是1嗎,我想拿2做根,怎么拿2做根啊,2的左孩子不是沒有嗎,讓2的左孩子變成1,把2的左孩子指向1,這部分就不存在了,然后這再加上一個(gè)3,然后他就又平衡了,那我們?cè)偌?呢,我們?cè)龠@再加一個(gè)4,這樹還是平衡的,但是如果你要是再加一個(gè)5的話,又不平衡了,怎么辦,大家如果感興趣可以查詢更多的資料來看一下,它是有一套完整解決方案的,它會(huì)一直維持樹的平衡,保證左右是平衡的,可以保證以后查詢的效率,這是我們所說的,二叉平衡樹有什么好處,提高查詢的速度,減少查詢次數(shù),是這么來的,二叉查找樹的特點(diǎn)在于什么,它是有規(guī)律的,這么一來呢,我們不便于添加,便于排序,是這么來的,而對(duì)于平衡二叉樹來說,便于查找再往下看,下一種樹叫紅黑樹,紅黑樹什么意思啊,首先記住它也是一種平衡二叉樹,有人說他也是一種平衡二叉樹,我們前面不是也有平衡二叉樹嗎,對(duì)啊,平衡二叉樹你要是想實(shí)現(xiàn)這個(gè),特點(diǎn)是固定的,左右平衡,但是實(shí)際上方案可以有很多種,實(shí)現(xiàn)方案保證他左右平衡的,我們一般說的平衡二叉樹呢,叫AVL算法,是這種算法來保證平衡的,但是后來又出現(xiàn)了一種算法,后來又出現(xiàn)一種算法叫紅黑算法唄,他也可以保證這棵樹也是平衡的,那這就是一顆最簡(jiǎn)單的紅黑樹的模型圖,首先我們看到他是平衡的,他把他的節(jié)點(diǎn)分別標(biāo)記紅色和黑色,并且紅色和黑色基本上都有交替出現(xiàn)1. 比如每個(gè)節(jié)點(diǎn)不是黑色就是紅色2. 根節(jié)點(diǎn)第一個(gè)是黑色的3. 每個(gè)葉子節(jié)點(diǎn)他保證是黑色的,但是你要知道他的葉子節(jié)點(diǎn)不是10,也不是50,而是他的空的左子樹和空的右子樹,4. 這里面是這么來標(biāo)記他的葉子節(jié)點(diǎn)的,總之它是通過一系列的規(guī)則來保證他最終的紅黑樹呢它是平衡的 紅黑樹的使用還是很廣泛的,像我們JAVA里面的TreeSet,TreeMap底層采用的都是紅黑樹,底層采用的都是紅黑樹,這個(gè)大家要明白,意味著我們JAVA里面的TreeSet是紅黑樹,這說明什么,大家想一下,第一個(gè)我們講TreeSet,第一個(gè)它是有序的,是不是說過它是有序的,他怎么成有序的了,你說TreeSet底層是紅黑樹就是有序的嗎,對(duì)啊紅黑樹首先是一個(gè)查找樹,對(duì)任何樹進(jìn)行中序遍歷得到的就是有序了,他就是這么來實(shí)現(xiàn)的,另外他既然是紅黑樹,不管我們按照什么順序加這個(gè)數(shù)據(jù),最終它會(huì)出現(xiàn)這個(gè)極端的情況嗎,不會(huì),所以我們紅黑樹的查找效率,也是比較高的,多少啊,就是log2 n,就是我們說的一個(gè)平衡樹,一種是最早的AVL樹,還有一個(gè)叫紅黑樹,記住它是左右平衡的,TreeSet使用的就是紅黑樹我們?cè)僦v一個(gè)B樹,B樹叫什么意思,Balanced Tree,B就是這個(gè)單詞唄Balanced,balanced什么意思,就是平衡,這個(gè)叫平衡樹,上面這個(gè)叫平衡二叉樹,這有什么區(qū)別嗎,有,這個(gè)是不是左右平衡了,但是他最多分兩個(gè)叉,那我最多讓他分三個(gè)叉或四個(gè)叉呢,這樣行不行呢,每個(gè)節(jié)點(diǎn)可以分更多的叉,你還是每個(gè)節(jié)點(diǎn)都平衡的,可以嗎,可以的,這就叫平衡樹,大家來看,這就叫一個(gè)平衡樹,他最多分了3個(gè)叉,他不是兩個(gè)叉,是分了3個(gè)叉,那么同一層就可以存更多的數(shù)據(jù)了,同樣的數(shù)據(jù)就可以有更少的層次了,他就可以有更少的層次了,這個(gè)也是有的,B樹他就叫平衡樹,它是多叉的,多叉的他就可以降低樹的深度,從而減少查詢的次數(shù),提高查詢的效率,這個(gè)一般是用在什么地方的,這個(gè)一般是用來讀硬盤上數(shù)據(jù)的時(shí)候,比如讀我們數(shù)據(jù)庫里面的數(shù)據(jù),索引的時(shí)候就可以用這個(gè)來做,比如硬盤里面的數(shù)據(jù)特別多,我們不能一次性的讀到內(nèi)存里面,內(nèi)存里面放不下,該怎么辦,就可以按照這種方式來,讀出一部分來,這是兩個(gè)節(jié)點(diǎn)的資料,讀了這兩個(gè)之后呢,比如我要讀的是9,我要找9這個(gè)數(shù),所有的數(shù)據(jù)不可能全部都讀到內(nèi)存里面,因?yàn)楸容^大,那我就采用這種平衡樹來存儲(chǔ),那我就先讀這一層,或者先把這兩層讀出來,容量是比較少的,我找的是9,你不需要把所有的數(shù)據(jù)都讀出來再找9,那效率會(huì)比較低,我先把這兩個(gè)讀出來,9它是有序的,你看他還是保證左邊小于中間,中間小于右邊,還是滿足我們剛才的規(guī)律的,你看這是17,這是什么意思,這有兩個(gè)數(shù),下邊有3個(gè)指針,我很奇怪,為什么兩個(gè)數(shù)下面有3個(gè)指針啊,因?yàn)檫@個(gè)指針指向的是小于17的,那這個(gè)指針指向的是大于35的,那中間這個(gè)指針指向的是17到35之間的,兩個(gè)數(shù)正好把整個(gè)樹分成3個(gè)區(qū)塊,同樣2個(gè)節(jié)點(diǎn)3個(gè)指針,這邊是小于8的,這邊是大于12的,當(dāng)然大于12是有要求的,那這個(gè)指針指向的是8到12中間的,那大家想一下,我想在這里面找9,該怎么找,先和17比,小于17,那意味著什么啊,這一塊,這一塊一下子排除了,因?yàn)樗瞧胶獾?所以他不是排除了二分之一,他排除了三分之二,這邊再來,拿著這個(gè)9和8進(jìn)行比較,結(jié)果發(fā)現(xiàn)他大于8,大于8把8指向的排除了,然后再和12比,那不用說了,那就是在這兒,9找到了,就這么來就可以了,這是我們所說的B樹,他和我們的二叉平衡樹的區(qū)別,B樹首先是平衡的,他只不過是分了更多的叉,然后呢我們?cè)倏戳硗庖粋€(gè) B+樹:B+樹什么意思,B+樹是這么來的,我們看上面的樹,如果我想找17呢,如果我想找12呢,17是不是一下子就找到了,找12呢,是不是也能找到找13是不是在這兒呢,就是我們找的數(shù)據(jù)啊,他可能在第一層,也可能在第二層,是不是也可能在第三層,各層都是有數(shù)據(jù)的,各層都有數(shù)據(jù)那B+樹他做了一下變化,他是怎么變的呢,他變成什么樣子了,B+樹的一個(gè)變化,他變成這個(gè)樣子了,什么樣子啊,我們畫一條線,所有的數(shù)據(jù)都在最下面一層,你看5,28,65,是不是也有啊,就是真正的數(shù)據(jù)全部都在下一層,我們之前是每一層都存數(shù)據(jù)的,現(xiàn)在不是了,現(xiàn)在是所有的數(shù)據(jù)都放在這,都放在最下面這一層,我上面只是索引,上面的是索引,這是完整的索引數(shù)據(jù),這個(gè)時(shí)候怎么辦呢,5,28,65,都對(duì)應(yīng)指針的,5如果往左邊走,那就是包括5的,因?yàn)檫@個(gè)5只是索引的數(shù)據(jù),不是真正的數(shù)據(jù),真正的數(shù)據(jù)在這兒,有幾個(gè)數(shù)就有幾個(gè)指針,一一對(duì)應(yīng)的,我們找一個(gè)數(shù),我們找一個(gè)5,怎么找,5找到了沒有,5,沒找到,哪兒找到了,真正的數(shù)據(jù)在這兒呢,按照P1這個(gè)指針,往下來走,還是5啊,再往下走,這個(gè)指針找到這兒,真正的數(shù)據(jù)它是在這兒,他在這兒已經(jīng)找到5了,那他這個(gè)怎么辦,就在這兒不行吧,如果整個(gè)5代表一個(gè)學(xué)生的話,5要是代表一個(gè)學(xué)生的話,這個(gè)地方存的也許是一個(gè)完整的學(xué)生,而這兒存的可能是一個(gè)學(xué)生的分?jǐn)?shù),或者學(xué)號(hào)啊,或者是年紀(jì)啊,這些排序的字段,是這么來的,這么就找到了,我們就再來找一個(gè)唄,再來找一個(gè)40吧,告訴我40該怎么找,從上面的一級(jí)索引,2級(jí)索引,數(shù)據(jù)是不是在這兒呢,我要找的是40,怎么辦,如果要是沒有我們這個(gè)索引的話,怎么找啊,是不是要逐個(gè)的查找啊,這個(gè)效率太低了吧,但是有了這個(gè)索引之后,最多也沒有幾次,為什么最多也沒有幾次,找40,先和5比,大于5,和28比,大于28,和65比,小于65,那就按照P2來找就可以了,一下子把左邊的排除了,一下子把右邊的也排除了,再來找40,和28比,大于28,那就不用考慮了,和35比,這下面都是大于35的,但是小于56了,那再和56比,小于56,這里顯示的是35到56之間的,和35比,不是,和38比,不是,和50比,不是,都已經(jīng)大于40了,不用找了,干什么啊,不存在,所以他上面這幾級(jí)啦,是可以快速給你分到分支的,可以排除大量數(shù)據(jù),一下子跳過大量的數(shù)據(jù),提高效率,那到最后一塊就變成線性查找,一個(gè)一個(gè)找,但是數(shù)據(jù)是比較少的,這就是我們所說的B+樹,那么大家記住了,我們后面馬上就要學(xué)數(shù)據(jù)庫,數(shù)據(jù)庫的索引就是采用的B+樹,數(shù)據(jù)庫的索引就是采用的B+樹,可以分多個(gè)叉,但是你發(fā)現(xiàn)這個(gè)叉級(jí)別都是一樣層次都是一樣的,最后我們?cè)賮砜匆粋€(gè)樹B*樹:B*樹兩個(gè)再對(duì)比一下唄,你覺得這兩個(gè)有什么區(qū)別,有區(qū)別嗎,有什么區(qū)別嗎,B*樹的索引之間又相連了,這里面有沒有啊,它是沒有的,它是B+樹的變體,在B+樹的非根和非葉子節(jié)點(diǎn),除了第一層和最后一層,中間各層之間,兄弟之間,是可以有指針的,這就是我們給大家講的相關(guān)的查找樹的相關(guān)觀念總結(jié)一下,我們一共講了幾個(gè)概念:第一個(gè)叫二叉查找樹,他有什么特點(diǎn),左邊小于根,根小于右邊,他有什么好處,便于查找,便于排序,為什么還要出一個(gè)二叉平衡樹,一看這個(gè)就明白了,這是一個(gè)二叉查找樹,但是左右不平衡,結(jié)果都變成了線性表了,查找特別低效,所以我們希望他左右平衡,那我們要實(shí)現(xiàn)這個(gè)平衡二叉樹,或者二叉平衡樹,實(shí)現(xiàn)的方式有很多,比如AVL樹,或者還有一種采用紅黑算法實(shí)現(xiàn)的紅黑樹,這三種都是二叉樹,再往下就是B樹,B+樹,B*樹,B樹什么意思啊,B樹就是分了多個(gè)叉,B+樹呢,數(shù)據(jù)全部在最底層,B*樹是索引之間也可以有關(guān)聯(lián)

?

總結(jié)

以上是生活随笔為你收集整理的查找树(二级)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。