欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java數(shù)據(jù)結(jié)構(gòu)之線性表

 更新時(shí)間:2017年03月10日 10:19:19   作者:朝向遠(yuǎn)方  
線性表是其組成元素間具有線性關(guān)系的一種數(shù)據(jù)結(jié)構(gòu),對(duì)線性表的基本操作主要有,獲取元素,設(shè)置元素值,遍歷,插入,刪除,查找,替換,排序等。而線性表可以采用順序儲(chǔ)存結(jié)構(gòu)和鏈?zhǔn)絻?chǔ)存結(jié)構(gòu),本節(jié)主要講解順序表、單鏈表以及雙鏈表的各種基本操作。

線性表是其組成元素間具有線性關(guān)系的一種數(shù)據(jù)結(jié)構(gòu),對(duì)線性表的基本操作主要有,獲取元素,設(shè)置元素值,遍歷,插入,刪除,查找,替換,排序等。而線性表可以采用順序儲(chǔ)存結(jié)構(gòu)和鏈?zhǔn)絻?chǔ)存結(jié)構(gòu),本節(jié)主要講解順序表、單鏈表以及雙鏈表的各種基本操作。

1:線性表抽象的數(shù)據(jù)類型

線性表:是由n(n>=0)個(gè)數(shù)據(jù)相同的元素組成的有限序列。線性表的定義接口如下

public interface IList<T> {
 /**
 * 是否為空
 * @return
 */
 boolean isEmpty();
 /**
 * 表的長(zhǎng)度
 * @return
 */
 int length();
 /**
 * 根據(jù)索引獲取長(zhǎng)度
 * @param i
 * @return
 */
 T get(int i);
 /**
 * 設(shè)置第i個(gè)元素值為x
 * @param i
 * @param x
 */
 void set(int i,T x);
 /**
 * 在線性表最后插入x元素
 * @param x
 */
 void append(T x);
 /**
 * 異常第i個(gè)元素并返回值
 * @param i
 * @return
 */
 T remove(int i);
 /**
 * 刪除線性表中所有元素
 */
 void removeAll();
 /**
 * 查詢首次出現(xiàn)關(guān)鍵字為key的元素
 * @param key
 * @return
 */
 T search(T key);
 void insert(int i,T x);
 /**
 * 升序添加
 * @param x
 */
 void insert(T x);
 /**
 * 升序刪除
 * @param x
 */
 void remove(T x);
}

2:線性表順序表示和實(shí)現(xiàn)

線性表的順序存儲(chǔ)結(jié)構(gòu)是一組連續(xù)的內(nèi)存單元依次存放的線性表的數(shù)據(jù)元素,元素的物理地址和邏輯地址次序是相同的。我們叫做這種存儲(chǔ)方式為順序表。

由于數(shù)組只能進(jìn)行賦值和取值,而且長(zhǎng)度是不可變化的,所以給我們的操作帶來(lái)很大的麻煩,但是用順序表就可以進(jìn)行刪除,插入等操作。其實(shí)順序表內(nèi)部同樣適用數(shù)組來(lái)表示的,只不過這個(gè)數(shù)據(jù)我們可以改變他的長(zhǎng)度,這樣說(shuō)來(lái)我們就好辦了,首先我們要為順序表定義一個(gè)數(shù)組,同時(shí)在定義一個(gè)值來(lái)記錄線性表的長(zhǎng)度,所以第一步我們就有了如下

準(zhǔn)備事件做好了以后,我們肯定會(huì)對(duì)順序表進(jìn)行初始化,剛剛開始數(shù)組的長(zhǎng)度肯定是0。但是我們必須要為數(shù)組開辟一個(gè)內(nèi)存空間,來(lái)存儲(chǔ)要插入的元素,如下

其他的都比較簡(jiǎn)單,我主要說(shuō)下插入和刪除

插入一個(gè)元素的時(shí)候,如果插在第i個(gè)位置,那么意味著它后面所有的元素前部往后面移一位,但是我們必須把i個(gè)位置留出來(lái)給即將插入的元素。但是我們還必須考慮,如果這個(gè)數(shù)組滿了的情況。如果滿了,我們必須重新為順序表開辟內(nèi)存空間,然后把以前的元素進(jìn)行遷移到新的表中,java實(shí)現(xiàn)如下

代碼看出,我們把從第i個(gè)位置的元素全部往后移(包括第i個(gè)元素)然后在把第i個(gè)元素進(jìn)行賦值

