亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之鏈表

 更新時(shí)間:2022年01月20日 16:01:14   作者:YSOcean  
這篇文章主要為大家介紹了Java數(shù)據(jù)結(jié)構(gòu)和算法之鏈表 ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助

前面博客我們?cè)谥v解數(shù)組中,知道數(shù)組作為數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)有一定的缺陷。在無(wú)序數(shù)組中,搜索性能差,在有序數(shù)組中,插入效率又很低,而且這兩種數(shù)組的刪除效率都很低,并且數(shù)組在創(chuàng)建后,其大小是固定了,設(shè)置的過(guò)大會(huì)造成內(nèi)存的浪費(fèi),過(guò)小又不能滿(mǎn)足數(shù)據(jù)量的存儲(chǔ)。

本篇博客我們將講解一種新型的數(shù)據(jù)結(jié)構(gòu)——鏈表。我們知道數(shù)組是一種通用的數(shù)據(jù)結(jié)構(gòu),能用來(lái)實(shí)現(xiàn)棧、隊(duì)列等很多數(shù)據(jù)結(jié)構(gòu)。而鏈表也是一種使用廣泛的通用數(shù)據(jù)結(jié)構(gòu),它也可以用來(lái)作為實(shí)現(xiàn)棧、隊(duì)列等數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ),基本上除非需要頻繁的通過(guò)下標(biāo)來(lái)隨機(jī)訪(fǎng)問(wèn)各個(gè)數(shù)據(jù),否則很多使用數(shù)組的地方都可以用鏈表來(lái)代替。

但是我們需要說(shuō)明的是,鏈表是不能解決數(shù)據(jù)存儲(chǔ)的所有問(wèn)題的,它也有它的優(yōu)點(diǎn)和缺點(diǎn)。本篇博客我們介紹幾種常見(jiàn)的鏈表,分別是單向鏈表、雙端鏈表、有序鏈表、雙向鏈表以及有迭代器的鏈表。并且會(huì)講解一下抽象數(shù)據(jù)類(lèi)型(ADT)的思想,如何用 ADT 描述棧和隊(duì)列,如何用鏈表代替數(shù)組來(lái)實(shí)現(xiàn)棧和隊(duì)列。

1、鏈表(Linked List)

鏈表通常由一連串節(jié)點(diǎn)組成,每個(gè)節(jié)點(diǎn)包含任意的實(shí)例數(shù)據(jù)(data fields)和一或兩個(gè)用來(lái)指向上一個(gè)/或下一個(gè)節(jié)點(diǎn)的位置的鏈接("links")

鏈表(Linked list)是一種常見(jiàn)的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),是一種線(xiàn)性表,但是并不會(huì)按線(xiàn)性的順序存儲(chǔ)數(shù)據(jù),而是在每一個(gè)節(jié)點(diǎn)里存到下一個(gè)節(jié)點(diǎn)的指針(Pointer)。

使用鏈表結(jié)構(gòu)可以克服數(shù)組鏈表需要預(yù)先知道數(shù)據(jù)大小的缺點(diǎn),鏈表結(jié)構(gòu)可以充分利用計(jì)算機(jī)內(nèi)存空間,實(shí)現(xiàn)靈活的內(nèi)存動(dòng)態(tài)管理。但是鏈表失去了數(shù)組隨機(jī)讀取的優(yōu)點(diǎn),同時(shí)鏈表由于增加了結(jié)點(diǎn)的指針域,空間開(kāi)銷(xiāo)比較大。

2、單向鏈表(Single-Linked List)

單鏈表是鏈表中結(jié)構(gòu)最簡(jiǎn)單的。一個(gè)單鏈表的節(jié)點(diǎn)(Node)分為兩個(gè)部分,第一個(gè)部分(data)保存或者顯示關(guān)于節(jié)點(diǎn)的信息,另一個(gè)部分存儲(chǔ)下一個(gè)節(jié)點(diǎn)的地址。最后一個(gè)節(jié)點(diǎn)存儲(chǔ)地址的部分指向空值。

