1. 程式人生 > >JAVA-初步認識-常用對象API(集合框架-treeset集合-二叉樹)

JAVA-初步認識-常用對象API(集合框架-treeset集合-二叉樹)

.com 技術 次數 style 引用 數據 最值 san 二叉樹

一.

treeset集合可以對其中的元素進行排序,它有兩種排序方法,現在我們想知道它底層是什麽結構,它是怎麽確定元素位置的?它是有原因的,而且它這種結構對於排序而言,效率很高。

一說到排序,之前說到選擇冒泡。選擇冒泡對於比較次數而言,比較多一些,因為是轉著圈在比。對於treeset而言,有個比較好的地方就是

技術分享圖片

將例子中的元素按照年齡排序,演示一遍它是怎麽存放的。

存zhangsan,28的時候,就在容器中搞了一個zhangsan,28。容器中只有一個元素,不進行比較。緊跟著再來個lisi,21,lisi要調集自己的compareto和zhangsan碰一下。lisi和zhangsan一比,發現比28小,返回一個負數,緊跟著放在了28的左邊。和28比完只有兩種情況,要麽是大,要麽是小。有人說,不是還有相等的情況麽,相等是進不來的。接著zhouqi來了,和28一比,比28還要大,它和21不需要再進行相比了,它直接放置在28的右邊。接著25來了,和28比,比28小,就不和29相比了,這樣一來就可以提高一點效率(如果一開始存儲的數就是最值,那就慘了),沒有必要挨個彭,這裏是分了叉的。25比28小,往左邊走,比21大,就往右邊放。最後24來了,比28小,往左邊走,比21大,往右走,比25小,往左走。

技術分享圖片

我們把這種結構稱之為二叉樹,從一個結點上分出兩個叉。這是一種數據結構,凡是相同進不來。怎麽判斷相同,只要是返回0,就進不去。

因此,到現在我們就可以通過二叉樹的方法完成排序,並能確定元素的位置。

二叉樹中的結點有什麽特點?首先結點包含了幾個要素,就跟我們說鏈表一樣,記住的是後面的數據。結點首先記住左邊的數據,就是小的數據,小的就往左邊放。21結點中持有幾個引用?兩個,一個叫做左,一個叫做右,右放置的都是大的數據。不止兩個,還有一個叫做父,記住的是它爹,一共是三,但是有的沒有三個,最多是三個。

這種結構怎麽尋找數據呢?先從19開始,它是最小的,緊跟著往上找,因為19沒有左邊和右邊。到21,按理說應該往上找,但是要看21右邊有沒有,有25。然後25的左右有沒有?就按照這樣的順序找。我感覺這樣的順序很奇怪,無法展現二叉樹的高效率。

現在說一個效率問題,如果存儲的數據很多的話,每記一個元素,都一直往下加,很慢,那怎麽辦呢?

二叉樹做的還是可以的,比如說按照下面的截圖,裝載了五個元素

技術分享圖片

在裝19的時候,怎麽裝?截圖中的五個元素也是有序的,我們想在一個有序的結構當中,去確定一個元素的位置,怎麽做最方便?二分查找,不用從頂層往下挨個比較,取五個元素中折中的那個元素,折中的那個元素不一定是28,所以它每次在往裏面放元素之前,先對已有的有序元素進行折半。這就是二叉樹怎麽提高效率地。

思考一個問題:現在用了比較器了,它厲害在能夠對元素進行指定方式的排序。拿它能不能完成我們之前所學的有序的動作呢?要做怎麽存進去,怎麽取出來。

如果實現怎麽存進去,怎麽取出來,那就意味著先取出來的是28,再取的是21,那就是21大於28,或者說zhangsan先取出來,然後是lisi,也就是說lisi大於zhangsan,說的不是年齡值,而是對象,21所代表的這個對象。為什麽呢?排完序後,取出來的都是最小的(這和存的時候,按照什麽順序存有關吧),其次才變大,所以取的時候,必須保證zhangsan是小於lisi的,那麽這個怎麽畫?

技術分享圖片

如果是這麽畫的就是,21大於28,21位於28的右側。21怎麽能大於28呢?二叉樹誰管你年齡和姓名,是你指定的。二叉樹看的是返回值,你要是說返回0,那全都是一樣的,不要把它固化在數值上。如果二叉樹是下面截圖這麽畫的話,取的先是28,28在這三個數中是最小的,右邊放的全是大的,那麽這個代碼怎麽寫呢?

技術分享圖片

就不這兒那兒的比較了,全部返回正數。返回1就意味這,28先進來了,liasi和zhangsan一比,lisi就比zhangsan大,二叉樹不管其它的,就看返回值是正負,還是0。觀看輸出結果,和存儲的結果是一樣的,這就是有序的。如果想要倒序的話,返回-1就可以了。

技術分享圖片

技術分享圖片

按照指定條件比較,別忘了主要條件和次要條件。

JAVA-初步認識-常用對象API(集合框架-treeset集合-二叉樹)