刪除第i個(gè)元素,這個(gè)和上面的正好相反,如果刪除第i個(gè)元素意味著在i之后的元素前部往前移一位。

3:順序表操作效率分析

因?yàn)轫樞虮硎蔷哂兴饕?,所以get()和set()效率極高,時(shí)間復(fù)雜度都是O(n)。

從上面發(fā)現(xiàn),在插入和刪除的時(shí)候都是需要大量元素的移動(dòng),因?yàn)樵诟鱾€(gè)位置插入元素的概率相同,所以平均插入一個(gè)元素要移動(dòng)的元素是2/n。那么它的時(shí)間復(fù)雜度就是O(n),如果要容器滿了,那么就需要申請(qǐng)更大的容器來(lái)存儲(chǔ)新加入的元素,那么效率會(huì)更加的低下。所以順序表的靜態(tài)性好,動(dòng)態(tài)性就很差了,所以在選擇的時(shí)候就要注意一下。

4:?jiǎn)捂湵淼膶?shí)現(xiàn)

線性表的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)是用若干地址分散的存儲(chǔ)單元存儲(chǔ)數(shù)據(jù)元素,邏輯上相鄰的2個(gè)元素,物理地址不一定相同,這么說(shuō)來(lái)就充分的利用了內(nèi)存中的地址。但是我們必須用附加信息來(lái)連接2個(gè)不同的數(shù)據(jù)元素,所以這里就引進(jìn)了2個(gè)概念,數(shù)據(jù)域(data)和地址域(next),其中數(shù)據(jù)域存儲(chǔ)的是這個(gè)元素的值,地址域存儲(chǔ)下一個(gè)元素的地址。其中數(shù)據(jù)域和地址域聯(lián)合起來(lái)我們稱為節(jié)點(diǎn)(node)。如果只有后繼節(jié)點(diǎn)沒有前驅(qū)節(jié)點(diǎn)我們就稱為單鏈表,那么現(xiàn)在我們來(lái)看看單鏈表的實(shí)現(xiàn)。

首先我們要定義一個(gè)節(jié)點(diǎn)Node

public class Node<T> {
 public T data;//數(shù)據(jù)域
 public Node next;//地址域
 public Node() {
 this(null, null);
 }
 public Node(T data, Node next) {
 this.data = data;
 this.next = next;
 }
}

現(xiàn)在我們想象一下,A(x)和B(y)2個(gè)節(jié)點(diǎn),其中A的后繼節(jié)點(diǎn)是B,那么我們?cè)趺幢硎灸?,如?/p>

Node<String> A=new Node<T>(x,null);
Node<String> B=new Node<T>(y,null);
A.next=B。

也可以把A寫成Node<String> A=new Node<T>(x,B);

ok現(xiàn)在我們正式開始實(shí)現(xiàn)一個(gè)帶有頭節(jié)點(diǎn)的單鏈表

我們可以把頭指針想象成一個(gè)指針來(lái)便于我們的操作,我們先看如何實(shí)現(xiàn)單鏈表的長(zhǎng)度

public int length() {
 int i = 0;
 Node<T> p = this.head.next;
 while (p != null) {
  p = p.next;
  i++;
 }
 return i;
 }

因?yàn)檫@是一個(gè)鏈?zhǔn)降慕Y(jié)構(gòu),我們無(wú)法得知長(zhǎng)度,只能通過循環(huán)來(lái)知道鏈表中節(jié)點(diǎn)的個(gè)數(shù),因?yàn)轭^指針的后繼節(jié)點(diǎn)就是我們鏈表中第一個(gè)節(jié)點(diǎn),所以我們就可以這樣往下循環(huán)來(lái)得知。

獲取第i個(gè)節(jié)點(diǎn)的值

同樣我們無(wú)法直接獲取節(jié)點(diǎn),這個(gè)時(shí)候同樣采用循環(huán),如果循環(huán)第i個(gè)元素值等于我們i那么我們就獲取這個(gè)節(jié)點(diǎn),然后得到值

public T get(int i) {
 if (i >= 0) {
  Node<T> p = this.head;
  for (int j = 0; j <= i; j++) {
  p = p.next;
  }
  if (p!=null){
  return p.data;
  }
 }
 return null;
 }

在第i個(gè)位置插入一個(gè)節(jié)點(diǎn)