單向鏈表只可向一個(gè)方向遍歷,一般查找一個(gè)節(jié)點(diǎn)的時(shí)候需要從第一個(gè)節(jié)點(diǎn)開(kāi)始每次訪(fǎng)問(wèn)下一個(gè)節(jié)點(diǎn),一直訪(fǎng)問(wèn)到需要的位置。而插入一個(gè)節(jié)點(diǎn),對(duì)于單向鏈表,我們只提供在鏈表頭插入,只需要將當(dāng)前插入的節(jié)點(diǎn)設(shè)置為頭節(jié)點(diǎn),next指向原頭節(jié)點(diǎn)即可。刪除一個(gè)節(jié)點(diǎn),我們將該節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)的next指向該節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)。  

在表頭增加節(jié)點(diǎn):

刪除節(jié)點(diǎn):  

①、單向鏈表的具體實(shí)現(xiàn)

package com.ys.datastructure;
public class SingleLinkedList {
    private int size;//鏈表節(jié)點(diǎn)的個(gè)數(shù)
    private Node head;//頭節(jié)點(diǎn)
    public SingleLinkedList(){
        size = 0;
        head = null;
    }
    //鏈表的每個(gè)節(jié)點(diǎn)類(lèi)
    private class Node{
        private Object data;//每個(gè)節(jié)點(diǎn)的數(shù)據(jù)
        private Node next;//每個(gè)節(jié)點(diǎn)指向下一個(gè)節(jié)點(diǎn)的連接
        public Node(Object data){
            this.data = data;
        }
    }
    //在鏈表頭添加元素
    public Object addHead(Object obj){
        Node newHead = new Node(obj);
        if(size == 0){
            head = newHead;
        }else{
            newHead.next = head;
            head = newHead;
        }
        size++;
        return obj;
    }
    //在鏈表頭刪除元素
    public Object deleteHead(){
        Object obj = head.data;
        head = head.next;
        size--;
        return obj;
    }
    //查找指定元素,找到了返回節(jié)點(diǎn)Node,找不到返回null
    public Node find(Object obj){
        Node current = head;
        int tempSize = size;
        while(tempSize > 0){
            if(obj.equals(current.data)){
                return current;
            }else{
                current = current.next;
            }
            tempSize--;
        }
        return null;
    }
    //刪除指定的元素,刪除成功返回true
    public boolean delete(Object value){
        if(size == 0){
            return false;
        }
        Node current = head;
        Node previous = head;
        while(current.data != value){
            if(current.next == null){
                return false;
            }else{
                previous = current;
                current = current.next;
            }
        }
        //如果刪除的節(jié)點(diǎn)是第一個(gè)節(jié)點(diǎn)
        if(current == head){
            head = current.next;
            size--;
        }else{//刪除的節(jié)點(diǎn)不是第一個(gè)節(jié)點(diǎn)
            previous.next = current.next;
            size--;
        }
        return true;
    }
    //判斷鏈表是否為空
    public boolean isEmpty(){
        return (size == 0);
    }
    //顯示節(jié)點(diǎn)信息
    public void display(){
        if(size >0){
            Node node = head;
            int tempSize = size;
            if(tempSize == 1){//當(dāng)前鏈表只有一個(gè)節(jié)點(diǎn)
                System.out.println("["+node.data+"]");
                return;
            }
            while(tempSize>0){
                if(node.equals(head)){
                    System.out.print("["+node.data+"->");
                }else if(node.next == null){
                    System.out.print(node.data+"]");
                }else{
                    System.out.print(node.data+"->");
                }
                node = node.next;
                tempSize--;
            }
            System.out.println();
        }else{//如果鏈表一個(gè)節(jié)點(diǎn)都沒(méi)有,直接打印[]
            System.out.println("[]");
        }
    }
}

測(cè)試:

@Test
public void testSingleLinkedList(){
    SingleLinkedList singleList = new SingleLinkedList();
    singleList.addHead("A");
    singleList.addHead("B");
    singleList.addHead("C");
    singleList.addHead("D");
    //打印當(dāng)前鏈表信息
    singleList.display();
    //刪除C
    singleList.delete("C");
    singleList.display();
    //查找B
    System.out.println(singleList.find("B"));
}

打印結(jié)果:

②、用單向鏈表實(shí)現(xiàn)棧

棧的pop()方法和push()方法,對(duì)應(yīng)于鏈表的在頭部刪除元素deleteHead()以及在頭部增加元素addHead()。

