亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

數(shù)據(jù)結(jié)構(gòu)之雙向鏈表(java版)

legendaryedu / 1126人閱讀

摘要:記得在一個(gè)公司面試上有一道題,寫一個(gè)雙向鏈表,包含鏈表的基本操作,插入,刪除,獲取長度等操作,由于時(shí)間匆忙,代碼寫的比較亂,連自己都沒眼看了,后來細(xì)想自己從來都沒有細(xì)心的寫過數(shù)據(jù)結(jié)構(gòu),總覺得只要原理明白了就萬事大吉了,事實(shí)證明,理論和實(shí)踐還

記得在一個(gè)公司面試上有一道題,寫一個(gè)雙向鏈表,包含鏈表的基本操作,插入,刪除,獲取長度等操作,由于時(shí)間匆忙,代碼寫的比較亂,連自己都沒眼看了,后來細(xì)想自己從來都沒有細(xì)心的寫過數(shù)據(jù)結(jié)構(gòu),總覺得只要原理明白了就萬事大吉了,事實(shí)證明,理論和實(shí)踐還是有很大差距的。
水平有限,如果有錯(cuò)誤,還請不吝賜教

定義一個(gè)內(nèi)部類Node用于存儲節(jié)點(diǎn)元素
class Node {
     private Node previous;//前驅(qū)節(jié)點(diǎn)
     private Node next;//后繼節(jié)點(diǎn)
     private E e;//泛型元素值
     public Node(Node previous, Node next, E e) {
         this.previous = previous;
         this.next = next;
         this.e = e;
    }
雙向鏈表的關(guān)鍵在于節(jié)點(diǎn)指針的轉(zhuǎn)移

下面以removeElement(E value)為例簡單介紹

    public void removeElement(E value){
        Node index=this.first;//創(chuàng)建index節(jié)點(diǎn)指向first節(jié)點(diǎn)
        while(index!=null){
            if(index.e==value)break;
            index=index.next;
        }//while循環(huán)用于遍歷整個(gè)鏈表來獲取指向要?jiǎng)h除的節(jié)點(diǎn)指針
        index.previous.next=index.next;
        index.next.previous=index.previous;
        length--;
    }

index.previous表示要?jiǎng)h除節(jié)點(diǎn)的前驅(qū)節(jié)點(diǎn)
index.previous.next=index.next;意思是將前驅(qū)節(jié)點(diǎn)的后項(xiàng)指針指向要?jiǎng)h除節(jié)點(diǎn)的后繼節(jié)點(diǎn)

同理index.next表示要?jiǎng)h除節(jié)點(diǎn)的后繼節(jié)點(diǎn)
index.next.previous=index.previous;意思是將后繼節(jié)點(diǎn)的前向指針指向要?jiǎng)h除節(jié)點(diǎn)的前驅(qū)節(jié)點(diǎn)
可能有點(diǎn)繞,簡單畫個(gè)鏈表結(jié)構(gòu)圖就可以很明了了

insertNext(E baseElement,E value)insertPrevious(E baseElement,E value)同理,這里不再贅述

DoubleLinkedList包含兩個(gè)節(jié)點(diǎn)指針(偽指針,java中沒有指針的概念)first和last,分別指向鏈表的第一個(gè)元素和最后一個(gè)元素

整體代碼
public class DoubleLinkedList {
    private Node first;//指向第一個(gè)元素
    private Node last;//指向最后一個(gè)元素
    private int length=0;//鏈表長度
    class Node {
        private Node previous;
        private Node next;
        private E e;