首先我們必須要找到要插入節(jié)點(diǎn)的前驅(qū)節(jié)點(diǎn),然后前驅(qū)節(jié)點(diǎn)的后繼節(jié)點(diǎn)指向這個(gè)新節(jié)點(diǎn),新節(jié)點(diǎn)的后繼節(jié)點(diǎn)指向原來(lái)前驅(qū)節(jié)點(diǎn)的后繼節(jié)點(diǎn)。

從代碼看出我們是根據(jù)頭節(jié)點(diǎn)進(jìn)行循環(huán)的。加入p.next!=null的目的是為了當(dāng)循環(huán)到最后一個(gè)節(jié)點(diǎn)的時(shí)候就停止,不在繼續(xù)了。

移除第i個(gè)節(jié)點(diǎn)

如果我們要?jiǎng)h除第i個(gè)節(jié)點(diǎn)和上面差不多,同樣我們要找到這個(gè)第i個(gè)節(jié)點(diǎn)的前驅(qū)節(jié)點(diǎn),和上面代碼差不多。

在鏈表后追加一個(gè)節(jié)點(diǎn)。

如果傳統(tǒng)的話我們可以采取insert(this.length,x);但是這樣一來(lái)計(jì)算長(zhǎng)度的時(shí)候就需要遍歷鏈表無(wú)疑速度減慢,只需要如下

insert(Integer.MAX_VALUE, x)即可,從插入代碼可以看到當(dāng)循環(huán)到最后一個(gè)節(jié)點(diǎn)就不會(huì)繼續(xù)了,然后把新的節(jié)點(diǎn)加入最后即可。

5:排序單鏈表

排序首先我們需要我們的元素要繼承comparable。

我們就說(shuō)插入和刪除。先說(shuō)插入

如果插入一個(gè)元素,我們先獲取要插入這個(gè)節(jié)點(diǎn)的前驅(qū)節(jié)點(diǎn)和后繼節(jié)點(diǎn)。(x.compareTo(y)<0 表示小于y)

其中p.data.next.compareTo(x)<0如果跳出循環(huán)說(shuō)明p節(jié)點(diǎn)值大于或等于x

如果刪除一個(gè)元素,和上面的基本一樣,但是要加上一個(gè)判斷如下

其中通過上面判斷我們知道p節(jié)點(diǎn)大于或等于x節(jié)點(diǎn)了,所以需要再次判斷。

6:?jiǎn)捂湵聿僮餍史治?/strong>

單鏈表在獲取元素和設(shè)置元素的時(shí)候都需要進(jìn)行遍歷所以時(shí)間復(fù)雜度O(n)

如果在p節(jié)點(diǎn)插入或刪除元素,只需要修改鏈的后繼節(jié)點(diǎn)的地址即可所以時(shí)間復(fù)雜度O(1),但是如果插入類似insert(i,x)就需要進(jìn)行遍歷了,那么時(shí)間復(fù)雜度就是O(n).

對(duì)單鏈表進(jìn)行插入和刪除只需要改變少量節(jié)點(diǎn)的鏈,不需要移動(dòng)元素,單鏈表的插入和刪除都是動(dòng)態(tài)申請(qǐng)和釋放的,不需要預(yù)先分配存儲(chǔ)空間,從而不會(huì)因?yàn)榇鎯?chǔ)空間不足而進(jìn)行擴(kuò)容,提高了運(yùn)行效率。

7:雙鏈表的實(shí)現(xiàn)

雙鏈表和單鏈表大多是相同的只不過多了前驅(qū)節(jié)點(diǎn),現(xiàn)在我們先定義一下雙鏈表

我們這里來(lái)演示循環(huán)雙鏈表的實(shí)現(xiàn)?;竞蛦捂湵硐嗤徊贿^如果為空鏈表那么它的后繼節(jié)點(diǎn)就是頭節(jié)點(diǎn)。ok我們先來(lái)看

求雙鏈表的長(zhǎng)度(基本和單鏈表一樣后面一樣的不在寫了)因?yàn)槭茄h(huán)雙鏈表最后一個(gè)節(jié)點(diǎn)的后繼節(jié)點(diǎn)為

我們這里只說(shuō)插入和刪除(其他基本一樣和單鏈表)

插入

同樣我們需要找到要插入的節(jié)點(diǎn)

其中p.next!=this.head表示如果是最后一個(gè)節(jié)點(diǎn)則跳出循環(huán)。其中要插入的節(jié)點(diǎn)在p節(jié)點(diǎn)之后,然后我們就好理解了。