package com.ys.datastructure;
public class StackSingleLink {
    private SingleLinkedList link;
    public StackSingleLink(){
        link = new SingleLinkedList();
    }
    //添加元素
    public void push(Object obj){
        link.addHead(obj);
    }
    //移除棧頂元素
    public Object pop(){
        Object obj = link.deleteHead();
        return obj;
    }
    //判斷是否為空
    public boolean isEmpty(){
        return link.isEmpty();
    }
    //打印棧內(nèi)元素信息
    public void display(){
        link.display();
    }
}

4、雙端鏈表

對(duì)于單項(xiàng)鏈表,我們?nèi)绻朐谖膊刻砑右粋€(gè)節(jié)點(diǎn),那么必須從頭部一直遍歷到尾部,找到尾節(jié)點(diǎn),然后在尾節(jié)點(diǎn)后面插入一個(gè)節(jié)點(diǎn)。這樣操作很麻煩,如果我們?cè)谠O(shè)計(jì)鏈表的時(shí)候多個(gè)對(duì)尾節(jié)點(diǎn)的引用,那么會(huì)簡(jiǎn)單很多?! ?/p>

注意和后面將的雙向鏈表的區(qū)別!?。?/p>

①、雙端鏈表的具體實(shí)現(xiàn)

package com.ys.link;
public class DoublePointLinkedList {
    private Node head;//頭節(jié)點(diǎn)
    private Node tail;//尾節(jié)點(diǎn)
    private int size;//節(jié)點(diǎn)的個(gè)數(shù)
    private class Node{
        private Object data;
        private Node next;
        public Node(Object data){
            this.data = data;
        }
    }
    public DoublePointLinkedList(){
        size = 0;
        head = null;
        tail = null;
    }
    //鏈表頭新增節(jié)點(diǎn)
    public void addHead(Object data){
        Node node = new Node(data);
        if(size == 0){//如果鏈表為空,那么頭節(jié)點(diǎn)和尾節(jié)點(diǎn)都是該新增節(jié)點(diǎn)
            head = node;
            tail = node;
            size++;
        }else{
            node.next = head;
            head = node;
            size++;
        }
    }
    //鏈表尾新增節(jié)點(diǎn)
    public void addTail(Object data){
        Node node = new Node(data);
        if(size == 0){//如果鏈表為空,那么頭節(jié)點(diǎn)和尾節(jié)點(diǎn)都是該新增節(jié)點(diǎn)
            head = node;
            tail = node;
            size++;
        }else{
            tail.next = node;
            tail = node;
            size++;
        }
    }
    //刪除頭部節(jié)點(diǎn),成功返回true,失敗返回false
    public boolean deleteHead(){
        if(size == 0){//當(dāng)前鏈表節(jié)點(diǎn)數(shù)為0
            return false;
        }
        if(head.next == null){//當(dāng)前鏈表節(jié)點(diǎn)數(shù)為1
            head = null;
            tail = null;
        }else{
            head = head.next;
        }
        size--;
        return true;
    }
    //判斷是否為空
    public boolean isEmpty(){
        return (size ==0);
    }
    //獲得鏈表的節(jié)點(diǎn)個(gè)數(shù)
    public int getSize(){
        return size;
    }
    //顯示節(jié)點(diǎn)信息
    public void display(){
        if(size >0){
            Node node = head;
            int tempSize = size;
            if(tempSize == 1){//當(dāng)前鏈表只有一個(gè)節(jié)點(diǎn)
                System.out.println("["+node.data+"]");
                return;
            }
            while(tempSize>0){
                if(node.equals(head)){
                    System.out.print("["+node.data+"->");
                }else if(node.next == null){
                    System.out.print(node.data+"]");
                }else{
                    System.out.print(node.data+"->");
                }
                node = node.next;
                tempSize--;
            }
            System.out.println();
        }else{//如果鏈表一個(gè)節(jié)點(diǎn)都沒(méi)有,直接打印[]
            System.out.println("[]");
        }
    }
}

②、用雙端鏈表實(shí)現(xiàn)隊(duì)列

package com.ys.link;
public class QueueLinkedList {
    private DoublePointLinkedList dp;
    public QueueLinkedList(){
        dp = new DoublePointLinkedList();
    }
    public void insert(Object data){
        dp.addTail(data);
    }
    public void delete(){
        dp.deleteHead();
    }
    public boolean isEmpty(){
        return dp.isEmpty();
    }
    public int getSize(){
        return dp.getSize();
    }
    public void display(){
        dp.display();
    }
}

