跳表java代碼解釋 跳表 java

跳躍表(SkipList)

跳躍表是一種基于有序鏈表的拓展,簡稱跳表。

創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)制作、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的朝陽縣網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

下面正式開始了哦,跟著思路來,非常簡單理解:

給定一個(gè)有序鏈表:

1-2-3-5-6-7-8

跳表的思想就是利用了類似索引的思想,提取出鏈表中的部分關(guān)鍵節(jié)點(diǎn),然后再用二分查找。

上面的有序鏈表,把奇數(shù)作為關(guān)鍵節(jié)點(diǎn)提取出來:

上面只是介紹了基本思想,其實(shí)還可以繼續(xù)優(yōu)化,看到這別擔(dān)心,難度不會(huì)增加,也非常好理解:

既然上面提取了一層節(jié)點(diǎn)作為索引,那是不是也可以進(jìn)一步提???

有了2級索引后,插入的節(jié)點(diǎn)可以先和2級索引比較,確定大體范圍;然后再和1級索引比較;最后再回到原鏈表,找到并插入對應(yīng)的位置。

節(jié)點(diǎn)多的時(shí)候還可以進(jìn)一步提取,保證每一層是上一層節(jié)點(diǎn)的一半。提取的極限是同一層只有兩個(gè)節(jié)點(diǎn)的時(shí)候,因?yàn)橐粋€(gè)節(jié)點(diǎn)比較沒有意義。

到這里,多層鏈表結(jié)構(gòu)就提取完了,這就是跳躍表。

當(dāng)大量新節(jié)點(diǎn)通過逐層比較插入到鏈表中后,上層節(jié)點(diǎn)就會(huì)顯得不夠用,這就需要從新節(jié)點(diǎn)中“提拔”一部分節(jié)點(diǎn)到上一層,問題就是“提拔”誰呢(如何選擇索引)?

跳表設(shè)計(jì)者采用了“拋硬幣”的方法,隨機(jī)決定新節(jié)點(diǎn)是否提拔。因?yàn)樘淼奶砑雍蛣h除的節(jié)點(diǎn)是不可預(yù)測的,很難用算法保證跳表的索引分布始終均勻。雖然拋硬幣的方式不能保證絕對均勻,但大體上是趨于均勻的。

比如說,9插入到鏈表后,開始分析:

跳躍表插入操作的時(shí)間復(fù)雜度是O(logN),而這種數(shù)據(jù)結(jié)構(gòu)所占空間是2N,既空間復(fù)雜度是 O(N)。

刪除的時(shí)候只要在索引層找到要?jiǎng)h除的節(jié)點(diǎn),然后刪除每一層相同的節(jié)點(diǎn)即可。如果某一層刪到只剩下一個(gè),那么整層都可以刪掉。比如刪除5:

跳躍表刪除操作的時(shí)間復(fù)雜度是O(logN)。

跳表維持結(jié)構(gòu)平衡的成本較低,完全靠隨機(jī)。二叉查找樹在多次插入和刪除后需要重新保持自平衡。

Redis的五種數(shù)據(jù)類型之一Sorted-set(zset)這種有序集合,正是對于跳躍表的改進(jìn)和應(yīng)用。

還有Java中的ConcurrentSkipListMap和ConcurrentSkipListSet內(nèi)部都是用跳表的數(shù)據(jù)結(jié)構(gòu)。

請問如何解釋清楚下面的Java代碼?

主要實(shí)現(xiàn)的是登錄驗(yàn)證的過程

首先傳入賬戶名和密碼

然后executeQuery查表,就是查和傳入的賬戶名一樣的有幾條記錄

接著if(rs.next())判斷(這里有BUG的,因?yàn)橛锌赡艽嬖谥孛膯栴},不過這里暫且認(rèn)為表中名字是唯一的)

如果有查詢到的記錄,就將表中字段的內(nèi)容取出來進(jìn)行賦值

然后temp=1我猜作用應(yīng)該是標(biāo)識位,

1標(biāo)識找到了,也就是賬號密碼沒錯(cuò)

2是找不到,登錄密碼出錯(cuò)

3表示用戶名輸錯(cuò)

當(dāng)密碼相同的時(shí)候,將其表中字段內(nèi)容取出來放到arraylist中供后續(xù)使用操作

return temp;就是用來返回登錄狀態(tài)的,可以通過判斷temp為幾知道哪里出錯(cuò)(不過這里只是返回沒有做后續(xù)處理)

java代碼解讀

第一個(gè)if是判斷searchkey是不是空的,如果不是空的,就追加到name字段作為查詢條件,like模糊查詢

接著第二個(gè)if判斷如果status的值不為空,就追加到status作為條件

