最近開始學(xué)習(xí)java的數(shù)據(jù)結(jié)構(gòu)(確切地說(shuō),是用java實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)),首先,很大的感觸是,和C實(shí)現(xiàn)鏈表的思想是相通的啊。數(shù)據(jù)結(jié)構(gòu)本來(lái)就一樣嘛。
閑話少扯,直奔主題!
先說(shuō)鏈表吧,鏈表不同于以前我們學(xué)過(guò)的隊(duì)列或數(shù)組,它是非線性的,即不是在內(nèi)存中連續(xù)存儲(chǔ)的。鏈表可以理解成由很多結(jié)點(diǎn)組成,很多人會(huì)把鏈表比喻為自行車 的鏈條,竊以為,這樣比喻是欠妥的,因?yàn)殒湕l是連續(xù)的(哈哈哈哈,這個(gè)牛角尖鉆的),或許可以將其理解為你手機(jī)里存的親友手機(jī)號(hào)碼,我們可以通過(guò)這個(gè)號(hào)碼 和那個(gè)人取得聯(lián)系。我們一般將鏈表的一個(gè)結(jié)點(diǎn)分成兩個(gè)部分:Data filed和Pointer field(這些是作者沿用C里的叫法),數(shù)據(jù)域用來(lái)存儲(chǔ)數(shù)據(jù),后面的指針域用來(lái)存放下一個(gè)結(jié)點(diǎn)的地址。
結(jié)點(diǎn)的定義如下:
public class Node {
// local declaration
private Object obj;
private Node next;
// getters and setters
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
} // end class Node
這段代碼很清晰的表明了結(jié)點(diǎn)的組成內(nèi)容。
我的隊(duì)列之鏈表實(shí)現(xiàn)版實(shí)現(xiàn)了以下幾個(gè)功能:創(chuàng)建、增加、刪除、插入、修改、打印、取指定位置的值以及取隊(duì)列的大小。
先選取其中的幾個(gè)闡述一下,希望大家指正!
1.刪除:先上代碼
// delete an item from list
public void del(int index){
// counters
int count = 0;
// delete item
if(index < 0 || index >= size()){
throw new RuntimeException("Out of index:" + index);
}else{
if(index == 0){
root = null;
}else{
Node node = root.getNext();
while(node != null){
count ++;
if(index == count){
node.setNext(node.getNext().getNext());
}
node = node.getNext();
} // end loop while
} // end if-else
} // end if-else
} // end method del
刪除的實(shí)現(xiàn)的一個(gè)難點(diǎn)是如何確認(rèn)到達(dá)指定的index位置進(jìn)行下一步操作。這里是首先定義了一個(gè)計(jì)數(shù)器,用以判斷是否到達(dá)指定位置,當(dāng) index==count時(shí),就可以進(jìn)行刪除操作了,刪除就是將index-1處得結(jié)點(diǎn)的next指向index+1處的結(jié)點(diǎn),java的一個(gè)優(yōu)點(diǎn)是,你 不用像C一樣人為地用free()函數(shù)釋放空間,JVM會(huì)自動(dòng)回收。個(gè)人強(qiáng)烈建議,在學(xué)數(shù)據(jù)結(jié)構(gòu)時(shí),拿支筆在紙上畫畫,這樣可以將抽象的東西具體化,有利 于理解。向鏈表中增加一個(gè)元素就是刪除的逆過(guò)程了。此處不再贅述。
2.插入:代碼如下
// insert an item to list (follow item NO.index)
public void insert(int index, Object obj){
// counters
int count = 0;
if(index < 0 || index >= size()){
throw new RuntimeException("Out of index: " + index);
}else{
// insert
if(index == 0){
root.setObj(obj);
}else{
// create a new node
Node insert = new Node();
insert.setObj(obj);
// insert it into the list
Node node = root.getNext();
while(node != null){
count ++;
if(index == count){
insert.setNext(node.getNext());
node.setNext(insert);
}
node = node.getNext();
} // end loop while
} // end if-else
} // end if-else
} // end method insert
這段代碼其實(shí)和刪除的很像,只是在判斷之間先創(chuàng)建一個(gè)insert結(jié)點(diǎn)并setObj了,而且,有一個(gè)很值得注意的地方是:必須先insert.setNext(node.getNext());否則就會(huì)出錯(cuò),大道理上是和程序時(shí)自上而下執(zhí)行是有關(guān)的。相信你懂的。
這兩段代碼都得先比較index和size()進(jìn)行比較,這是為了保持代碼的健壯性。防止溢出。
寫這個(gè)的時(shí)候,我就在想,我寫的東西很大一種程度上是給未來(lái)的自己看的,可以用作復(fù)習(xí),可以用來(lái)找回憶,所以,總希望以一種輕松和諧的姿態(tài)行文。
既然寫了這么多,就繼續(xù)扯點(diǎn)其他的吧,最近才發(fā)現(xiàn),隨著時(shí)間的推移,最初那種經(jīng)常將C和Java攪在一起的局面已經(jīng)一去不復(fù)返了,現(xiàn)在開始學(xué)著用Java 解決一些以前用C解決的問(wèn)題,通過(guò)這個(gè)過(guò)程,開始更加了解C和Java,二者的相似點(diǎn)和不同的地方也已經(jīng)有點(diǎn)眉目了。欣慰啊,最開始同時(shí)學(xué)習(xí)的時(shí)候,總是 有點(diǎn)擔(dān)心,但是后來(lái)轉(zhuǎn)念一想:C和Java都是計(jì)算機(jī)語(yǔ)言,沒(méi)有必要將其完全分開,這才堅(jiān)持了下來(lái)。過(guò)程雖然有點(diǎn)痛苦,但是結(jié)果還是有點(diǎn)滿意。
現(xiàn)在這個(gè)階段,發(fā)現(xiàn)自己的C和java還是屬于大菜階段,但是,我一直固執(zhí)地以為,只要我堅(jiān)持了,就沒(méi)有辦不到的事,至少過(guò)去20年的經(jīng)驗(yàn)這樣告訴我的。編程的天才都是訓(xùn)練出來(lái)的!我是一個(gè)不相信天才的人(盡管曾經(jīng)有人這樣叫過(guò)我 )。
最后,以我桌面上的一句話結(jié)束這次對(duì)話吧:The minute you think of giving up, think of the reason why you held on so long.
閑話少扯,直奔主題!
先說(shuō)鏈表吧,鏈表不同于以前我們學(xué)過(guò)的隊(duì)列或數(shù)組,它是非線性的,即不是在內(nèi)存中連續(xù)存儲(chǔ)的。鏈表可以理解成由很多結(jié)點(diǎn)組成,很多人會(huì)把鏈表比喻為自行車 的鏈條,竊以為,這樣比喻是欠妥的,因?yàn)殒湕l是連續(xù)的(哈哈哈哈,這個(gè)牛角尖鉆的),或許可以將其理解為你手機(jī)里存的親友手機(jī)號(hào)碼,我們可以通過(guò)這個(gè)號(hào)碼 和那個(gè)人取得聯(lián)系。我們一般將鏈表的一個(gè)結(jié)點(diǎn)分成兩個(gè)部分:Data filed和Pointer field(這些是作者沿用C里的叫法),數(shù)據(jù)域用來(lái)存儲(chǔ)數(shù)據(jù),后面的指針域用來(lái)存放下一個(gè)結(jié)點(diǎn)的地址。
結(jié)點(diǎn)的定義如下:
public class Node {
// local declaration
private Object obj;
private Node next;
// getters and setters
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
} // end class Node
這段代碼很清晰的表明了結(jié)點(diǎn)的組成內(nèi)容。
我的隊(duì)列之鏈表實(shí)現(xiàn)版實(shí)現(xiàn)了以下幾個(gè)功能:創(chuàng)建、增加、刪除、插入、修改、打印、取指定位置的值以及取隊(duì)列的大小。
先選取其中的幾個(gè)闡述一下,希望大家指正!
1.刪除:先上代碼
// delete an item from list
public void del(int index){
// counters
int count = 0;
// delete item
if(index < 0 || index >= size()){
throw new RuntimeException("Out of index:" + index);
}else{
if(index == 0){
root = null;
}else{
Node node = root.getNext();
while(node != null){
count ++;
if(index == count){
node.setNext(node.getNext().getNext());
}
node = node.getNext();
} // end loop while
} // end if-else
} // end if-else
} // end method del
刪除的實(shí)現(xiàn)的一個(gè)難點(diǎn)是如何確認(rèn)到達(dá)指定的index位置進(jìn)行下一步操作。這里是首先定義了一個(gè)計(jì)數(shù)器,用以判斷是否到達(dá)指定位置,當(dāng) index==count時(shí),就可以進(jìn)行刪除操作了,刪除就是將index-1處得結(jié)點(diǎn)的next指向index+1處的結(jié)點(diǎn),java的一個(gè)優(yōu)點(diǎn)是,你 不用像C一樣人為地用free()函數(shù)釋放空間,JVM會(huì)自動(dòng)回收。個(gè)人強(qiáng)烈建議,在學(xué)數(shù)據(jù)結(jié)構(gòu)時(shí),拿支筆在紙上畫畫,這樣可以將抽象的東西具體化,有利 于理解。向鏈表中增加一個(gè)元素就是刪除的逆過(guò)程了。此處不再贅述。
2.插入:代碼如下
// insert an item to list (follow item NO.index)
public void insert(int index, Object obj){
// counters
int count = 0;
if(index < 0 || index >= size()){
throw new RuntimeException("Out of index: " + index);
}else{
// insert
if(index == 0){
root.setObj(obj);
}else{
// create a new node
Node insert = new Node();
insert.setObj(obj);
// insert it into the list
Node node = root.getNext();
while(node != null){
count ++;
if(index == count){
insert.setNext(node.getNext());
node.setNext(insert);
}
node = node.getNext();
} // end loop while
} // end if-else
} // end if-else
} // end method insert
這段代碼其實(shí)和刪除的很像,只是在判斷之間先創(chuàng)建一個(gè)insert結(jié)點(diǎn)并setObj了,而且,有一個(gè)很值得注意的地方是:必須先insert.setNext(node.getNext());否則就會(huì)出錯(cuò),大道理上是和程序時(shí)自上而下執(zhí)行是有關(guān)的。相信你懂的。
這兩段代碼都得先比較index和size()進(jìn)行比較,這是為了保持代碼的健壯性。防止溢出。
寫這個(gè)的時(shí)候,我就在想,我寫的東西很大一種程度上是給未來(lái)的自己看的,可以用作復(fù)習(xí),可以用來(lái)找回憶,所以,總希望以一種輕松和諧的姿態(tài)行文。
既然寫了這么多,就繼續(xù)扯點(diǎn)其他的吧,最近才發(fā)現(xiàn),隨著時(shí)間的推移,最初那種經(jīng)常將C和Java攪在一起的局面已經(jīng)一去不復(fù)返了,現(xiàn)在開始學(xué)著用Java 解決一些以前用C解決的問(wèn)題,通過(guò)這個(gè)過(guò)程,開始更加了解C和Java,二者的相似點(diǎn)和不同的地方也已經(jīng)有點(diǎn)眉目了。欣慰啊,最開始同時(shí)學(xué)習(xí)的時(shí)候,總是 有點(diǎn)擔(dān)心,但是后來(lái)轉(zhuǎn)念一想:C和Java都是計(jì)算機(jī)語(yǔ)言,沒(méi)有必要將其完全分開,這才堅(jiān)持了下來(lái)。過(guò)程雖然有點(diǎn)痛苦,但是結(jié)果還是有點(diǎn)滿意。
現(xiàn)在這個(gè)階段,發(fā)現(xiàn)自己的C和java還是屬于大菜階段,但是,我一直固執(zhí)地以為,只要我堅(jiān)持了,就沒(méi)有辦不到的事,至少過(guò)去20年的經(jīng)驗(yàn)這樣告訴我的。編程的天才都是訓(xùn)練出來(lái)的!我是一個(gè)不相信天才的人(盡管曾經(jīng)有人這樣叫過(guò)我 )。
最后,以我桌面上的一句話結(jié)束這次對(duì)話吧:The minute you think of giving up, think of the reason why you held on so long.