5、抽象數(shù)據(jù)類(lèi)型(ADT)

在介紹抽象數(shù)據(jù)類(lèi)型的時(shí)候,我們先看看什么是數(shù)據(jù)類(lèi)型,聽(tīng)到這個(gè)詞,在Java中我們可能首先會(huì)想到像 int,double這樣的詞,這是Java中的基本數(shù)據(jù)類(lèi)型,一個(gè)數(shù)據(jù)類(lèi)型會(huì)涉及到兩件事:

  • ①、擁有特定特征的數(shù)據(jù)項(xiàng)
  • ②、在數(shù)據(jù)上允許的操作

比如Java中的int數(shù)據(jù)類(lèi)型,它表示整數(shù),取值范圍為:-2147483648~2147483647,還能使用各種操作符,+、-、*、/ 等對(duì)其操作。數(shù)據(jù)類(lèi)型允許的操作是它本身不可分離的部分,理解類(lèi)型包括理解什么樣的操作可以應(yīng)用在該類(lèi)型上。

那么當(dāng)年設(shè)計(jì)計(jì)算機(jī)語(yǔ)言的人,為什么會(huì)考慮到數(shù)據(jù)類(lèi)型?

我們先看這樣一個(gè)例子,比如,大家都需要住房子,也都希望房子越大越好。但顯然,沒(méi)有錢(qián),考慮房子沒(méi)有意義。于是就出現(xiàn)了各種各樣的商品房,有別墅的、復(fù)式的、錯(cuò)層的、單間的……甚至只有兩平米的膠囊房間。這樣做的意義是滿(mǎn)足不同人的需要。

同樣,在計(jì)算機(jī)中,也存在相同的問(wèn)題。計(jì)算1+1這樣的表達(dá)式不需要開(kāi)辟很大的存儲(chǔ)空間,不需要適合小數(shù)甚至字符運(yùn)算的內(nèi)存空間。于是計(jì)算機(jī)的研究者們就考慮,要對(duì)數(shù)據(jù)進(jìn)行分類(lèi),分出來(lái)多種數(shù)據(jù)類(lèi)型。比如int,比如float。

雖然不同的計(jì)算機(jī)有不同的硬件系統(tǒng),但實(shí)際上高級(jí)語(yǔ)言編寫(xiě)者才不管程序運(yùn)行在什么計(jì)算機(jī)上,他們的目的就是為了實(shí)現(xiàn)整形數(shù)字的運(yùn)算,比如a+b等。他們才不關(guān)心整數(shù)在計(jì)算機(jī)內(nèi)部是如何表示的,也不管CPU是如何計(jì)算的。于是我們就考慮,無(wú)論什么計(jì)算機(jī)、什么語(yǔ)言都會(huì)面臨類(lèi)似的整數(shù)運(yùn)算,我們可以考慮將其抽象出來(lái)。抽象是抽取出事物具有的普遍性本質(zhì),是對(duì)事物的一個(gè)概括,是一種思考問(wèn)題的方式。

抽象數(shù)據(jù)類(lèi)型(ADT)是指一個(gè)數(shù)學(xué)模型及定義在該模型上的一組操作。它僅取決于其邏輯特征,而與計(jì)算機(jī)內(nèi)部如何表示和實(shí)現(xiàn)無(wú)關(guān)。比如剛才說(shuō)得整型,各個(gè)計(jì)算機(jī),不管大型機(jī)、小型機(jī)、PC、平板電腦甚至智能手機(jī),都有“整型”類(lèi)型,也需要整形運(yùn)算,那么整型其實(shí)就是一個(gè)抽象數(shù)據(jù)類(lèi)型?!?/p>

更廣泛一點(diǎn)的,比如我們剛講解的棧和隊(duì)列這兩種數(shù)據(jù)結(jié)構(gòu),我們分別使用了數(shù)組和鏈表來(lái)實(shí)現(xiàn),比如棧,對(duì)于使用者只需要知道pop()和push()方法或其它方法的存在以及如何使用即可,使用者不需要知道我們是使用的數(shù)組或是鏈表來(lái)實(shí)現(xiàn)的。