如果status為空,走else分支,從userContext中獲取到employee對象,接著判斷,如果它的角色不是manager的話

把這個(gè)對象的id拿出來,作為seller.Id的條件進(jìn)行查詢

求高手跟我解釋下 下面JAVA代碼每句代碼的意思

就從denglu(...)方法開始講了,這個(gè)方法在聲明的時(shí)候標(biāo)識了會(huì)throws Exception,表示這個(gè)方法中的某些代碼可能會(huì)拋出異常。

UserDenglu resultUser = null; 構(gòu)造一個(gè)名叫 UserDenglu的類的對象 resultUser,值為null表示沒有實(shí)例化(只是聲明了一個(gè)模型,沒有在內(nèi)存中占用位置)。

String sql = ... 這名是定義一個(gè)字符串變量,它的值是一個(gè)sql語句;語句的意思是: 查詢t_denglu表中字段userName值(?為暫留空,后面填)并且password值為(?為暫留空,后面填);

PreparedStatement pstmt = con.prepareStatement(sql); 將sql語句傳給con對象(數(shù)據(jù)庫連接對象)的prepareStatement方法得到返回值為 pstmt對象;

pstmt.setString(1, user.getUserName()); 把sql語句中的第一個(gè)?參數(shù)替換成 user.getUserName()方法的返回值;

pstmt.setString(2, user.getPassword()); 意義與上句類同,替換第二個(gè)?參數(shù)。

ResultSet rs = pstmt.executeQuery(); 執(zhí)行數(shù)據(jù)庫查詢語句,將查詢結(jié)果放入rs對象中;

if(rs.next()) 如果rs結(jié)果集中還有下一條的話

resultUser = new UserDenglu(); 實(shí)例化resultUser對象;

resultUser.setUserName(rs.getString("username"));將數(shù)據(jù)庫結(jié)果集中查詢到的列名為username的列的值傳入 resultUser.setUserName()方法中;

resultUser.setPassword(rs.getString("password"));與上句類同,將password列的值傳入到resultUser的setPassword()方法中。

========================================================

這個(gè)做的是用戶登錄功能,該方法中接收一個(gè)包含用戶輸入的用戶名和密碼的UserDenglu對象,然后用它們來查詢數(shù)據(jù)庫中是否有對應(yīng)用戶名和密碼對的結(jié)果,如果有的話,就登錄成功,如果沒有,就登錄失敗。登錄失敗,該方法返回的是null,如果登錄成功,返回的是一個(gè)包含數(shù)據(jù)庫中查詢出來的用戶名和密碼的UserDenglu對象。調(diào)用這個(gè)方法時(shí),可以判斷它返回值是否為null來判斷是否登錄成功(用戶名和密碼正確)。

java代碼解析

一樓的說的夠全面了,不過稍有誤解.

再來表示抱歉,我對編程語言中的中文名詞非常不了解,所以如果以下的回復(fù)對你的閱讀或者理解造成困難,請見諒.

1.首先,要明白這個(gè)問題的答案,需要了解call?(pass)?by?value?和?call?(pass)?by?reference?的區(qū)別.簡單來說:

call?by?value通常是復(fù)制這個(gè)parameter的值去另外一塊內(nèi)存里,然后傳給function,?所以在method/function里邊對這個(gè)變量的所有變更,實(shí)際上都是對復(fù)制過來的鏡像進(jìn)行操作,不會(huì)對原本的variable有任何影響.

call?by?reference是將parameter的reference傳給function,簡單點(diǎn)理解就是直接把variable傳給function.所以說這個(gè)variable的值是可以被function改變的.這個(gè)用法在c/c++中非常常見,用法是variable_name.

2.再來,在Java里邊,你可以很簡單的理解為:?Java中只有call?by?value,?也就是說,所以所有傳給function的parameter本身都不會(huì)被改變.?(這是最簡單直白的理解,當(dāng)然也有另一種常從sun的人那邊聽到的說法:Java是call?by?value?+?call?by?reference?by?value)

3.那么現(xiàn)在的問題就是為什么第二個(gè)結(jié)果是2了.?首先說一下sun官方的解釋:?對于reference?type在作為parameter/argument的時(shí)候,也是call?by?value,?但是在你擁有足夠權(quán)限時(shí)(比方說那個(gè)變量是public的,?不是final的等等各種符合的情況),可以修改這個(gè)object中fields的值(也就是屬于這個(gè)object(嚴(yán)謹(jǐn)點(diǎn)講是an?instance?of?the?object)?內(nèi)部的變量,?在你的例子中,?ko?里邊的?a?就是一個(gè)field,?所以update(ko)會(huì)使ko.a變成2).