刪除

和上面的差不多

8:循環(huán)雙鏈表

根本和單鏈表一樣。也是先找到節(jié)點(diǎn)的位置然后插入或刪除

總結(jié):主要是回顧一下線性表,通過對(duì)線性表的了解,在以后我們看java容器源碼的時(shí)候會(huì)帶來(lái)極大的幫助

以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!

相關(guān)文章

  • JDK1.8安裝與配置超詳細(xì)教程

    JDK1.8安裝與配置超詳細(xì)教程

    JDK1.8即為JDK8,JDK8是目前是最成熟最穩(wěn)定的版本,本文將詳細(xì)介紹JDK1.8的安裝與配置,需要的朋友可以參考下
    2023-03-03
  • SpringMvc web.xml配置實(shí)現(xiàn)原理過程解析

    SpringMvc web.xml配置實(shí)現(xiàn)原理過程解析

    這篇文章主要介紹了SpringMvc web.xml配置實(shí)現(xiàn)原理過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 關(guān)于多線程常用方法以及對(duì)鎖的控制(詳解)

    關(guān)于多線程常用方法以及對(duì)鎖的控制(詳解)

    下面小編就為大家?guī)?lái)一篇關(guān)于多線程常用方法以及對(duì)鎖的控制(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2017-05-05
  • 詳解手把手Maven搭建SpringMVC+Spring+MyBatis框架(超級(jí)詳細(xì)版)

    詳解手把手Maven搭建SpringMVC+Spring+MyBatis框架(超級(jí)詳細(xì)版)

    本篇文章主要介紹了手把手Maven搭建SpringMVC+Spring+MyBatis框架(超級(jí)詳細(xì)版),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Monaco?Editor實(shí)現(xiàn)sql和java代碼提示實(shí)現(xiàn)示例

    Monaco?Editor實(shí)現(xiàn)sql和java代碼提示實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了Monaco?Editor代碼提示sql和java實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 關(guān)于Java企業(yè)級(jí)項(xiàng)目開發(fā)思想

    關(guān)于Java企業(yè)級(jí)項(xiàng)目開發(fā)思想

    Java企業(yè)級(jí)項(xiàng)目開發(fā)思想。偶遇,讀有所得,遂分享給大家,本文不涉及案例,只談思想和理念,需要的朋友可以參考。
    2017-09-09
  • Okhttp在SpringBoot中的應(yīng)用實(shí)戰(zhàn)記錄(太強(qiáng)了)

    Okhttp在SpringBoot中的應(yīng)用實(shí)戰(zhàn)記錄(太強(qiáng)了)

    這篇文章主要給大家介紹了關(guān)于Okhttp在SpringBoot中應(yīng)用實(shí)戰(zhàn)的相關(guān)資料,在Spring Boot中使用OkHttp主要是為了發(fā)送HTTP請(qǐng)求和處理響應(yīng),OkHttp是一個(gè)高效、易用的HTTP客戶端庫(kù),它具有簡(jiǎn)潔的API和強(qiáng)大的功能,需要的朋友可以參考下
    2023-12-12
  • 淺談Java到底是值傳遞還是引用傳遞呢

    淺談Java到底是值傳遞還是引用傳遞呢

    今天帶大家學(xué)習(xí)Java的相關(guān)知識(shí),文章圍繞著Java到底是值傳遞還是引用傳遞展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • SpringBoot @ConfigurationProperties注解的簡(jiǎn)單使用

    SpringBoot @ConfigurationProperties注解的簡(jiǎn)單使用

    即便現(xiàn)在簡(jiǎn)化了配置,但是一個(gè)獨(dú)立的配置文件總是易于理解而且使人安心的。Spring在構(gòu)建完項(xiàng)目后,會(huì)默認(rèn)在resources文件夾下創(chuàng)建一個(gè)application.properties文件,application.yml也是一樣的效果。@ConfigurationProperties可以獲取配置文件中的數(shù)據(jù),將其注入類。
    2021-05-05
  • IDEA MyBatis Plugins自動(dòng)生成實(shí)體類和mapper.xml

    IDEA MyBatis Plugins自動(dòng)生成實(shí)體類和mapper.xml

    這篇文章主要介紹了IDEA MyBatis Plugins自動(dòng)生成實(shí)體類和mapper.xml,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評(píng)論