ADT的思想可以作為我們?cè)O(shè)計(jì)工具的理念,比如我們需要存儲(chǔ)數(shù)據(jù),那么就從考慮需要在數(shù)據(jù)上實(shí)現(xiàn)的操作開(kāi)始,需要存取最后一個(gè)數(shù)據(jù)項(xiàng)嗎?還是第一個(gè)?還是特定值的項(xiàng)?還是特定位置的項(xiàng)?回答這些問(wèn)題會(huì)引出ADT的定義,只有完整的定義了ADT后,才應(yīng)該考慮實(shí)現(xiàn)的細(xì)節(jié)。

這在我們Java語(yǔ)言中的接口設(shè)計(jì)理念是想通的。

6、有序鏈表

前面的鏈表實(shí)現(xiàn)插入數(shù)據(jù)都是無(wú)序的,在有些應(yīng)用中需要鏈表中的數(shù)據(jù)有序,這稱(chēng)為有序鏈表。

在有序鏈表中,數(shù)據(jù)是按照關(guān)鍵值有序排列的。一般在大多數(shù)需要使用有序數(shù)組的場(chǎng)合也可以使用有序鏈表。有序鏈表優(yōu)于有序數(shù)組的地方是插入的速度(因?yàn)樵夭恍枰苿?dòng)),另外鏈表可以擴(kuò)展到全部有效的使用內(nèi)存,而數(shù)組只能局限于一個(gè)固定的大小中。

package com.ys.datastructure;
public class OrderLinkedList {
    private Node head;
    private class Node{
        private int data;
        private Node next;
        public Node(int data){
            this.data = data;
        }
    }
    public OrderLinkedList(){
        head = null;
    }
    //插入節(jié)點(diǎn),并按照從小打到的順序排列
    public void insert(int value){
        Node node = new Node(value);
        Node pre = null;
        Node current = head;
        while(current != null && value > current.data){
            pre = current;
            current = current.next;
        }
        if(pre == null){
            head = node;
            head.next = current;
        }else{
            pre.next = node;
            node.next = current;
        }
    }
    //刪除頭節(jié)點(diǎn)
    public void deleteHead(){
        head = head.next;
    }
    public void display(){
        Node current = head;
        while(current != null){
            System.out.print(current.data+" ");
            current = current.next;
        }
        System.out.println("");
    }
}

在有序鏈表中插入和刪除某一項(xiàng)最多需要O(N)次比較,平均需要O(N/2)次,因?yàn)楸仨氀刂湵砩弦徊揭徊阶卟拍苷业秸_的插入位置,然而可以最快速度刪除最值,因?yàn)橹恍枰獎(jiǎng)h除表頭即可,如果一個(gè)應(yīng)用需要頻繁的存取最小值,且不需要快速的插入,那么有序鏈表是一個(gè)比較好的選擇方案。比如優(yōu)先級(jí)隊(duì)列可以使用有序鏈表來(lái)實(shí)現(xiàn)。

7、有序鏈表和無(wú)序數(shù)組組合排序

比如有一個(gè)無(wú)序數(shù)組需要排序,前面我們?cè)谥v解冒泡排序、選擇排序、插入排序這三種簡(jiǎn)單的排序時(shí),需要的時(shí)間級(jí)別都是O(N2)。

現(xiàn)在我們講解了有序鏈表之后,對(duì)于一個(gè)無(wú)序數(shù)組,我們先將數(shù)組元素取出,一個(gè)一個(gè)的插入到有序鏈表中,然后將他們從有序鏈表中一個(gè)一個(gè)刪除,重新放入數(shù)組,那么數(shù)組就會(huì)排好序了。和插入排序一樣,如果插入了N個(gè)新數(shù)據(jù),那么進(jìn)行大概N2/4次比較。但是相對(duì)于插入排序,每個(gè)元素只進(jìn)行了兩次排序,一次從數(shù)組到鏈表,一次從鏈表到數(shù)組,大概需要2*N次移動(dòng),而插入排序則需要N2次移動(dòng),

效率肯定是比前面講的簡(jiǎn)單排序要高,但是缺點(diǎn)就是需要開(kāi)辟差不多兩倍的空間,而且數(shù)組和鏈表必須在內(nèi)存中同時(shí)存在,如果有現(xiàn)成的鏈表可以用,那么這種方法還是挺好的。