4.如果你是一個(gè)有過c/c++學(xué)習(xí)經(jīng)驗(yàn)的人或者你以上的解釋很難理解,以下這種說法或許更適合你?(當(dāng)然了,這只是大多包括我在內(nèi)有c經(jīng)驗(yàn)的人的一種理解方式)

這里可以引入一個(gè)新的概念,pointer.?這是一種比較特殊的變量,它內(nèi)部所儲存的東西,其實(shí)只是另外一個(gè)變量的內(nèi)存地址.?如果對內(nèi)存沒有概念,你可以把它簡單理解為是風(fēng)箏的線軸,雖然看它本身看不出什么端倪,但是順著摸過去總會(huì)找到風(fēng)箏,看到它是什么樣子.?以pointer方式理解Java的人,通常會(huì)說:?Type?variable?=?new?Type();?這個(gè)過程中,最后生成的這個(gè)variable其實(shí)就是一個(gè)pointer,而不是instance本身.

在Java中,?有c/c++經(jīng)驗(yàn)的人通常認(rèn)為Java是call?by?value.同時(shí),當(dāng)一個(gè)變量用在儲存reference?type的時(shí)候,實(shí)際上儲存的是它的pointer,這也一樣可以解釋為什么ko.a會(huì)有2這個(gè)結(jié)果,因?yàn)殡m然pointer被傳到function里邊時(shí),本身是call?by?value,無法被改變.但這并不影響function本身對這個(gè)pointer指向的object的內(nèi)容做任何改變.?當(dāng)然,再次聲明,這只是一種幫助有c/c++經(jīng)驗(yàn)的人理解的方法.?Sun本身嚴(yán)正聲明Java里邊沒有pointer這個(gè)東西的存在.

5.?再來解釋一下為什么說樓上所說的(或者說樓上引用的)理解略有偏差.

引用"我們上面剛學(xué)習(xí)了JAVA的數(shù)據(jù)類型,則有:值類型就是按值傳遞的,而引用類型是按引用傳遞的"?這句話很明顯的有兩點(diǎn)錯(cuò)誤.?第一點(diǎn),如果我上面所說的,Java是沒有call?by?reference的.

第二點(diǎn),暫且假設(shè)Java里邊是有call?by?reference的,?這句話依然不成立.

Java中的變量有兩種類型:?primitive?types?和?reference?type.

primitive?type包括byte,?short,?int,?long,?char,?boolean,?float和double.

而這8種之外的所有的,都是reference?type.

下面是一段對你的貼上來的code的一點(diǎn)延伸,希望可以幫助你更好的理解Java中的argument?/?parameter到底是如何運(yùn)作的.

public?class?Test?{

public?static?void?main(String[]?args)?{

int?a?=?1;

Koo?koo?=?new?Koo();

Object?o?=?new?Integer(1);

Koo?newKoo?=?new?Koo();

update(a);

update(koo);

update(o);

update(newKoo);

newUpdate(newKoo);

System.out.println(a);

System.out.println(koo.a);

System.out.println(o);

System.out.println(newKoo.a);

}

static?void?update(int?a)?{

a++;

}

static?void?update(Koo?koo)?{

koo.a++;

}

static?void?update(Object?o)?{

o?=?(int)?(Integer.parseInt(o.toString())?+?1);

}

static?void?newUpdate(Koo?koo)?{

koo?=?new?Koo();

}

}

class?Koo?{

int?a?=?1;

}

/*

o?=?(int)?(Integer.parseInt(o.toString())?+?1);?這一行中的(int)純粹是多余的,是否有這個(gè)casting對code本身沒有任何影響.?如果你高興也可以用

o?=?new?Integer(Integer.parseInt(o.toString())?+?1);

或者干脆

o?=?Integer.parseInt(o.toString())?+?1;

*/

以上這些code運(yùn)行之后會(huì)得到1?2?1?2的結(jié)果.?后面兩個(gè)結(jié)果可以很好的說明,?即使對objects?(reference?type?variables)?來看,?Java所應(yīng)用的也并不是call?by?reference.?否則的話,以上code運(yùn)行結(jié)果應(yīng)該是1?2?2?1

希望你可以真正理解這個(gè)新的例子中,產(chǎn)生1212這個(gè)結(jié)果的原因,從而對Java中的arguments有一個(gè)系統(tǒng)全面的認(rèn)識.

圖片是相關(guān)資料的鏈接,知道里貌似不能加網(wǎng)址

新聞標(biāo)題:跳表java代碼解釋 跳表 java
文章分享:http://muchs.cn/article18/hggodp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、App開發(fā)、用戶體驗(yàn)、外貿(mào)網(wǎng)站建設(shè)、全網(wǎng)營銷推廣、軟件開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)