        public Node(Node previous, Node next, E e) {
            this.previous = previous;
            this.next = next;
            this.e = e;
        }
    }
    /***
     * 向頭節(jié)點(diǎn)添加元素,節(jié)點(diǎn)結(jié)構(gòu)對外應(yīng)該是不可見的,所以這里只傳遞一個(gè)泛型的值e
     */
    public void addFirst(E e) {
        if (first == null) {//鏈表為空判斷
            Node node = new Node(null, null, e);//創(chuàng)建一個(gè)新的節(jié)點(diǎn),前驅(qū)和后繼都為空
            this.first = node;
            this.last=node;//將first和last指針指向鏈表的第一個(gè)元素
            length++;//鏈表長度自增一,下同
        }else{
            Node node=new Node(null,first,e);//鏈表不為空創(chuàng)建一個(gè)前驅(qū)為空,后繼為當(dāng)前first節(jié)點(diǎn)的節(jié)點(diǎn),值為傳入的參數(shù)e
            this.first.previous=node;//當(dāng)前first的前驅(qū)設(shè)置為node
            this.first=node;//將first指針指向新節(jié)點(diǎn)
            length++;
        }
    }
/***
*addLast同addFirst
*/
    public void addLast(E e) {
        if (last == null) {
            Node node = new Node(null, null, e);
            this.first = node;
            this.last=node;
            length++;
        }else{
            Node node=new Node(last,null,e);
            this.last.next=node;
            this.last=node;
            length++;
        }
    }
    public void insertPrevious(E baseElement,E value){
        Node index=this.first;
        while(index!=null){
            if(index.e==baseElement)break;
            index=index.next;
        }
        Node insertValue=new Node(index.previous,index,value);
        index.previous.next=insertValue;
        index.previous=insertValue;
        length++;
    }
    public void insertNext(E baseElement,E value){
        Node index=this.first;
        while(index!=null){
            if(index.e==baseElement)break;
            index=index.next;
        }
        Node insertValue=new Node(index,index.next,value);
        index.next.previous=insertValue;
        index.next=insertValue;
        length++;
    }
    public void removeElement(E value){
        Node index=this.first;
        while(index!=null){
            if(index.e==value)break;
            index=index.next;
        }
        index.previous.next=index.next;
        index.next.previous=index.previous;
        length--;
    }
    public int getLength(){
        return length;
    }
    @Override
    public String toString() {
        StringBuffer sb=new StringBuffer();
        Node current=this.first;
        while(current!=null){
            sb.append(current.e+"->");
            current=current.next;
        }
        return sb.toString();
    }
    public static void main(String[] args) {
        DoubleLinkedList list=new DoubleLinkedList<>();
        list.addLast("value1");
        list.addLast("value2");
        list.addLast("value3");
        list.addLast("value4");
        list.addFirst("value0");
        list.insertPrevious("value3","insertValue");
        list.insertNext("value3","insertValue2");
        System.out.println(list.toString());
        System.out.println("鏈表的長度是"+list.getLength());
        list.removeElement("value3");
        System.out.println(list.toString());
        System.out.println("鏈表的長度是"+list.getLength());
    }
}
如果不太了解雙向鏈表的結(jié)構(gòu)可以在紙上畫出每個(gè)Node以及指向關(guān)系

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/66831.html

相關(guān)文章

  • Java集合LinkedHashMap源碼解析

    摘要:底層基于拉鏈?zhǔn)降纳⒘薪Y(jié)構(gòu),并在中引入紅黑樹優(yōu)化過長鏈表的問題。在其之上,通過維護(hù)一條雙向鏈表,實(shí)現(xiàn)了散列數(shù)據(jù)結(jié)構(gòu)的有序遍歷。 原文地址 LinkedHashMap LinkedHashMap繼承自HashMap實(shí)現(xiàn)了Map接口?;緦?shí)現(xiàn)同HashMap一樣,不同之處在于LinkedHashMap保證了迭代的有序性。其內(nèi)部維護(hù)了一個(gè)雙向鏈表,解決了 HashMap不能隨時(shí)保持遍歷順序和插...

    QiShare 評論0 收藏0
  • 這幾道Java集合框架面試題在面試中幾乎必問

    摘要:若遇到哈希沖突,則將沖突的值加到鏈表中即可。之后相比于之前的版本,之后在解決哈希沖突時(shí)有了較大的變化,當(dāng)鏈表長度大于閾值默認(rèn)為時(shí),將鏈表轉(zhuǎn)化為紅黑樹,以減少搜索時(shí)間。有序,唯一紅黑樹自平衡的排序二叉樹。 本文是最最最常見Java面試題總結(jié)系列第三周的文章。主要內(nèi)容: Arraylist 與 LinkedList 異同 ArrayList 與 Vector 區(qū)別 HashMap的底層...

    bigdevil_s 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<