8、雙向鏈表

我們知道單向鏈表只能從一個(gè)方向遍歷,那么雙向鏈表它可以從兩個(gè)方向遍歷。

具體代碼實(shí)現(xiàn):

package com.ys.datastructure;
public class TwoWayLinkedList {
    private Node head;//表示鏈表頭
    private Node tail;//表示鏈表尾
    private int size;//表示鏈表的節(jié)點(diǎn)個(gè)數(shù)
    private class Node{
        private Object data;
        private Node next;
        private Node prev;
        public Node(Object data){
            this.data = data;
        }
    }
    public TwoWayLinkedList(){
        size = 0;
        head = null;
        tail = null;
    }
    //在鏈表頭增加節(jié)點(diǎn)
    public void addHead(Object value){
        Node newNode = new Node(value);
        if(size == 0){
            head = newNode;
            tail = newNode;
            size++;
        }else{
            head.prev = newNode;
            newNode.next = head;
            head = newNode;
            size++;
        }
    }
    //在鏈表尾增加節(jié)點(diǎn)
    public void addTail(Object value){
        Node newNode = new Node(value);
        if(size == 0){
            head = newNode;
            tail = newNode;
            size++;
        }else{
            newNode.prev = tail;
            tail.next = newNode;
            tail = newNode;
            size++;
        }
    }
    //刪除鏈表頭
    public Node deleteHead(){
        Node temp = head;
        if(size != 0){
            head = head.next;
            head.prev = null;
            size--;
        }
        return temp;
    }
    //刪除鏈表尾
    public Node deleteTail(){
        Node temp = tail;
        if(size != 0){
            tail = tail.prev;
            tail.next = null;
            size--;
        }
        return temp;
    }
    //獲得鏈表的節(jié)點(diǎn)個(gè)數(shù)
    public int getSize(){
        return size;
    }
    //判斷鏈表是否為空
    public boolean isEmpty(){
        return (size == 0);
    }
    //顯示節(jié)點(diǎn)信息
    public void display(){
        if(size >0){
            Node node = head;
            int tempSize = size;
            if(tempSize == 1){//當(dāng)前鏈表只有一個(gè)節(jié)點(diǎn)
                System.out.println("["+node.data+"]");
                return;
            }
            while(tempSize>0){
                if(node.equals(head)){
                    System.out.print("["+node.data+"->");
                }else if(node.next == null){
                    System.out.print(node.data+"]");
                }else{
                    System.out.print(node.data+"->");
                }
                node = node.next;
                tempSize--;
            }
            System.out.println();
        }else{//如果鏈表一個(gè)節(jié)點(diǎn)都沒(méi)有,直接打印[]
            System.out.println("[]");
        }
    }
}

我們也可以用雙向鏈表來(lái)實(shí)現(xiàn)雙端隊(duì)列,這里就不做具體代碼演示了。

9、總結(jié)

上面我們講了各種鏈表,每個(gè)鏈表都包括一個(gè)LinikedList對(duì)象和許多Node對(duì)象,LinkedList對(duì)象通常包含頭和尾節(jié)點(diǎn)的引用,分別指向鏈表的第一個(gè)節(jié)點(diǎn)和最后一個(gè)節(jié)點(diǎn)。而每個(gè)節(jié)點(diǎn)對(duì)象通常包含數(shù)據(jù)部分data,以及對(duì)上一個(gè)節(jié)點(diǎn)的引用prev和下一個(gè)節(jié)點(diǎn)的引用next,只有下一個(gè)節(jié)點(diǎn)的引用稱(chēng)為單向鏈表,兩個(gè)都有的稱(chēng)為雙向鏈表。next值為null則說(shuō)明是鏈表的結(jié)尾,如果想找到某個(gè)節(jié)點(diǎn),我們必須從第一個(gè)節(jié)點(diǎn)開(kāi)始遍歷,不斷通過(guò)next找到下一個(gè)節(jié)點(diǎn),直到找到所需要的。棧和隊(duì)列都是ADT,可以用數(shù)組來(lái)實(shí)現(xiàn),也可以用鏈表實(shí)現(xiàn)。

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • Java設(shè)計(jì)者模式簡(jiǎn)單工廠(chǎng)模式解析

    Java設(shè)計(jì)者模式簡(jiǎn)單工廠(chǎng)模式解析

    這篇文章主要介紹了Java設(shè)計(jì)者模式簡(jiǎn)單工廠(chǎng)模式解析,介紹了其簡(jiǎn)介,實(shí)例以及優(yōu)缺點(diǎn)分析,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • 使用maven自定義插件開(kāi)發(fā)

    使用maven自定義插件開(kāi)發(fā)

    這篇文章主要介紹了使用maven自定義插件開(kāi)發(fā),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • SpringBoot處理請(qǐng)求參數(shù)中包含特殊符號(hào)

    SpringBoot處理請(qǐng)求參數(shù)中包含特殊符號(hào)

    今天寫(xiě)代碼遇到了一個(gè)問(wèn)題,請(qǐng)求參數(shù)是個(gè)路徑“D:/ExcelFile”,本文就詳細(xì)的介紹一下該錯(cuò)誤的解決方法,感興趣的可以了解一下
    2021-06-06
  • Springboot如何優(yōu)雅地進(jìn)行字段校驗(yàn)

    Springboot如何優(yōu)雅地進(jìn)行字段校驗(yàn)

    這篇文章主要給大家介紹了關(guān)于Springboot如何優(yōu)雅地進(jìn)行字段校驗(yàn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • JavaMe開(kāi)發(fā)繪制可自動(dòng)換行文本

    JavaMe開(kāi)發(fā)繪制可自動(dòng)換行文本

    JavaMe Graphics類(lèi)中的drawString不支持文本換行,這樣繪制比較長(zhǎng)的字符串時(shí),文本被繪制在同一行,超過(guò)屏幕部分的字符串被截?cái)嗔?。如何使繪制的文本能自動(dòng)換行呢?
    2015-09-09
  • 將內(nèi)容寫(xiě)到txt文檔里面并讀取及刪除的方法

    將內(nèi)容寫(xiě)到txt文檔里面并讀取及刪除的方法

    本文有個(gè)不錯(cuò)的示例,主要講解如何將內(nèi)容寫(xiě)到txt文檔里面、讀取文件里面的內(nèi)容以及清除txt文件里面的內(nèi)容
    2014-01-01
  • Java實(shí)現(xiàn)數(shù)據(jù)庫(kù)連接池的方法

    Java實(shí)現(xiàn)數(shù)據(jù)庫(kù)連接池的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)數(shù)據(jù)庫(kù)連接池的方法,涉及java數(shù)據(jù)庫(kù)連接池的創(chuàng)建、連接、刷新、關(guān)閉及狀態(tài)獲取的常用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • SpringBoot的監(jiān)控及使用詳解

    SpringBoot的監(jiān)控及使用詳解

    這篇文章主要介紹了SpringBoot的監(jiān)控及使用詳解,Spring Boot提供了一系列的監(jiān)控功能,方便開(kāi)發(fā)人員對(duì)應(yīng)用程序進(jìn)行監(jiān)控和管理,本文將討論 Spring Boot中的監(jiān)控功能及其使用方法,需要的朋友可以參考下
    2023-07-07
  • SpringBoot 整合Tess4J庫(kù)實(shí)現(xiàn)圖片文字識(shí)別案例詳解

    SpringBoot 整合Tess4J庫(kù)實(shí)現(xiàn)圖片文字識(shí)別案例詳解

    Tess4J是一個(gè)基于Tesseract OCR引擎的Java接口,可以用來(lái)識(shí)別圖像中的文本,說(shuō)白了,就是封裝了它的API,讓Java可以直接調(diào)用,今天給大家分享一個(gè)SpringBoot整合Tess4j庫(kù)實(shí)現(xiàn)圖片文字識(shí)別的小案例
    2023-10-10
  • Springboot整合Dozer實(shí)現(xiàn)深度復(fù)制的方法

    Springboot整合Dozer實(shí)現(xiàn)深度復(fù)制的方法

    Dozer是一種Java?Bean到Java?Bean的映射器,遞歸地將數(shù)據(jù)從一個(gè)對(duì)象復(fù)制到另一個(gè)對(duì)象,它是一個(gè)強(qiáng)大的,通用的,靈活的,可重用的和可配置的開(kāi)源映射框架,本文給大家介紹Springboot整合Dozer的相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧
    2022-03-03

最新評(píng)論