QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5182|回复: 0
打印 上一主题 下一主题

【Java演示】什么是链表?数据结构

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2020-5-4 15:55 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta

    : b; w$ J8 D  h! k0 Q+ B" p【Java演示】什么是链表?数据结构
    0 y$ F$ h/ X8 u1 W4 K! ~) O; A$ m一、单向链表# O1 b% s  b2 F  ^) f5 s" t: b

    0 }1 ~2 {; F: o 1.png 7 I, J+ A  L* n* a! B
    链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。- u6 ~9 E% D. L- E8 b
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。' j/ F" L- |! |; U( |" c+ r8 ~$ S
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。
    ! b: t+ Q4 v8 q  z7 x% u; M9 g4 M/ U2 O' m  q' r+ O$ [
    什么叫随机存储呢?. C1 _* t0 m2 Y2 q

    " F% S& u0 K7 Q如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
      R& v) E7 s# m% H5 _- l上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    . u8 m, Z2 d# p 3.png
      E# k# w, p, z5 {% @
    ' z4 |8 B( _$ R" p1 v6 g

    图中的箭头代表链表节点的next指针。

    链表的基本操作1. 查找节点

    在查找元素时,链表不像数组那样可以通过下标快速进行定位,只能从头节点开始向后一个一个节点逐一查找。

    4.png
    / E4 @) H6 X% z1 j) _& j; ]. u" z! M. ^  S% n
    /**3 I5 O/ J1 }& x" V9 E+ J5 B
         * 链表查找元素
    ! m% L; }: h: Z2 S9 w6 r( z     *
    1 G0 S! N+ X. ^1 H     * @param index 查找的位置
    ; `+ q  r$ C7 Z& m( p9 r& |8 q) B- I     * @return index位置的Node对象7 r, e7 C5 z$ b" |* \. [) K6 }) q
         */
    $ i; Q7 Z  p  F" n- _& `- v    public Node get(int index) {3 k$ w3 h6 c" P6 q. c5 I9 {
            if (index < 0 || index > size) {
    , A% F& A) [3 n            throw new IndexOutOfBoundsException("超出链表的节点的范围!");! S* C6 }. f/ w  f: [/ Y
            }
    ; I1 U  E& g" v4 Q7 O        Node temp = head;1 ]2 i3 h3 L6 \  z1 }* _1 v! P
            for (int i = 0; i < index; i++) {/ Y3 g% D$ R7 U* t+ j" R
                temp = temp.next;3 M) V( G# Z# u9 b* f# L
            }
    / j; r- b. n) O6 I" R: A- c- q        return temp;! o# d! |. s2 o7 R
        }
    # J& m6 D5 a7 J8 K9 r# S/ |  {6 S# n- S8 [; G1 w$ E

    链表中的数据只能按顺序进行访问,最坏的时间复杂度是O(n)

    2. 更新节点 5.png / l/ a# g/ Y8 e$ R; k
    5 J" ^7 l4 L7 Z
    如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    ) O& h) N; \' o$ Y) z如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)3 a  j* ]* O) o! u' c( P7 Q1 k" s) |1 {# C+ X
    /**
    # z, V- ^. R: G  d8 B     * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    $ c; h0 k1 \# m  j     *) M0 {, V8 m- W( b
         * @param index 需要更新的节点的位置* p* C, \( P+ g
         * @param data  新data  O  n$ n9 A$ @. V: o6 R8 k
         * @return 旧data+ s: l" a6 k+ B1 Z
         */
    5 C! J% i3 g: A" p0 T) y/ n% I. C    public int set(int index, int data) {: h" c  A3 l- t: E1 R
            Node x = get(index);
    1 p  g8 N( X' _" h5 }! q        int oldVal = x.data;) |! c, P+ T7 p3 I( ?8 {
            x.data = data;
    1 W$ @! v7 d* y- A; q* p        return oldVal;
    ' J7 F3 `, M9 I0 Q    }
    1 O/ g7 j' `& @$ w& V* W. n4 ~7 g/ K7 F% K- q( m
    3. 插入节点

    只要内存空间允许,能够插入链表的元素是无穷无尽的,不需要像数组那样考虑扩容的问题。

    与数组类似,链表插入节点时,同样分为3种情况。

    • 尾部插入
    • 头部插入
    • 中间插入/ y, H! P, ^* f% A% C
    3.1. 尾部插入

    尾部插入,是最简单的情况,把最后一个节点的next指针指向新插入的节点即可。


    . O/ B$ }. ]- k* ^1 b3 N2 h 6.png
    9 J2 _5 T% j7 u2 d% W1 z, R3.2. 头部插入

    头部插入,可以分成两个步骤。

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。
      2 `  ?0 T6 B  \& F
    7.png
    8 G4 Z: }3 V" p& ]# n, r0 H4 {
    ( w9 Y% m* w6 e+ k: n/ a! K3.3. 中间插入

    中间插入,同样分为两个步骤。

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。
      4 }- ?- m5 s4 \# r
    8.png $ j& z2 n0 y3 {7 l/ y+ c4 P
    ( }$ A) A- c( M' s9 f
    三钟情况的代码合到一起  D$ X  L. |( \$ P6 H6 y
    : p: G/ F( ^" Y/ u3 j8 {
    /**. n2 m8 H+ _0 M, f
         * 链表插入元素
    8 @6 o6 B; Q$ k: G     *
    " f% f9 K9 q; S" l8 g8 A0 A     * @param index 插入位置
    % o- U' g- g1 A- i: _     * @param data  插入元素 被插入的链表节点的数据( o3 N1 }* z6 d' M0 _% D
         */
    * |9 V5 j% D7 J* H6 N' I5 c4 `    public void insert(int index, int data) {7 a. R7 g, n/ T: l9 v
            if (index < 0 || index > size) {" }- s/ e; S: M( ^& V' p, J1 P* ~% N
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    / y0 o7 ?3 D# Z. w' g4 N+ m        }1 i- j. Q% A8 `/ W2 d
            Node insertedNode = new Node(data);# u* G* ^  A9 S7 e# f: t; S
            if (size == 0) {
    1 e! `8 Z# a; [- L6 ]8 @            //空链表
    , z; z/ y# t4 v8 ?6 x! q8 E8 V            head = insertedNode;; |- ?2 e5 h. P5 Z. J
                last = insertedNode;
    ) D. N  p. R, @+ q! Y        } else if (index == 0) {
    9 |: }$ u% t) ^. r            //插入头部3 D& Q; f0 T& y8 o+ f) @# V5 C
                insertedNode.next = head;; Y( F# R; B( [, H! [/ n/ w. a
                head = insertedNode;
    ' L; ~6 \! e4 J8 d& t        } else if (size == index) {6 C6 x, H6 |& G, z& n' `
                //插入尾部0 r3 K4 E( E% `& W& ^; u% l$ ?: N
                last.next = insertedNode;9 \( T. Q, c- f# d! \/ J" {
                last = insertedNode;
      J4 C+ e6 E! o) k9 l        } else {' z9 C2 t. ~8 h# o/ t
                //插入中间
    ' I3 ]4 ?" @6 B            Node prvNode = get(index - 1);# m$ l: X( E  x( B' \; l" ^
                insertedNode.next = prvNode.next;
    & d; J- R4 d9 }2 I, ^            prvNode.next = insertedNode;2 u; h& V/ X" w8 [* D9 h8 m2 E& F
            }
    0 [0 \/ ^, K0 v+ k5 w$ s# ^        size++;
    8 F% D8 e0 \7 W% E. P2 X    }7 t; \3 r& f' _7 j& x
    0 [! P1 |2 m( J- j0 ~) m% W" O* N
    /**
    , U0 K. @) u) {! _- m& Q     * 链表插入元素8 K$ X5 S0 |1 ]
         *
    * m, W0 G% E1 a% l- x6 T# t( F     * @param index 插入位置
    0 [2 a9 J! a2 _6 a4 F) `2 F3 n* @     * @param data  插入元素 被插入的链表节点的数据
    9 j: W  V; Y. T, w     */
    $ Y  s. |- ?3 `# ^7 U, c    public void insert(int index, int data) {
    + ^. a: I# }3 [8 ]9 O        if (index < 0 || index > size) {# ?$ Q% g. l- O. a- {
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    " o  o( o/ R; x+ u2 C8 o" F        }$ k2 }* Z) k: G2 X1 y1 ?3 P
            Node insertedNode = new Node(data);
    9 e, u" G/ t8 M        if (size == 0) {& J' K. H/ ]3 N  r' e% |* r
                //空链表6 h, K7 o, s, i. o3 {( ^1 h
                head = insertedNode;* L, Y2 g5 v, v% M
                last = insertedNode;/ c/ A2 f+ s6 Z/ ?+ X! _
            } else if (index == 0) {
    " a+ {" R: ^8 f5 M2 e% R            //插入头部
    ) l+ l- j' [# v# |0 V' C# v            insertedNode.next = head;6 p# v8 y3 Q8 B) a6 h$ _# ^
                head = insertedNode;, t9 v9 A0 q/ g% j
            } else if (size == index) {& p$ w6 |% O' z) z
                //插入尾部; j7 z2 @3 U4 p* ~8 ]$ y: q6 j
                last.next = insertedNode;
    ' g1 K6 \7 d. I5 W            last = insertedNode;
    : W, e3 y6 p* V) |. i( `& u        } else {
    8 h. U: E7 c7 u, |& H& |            //插入中间3 J6 h$ Y* w2 @4 C
                Node prvNode = get(index - 1);
    ! ]' ~/ h7 j# Y            insertedNode.next = prvNode.next;
    5 Y+ J$ }9 E; `' H            prvNode.next = insertedNode;
    - c- D4 ?$ H5 m# a7 `" ]        }/ ?7 p+ Y+ r; ]# q& I3 P7 D' m
            size++;
      b' _1 @5 f" G6 H+ g    }
    3 e$ n8 e. Z4 N: e8 p' D) ~# U, r) z4. 删除元素

    链表的删除操作同样分为3种情况。

    • 尾部删除
    • 头部删除
    • 中间删除
      7 w+ {& m: o$ d
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即/ ^1 s0 B+ ]8 N
    可。

    9.png
    . G* A; a6 M( ]) M3 r1 h7 o" v! ?
    # o% i5 W' o+ }: [6 C4.1. 头部删除

    头部删除,也很简单,把链表的头节点设为原先头节点的next指针即可。

    10.png
    5 B( h7 E. p+ ]  B+ p/ z8 f( `8 c4 @* u: ]( M3 h
    4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要  f- s0 A! U" \- h! x" e( M! D
    删除元素的下一个节点即可。

    11.png
    - G% W; X3 m+ A1 l- Y" `( C! F) l
    ) l! B& A; W: f. y$ Z  E( K) n" u: l; d, b- k# `- B
    这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
      c7 S4 P% F' O6 U, t7 W如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)
    * K8 W1 G3 k. w/**2 `) R8 M$ X5 p1 L/ M
         * 链表删除元素) C% J  }, P& e. }$ P
         *
    / H# V- K/ A1 o9 Z0 f4 c     * @param index 删除的位置
    1 g+ N3 N" W' E$ m2 t     * @return 被删除的节点, b2 |: W1 V9 p" g' f6 }% V
         */
    8 ~! n) l( e. m% c    public Node remove(int index) {
    $ u& h2 `8 Q1 H        if (index < 0 || index > size) {  t4 u/ o% ?/ @; F6 q6 |
                throw new IndexOutOfBoundsException("超出链表节点范围");
    ) s  ~4 V) L+ @. y0 R        }% |, l6 ^  ?2 y  _( `
            Node removeNode;
    % \1 v; C2 ]- w, ]( e        if (index == 0) {5 f" ?' I/ |$ ~- K, y
                if (size == 0) {
    5 r" b8 l; O  ^# k7 S* g" n3 f. b                throw new NullPointerException("当前链表为空,不可以进行删除操作");
      n9 \; c2 d5 a3 z8 d! D+ }            }
    ! d, x+ T2 Q0 e  u            //删除头节点0 _0 T+ a* B0 l# t9 {+ x
                removeNode = head;
    # |& q; p. G5 d0 q) Q) {; R* N            head = head.next;
    ; @' v9 N' J1 K# b0 w* S        } else if (index == size - 1) {" L$ L0 t! ]& R, p4 E
                //删除尾节点
    & ]& X- ]$ Q0 R" C$ ?! z. B# _            Node preNode = get(index - 1);
    1 N5 H* Q5 A+ f2 s% E" E            removeNode = preNode.next;
    ; ^) ^8 n+ b4 L3 K            preNode.next = null;
    9 R/ ~. u( ?+ ^" F4 \            last = preNode;
    " {" J; C: J6 \, Y! G; _        } else {0 X2 S* ]" n. p4 X$ u
                //删除中间节点
    ) ]3 f0 k% Q% I0 ]4 R            Node prevNode = get(index - 1);
    . y1 A* c9 b! e0 h/ q& l            removeNode = prevNode.next;- n/ ~& _; z5 N& I! ?* P7 k
                prevNode.next = prevNode.next.next;
    , `$ }& O3 f5 x. b, L        }2 L( ^0 n  {! U3 m' C! S% w( h
            size--;. d& H3 w" g4 m$ ?! \3 [, k
            return removeNode;. @: Y$ d- ?6 H
        }
    ; ^! {$ F; M' `$ |6 L7 AJava实现链表的完整代码package chapter2.part2;
    ; T# ?& Z7 e; @2 m3 g6 _6 W- W9 U: q  B/ W* @4 U; i3 ~
    /**
    : n3 i) l$ U  ]2 D$ s( { * Created by IntelliJ IDEA.8 O# b) p) f, W% Z& ~3 t  w
    *1 ]! y. P2 g1 _+ ?* g% B, o( v9 \
    * @Author: 张志浩  Zhang Zhihao" f- P3 P2 u* Z& I5 n
    * @Email: 3382885270@qq.com
    ( `: w9 s* H6 _2 p5 `- s * @Date: 2020/5/3$ V  p( h7 J# c/ x
    * @Time: 13:39; e. m0 N# U: [; x. k3 ?: w
    * @Version: 1.0# f; I. o3 r9 j% y
    */
    # q) A" n5 ^5 apublic class MyLinkedList2 {( i. |. i2 C! F* q! m/ O: O2 l
        private Node head; //头节点
    " R% @0 O" ~1 Q0 i# F    private Node last; //尾节点, e2 h, c9 X& k# `* H$ C6 Z
        private int size; //链表实际长度. M" C1 ~# P8 E3 M$ R/ j
    + r' X5 o" N0 b# C  u
        public static void main(String[] args) {
    / h+ T, ]) Y/ b) a; t5 V) j/ u, l        MyLinkedList2 myLinkedList = new MyLinkedList2();1 R+ W: C: V9 s
    //        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    7 a/ {( T  I2 p) A9 X) B- I& j3 `//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围0 v# k& Y7 j9 @5 g. b  R- K
            myLinkedList.insert(0, 3);5 [) d, Q; O% ?5 w' a' G# G* u
            myLinkedList.insert(1, 7);) `, r. Y9 F2 N- a/ S
            myLinkedList.insert(2, 9);
    % x$ ?- G- {0 u0 u# Y$ Z4 c        myLinkedList.insert(3, 5);
    3 D, p5 l1 g+ M" y7 o        myLinkedList.insert(1, 6);' O; g4 q. O+ M, s
            myLinkedList.remove(0);5 g9 |, b& [  j# j- g0 H: r
            myLinkedList.set(0, 23);
    1 h. x7 a0 P, h' K        myLinkedList.output();
    2 e" i  p$ P& Q0 }    }2 W# K$ U# @$ x& ^

    # T  }0 x2 n1 p/ R  v3 h* l2 n    /**
    1 q% v4 B# T( m: F  Y6 j, {, F     * 链表插入元素
    9 A# r) {) p) D     *4 G9 f9 u! Z8 H! {
         * @param index 插入位置
    % D" h: k( f6 f) v& n     * @param data  插入元素 被插入的链表节点的数据9 s5 @$ A+ [1 m/ H* _
         */
    - W$ w+ m% \0 j7 B    public void insert(int index, int data) {! f$ h2 G$ Z- c; k1 D
            if (index < 0 || index > size) {" q! h. v& a8 ]  m8 k% @& {# I5 n
                throw new IndexOutOfBoundsException("超出链表节点范围!");9 J. T7 [$ ~3 [8 J# J' U( j/ k( n
            }
    $ J+ h8 N3 z! j$ T% s* f  ?# @        Node insertedNode = new Node(data);# S& n- w9 J, v* U
            if (size == 0) {
    / o3 R) N4 W( l1 b            //空链表
    / }* W$ R, i7 |, S- t7 o9 d            head = insertedNode;
    . g9 I3 N/ Z9 I0 T7 a/ x            last = insertedNode;* Y: }. B- R& X6 H
            } else if (index == 0) {
    ' `' k+ }* s' A2 E  z; g            //插入头部  x: n' b5 O1 [  n% X5 w7 T( r
                insertedNode.next = head;9 k- p. J: _8 C5 w1 \$ v, a
                head = insertedNode;
    ) c. ~" A% n0 O& f; t+ Q( x' {, W7 A        } else if (size == index) {- i6 W5 S% [1 i& }5 h
                //插入尾部
    8 `; I' G" @$ n. J# O5 w            last.next = insertedNode;# i- K  F! K0 U
                last = insertedNode;' u" |; p3 q& h
            } else {
    0 Y& h' U4 G* V- Y% ^1 W            //插入中间( ~* }/ ]" b8 d3 `: q
                Node prvNode = get(index - 1);
    . S- U4 G# P3 Y; y2 [, f            insertedNode.next = prvNode.next;! F9 ^; {  d2 v/ i) Y- F
                prvNode.next = insertedNode;' N: ^% }2 d4 u: z5 n
            }
    + y* c& ]9 o5 f7 |+ E7 v        size++;
    ) E4 i! }6 b8 E, ]: W9 _$ b" {    }
    - p. I9 e$ W( Z, H6 @  ~
    8 K; C# O$ o# m2 {  }, E    /**8 a% h$ d3 N* W5 o# F* P& H& l( _
         * 链表删除元素
    ) X: q. u' }' @6 c1 Y     *9 L: Q0 K- Q, s: c
         * @param index 删除的位置! U' n7 r1 I: I) \1 D' f# ]
         * @return 被删除的节点
    6 E! U/ x5 I& M- w  }* w) g     */
    5 q* T9 C  Y" o1 {- Z    public Node remove(int index) {
    ; S( m- k6 Q$ O4 D& `; I& O6 s# G        if (index < 0 || index > size) {8 U3 b& f9 T9 j$ H- l
                throw new IndexOutOfBoundsException("超出链表节点范围");
    % x+ B: o* `% N/ h4 ]        }
    ! J# E4 J+ L3 B+ E' C8 S+ ^; y        Node removeNode;
    : F/ z' s' S8 k- G        if (index == 0) {
    2 Q- K- {% a9 e( _5 ]6 c            if (size == 0) {: P5 k9 W. n1 O: V
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");; x. |3 m- R/ l: y) m
                }, Y; i' P- |1 t6 J& H( ?5 g
                //删除头节点
    , i6 S; t/ X: b$ O; M            removeNode = head;- E9 D! u) I& r  g& z& E& ]7 ]
                head = head.next;+ }2 `4 o4 F1 L! ]0 c" P) F+ Z! G
            } else if (index == size - 1) {' g, k$ r! x# H1 ]$ n; ^
                //删除尾节点. E3 [1 r( L; X9 |6 m2 z+ _1 e) G
                Node preNode = get(index - 1);8 W0 A/ W* u) u  x
                removeNode = preNode.next;( o% Z& F& [- h1 c8 Q: `
                preNode.next = null;
    6 a* }+ R& ^2 h            last = preNode;9 G5 N+ X4 R9 `  g
            } else {3 O! _7 I4 a. G% H1 `/ h8 F: z
                //删除中间节点
    2 k) n1 V/ v  C8 [5 T            Node prevNode = get(index - 1);1 Q! R: w" D4 p# ?2 y+ m' g
                removeNode = prevNode.next;
    % W1 a: s* u4 |& q9 m- K' o            prevNode.next = prevNode.next.next;
    " l) X! y/ K  V3 j' u        }
    0 ^4 D: T. f/ B( D6 G' M        size--;
    6 C9 _5 j8 f  C# x/ y# U' [& x        return removeNode;
    , W, p$ B9 m9 w1 E; E# C    }: w5 A, v; V7 {# m

    : r9 Q) T+ @# y) h5 a6 n    /**
    " N5 ?1 a5 j' X- f     * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    * ?" z: `) _+ q( q# q$ n     *. T- x3 W4 v) I% {, i2 o1 R4 K- t
         * @param index 需要更新的节点的位置
    6 R$ O# v0 c) }& F0 D$ o) j     * @param data  新data
    # F% B! {+ w) x7 ]) [1 A+ n4 \- a     * @return 旧data9 E0 @" b1 _) p' R2 l% P& j3 k
         */' `2 s7 F4 e0 R3 n
        public int set(int index, int data) {
    % O6 w5 _6 ^) u+ |! e        Node x = get(index);
    4 y, i' _3 H8 e5 T- p" i; n        int oldVal = x.data;  ~5 v  b+ e. K& H
            x.data = data;  N3 r% I0 [# x
            return oldVal;2 s8 E! ]; h( O$ a! a- i: f
        }1 z- z/ U+ Z! M2 \4 _: m; |# W! ]

    * ?% J8 y; y" m    /**
    0 g/ ]( {* g' m; E% s     * 链表查找元素) c2 u* r# j3 h1 \6 X, p
         *) _9 K# f0 Y/ E1 M/ Q' `, e+ {0 D
         * @param index 查找的位置
    4 |# k) g. t$ j$ M& b     * @return index位置的Node对象% K8 n. `: L+ p7 [+ R
         */8 s, G. S0 ?, C) ^
        public Node get(int index) {5 q) ]( o" t; r6 ~8 y
            if (index < 0 || index > size) {
    4 E* @" e. Q: V2 S            throw new IndexOutOfBoundsException("超出链表的节点的范围!");/ L2 i6 d) L3 L$ I3 o
            }
    & b. r$ |& ~2 F- d( k% T' M, d3 z        Node temp = head;
    , |% g8 N+ M. x1 t( T        for (int i = 0; i < index; i++) {: v. s5 v' G1 z8 F$ E
                temp = temp.next;
    3 f2 @3 Y; J  a$ t$ n% Z        }- S. S. {" r# `" R% Y
            return temp;: W' ]3 ]+ O  W$ n  z4 H+ L" \
        }8 y% C: v4 h7 k5 |' S  t
    " d8 F4 V; o  g7 a! s- H& ?
        /**
      U+ C' G" _% i$ q, O  @     * 输出链表" z& _& e+ o- S
         */
    # \: @- h, ]- ?4 T0 k    public void output() {; _' s. M' k/ ~8 `( I
            Node temp = head;3 d1 t7 V, a+ V, r
            while (temp != null) {" k. m7 J& G( G2 b( ~3 u: B2 i" o' o
                System.out.print(temp.data + " ");
    # z- g8 |0 Q, \4 v7 V* I            temp = temp.next;
    8 Y* ^, a+ @$ P5 @        }
    ) R; x5 J6 ?# I8 q" ]$ J, U    }
    / |3 G4 U  D# J# ^: j4 {2 o: p: w/ M6 Z7 S2 F* h
        /**
    + @, E! @) X8 J) h; c4 W- x     * 链表节点5 R/ o) a" ^) Z, k
         */
    0 W* X# Y4 R: }. I! U% D9 `    class Node {
    - |+ L; e3 O8 `$ k/ j& `7 b        int data;
    " M6 o+ P6 ]' j5 ^& T6 g# f, W        Node next;
    ( `, q3 r+ _7 N) p! {5 a4 R) V; Z/ V. a
            Node(int data) {
    . M% h: o# v. X            this.data = data;
    7 ~1 |5 ?4 Y; }: b        }9 V  k. `" O* t$ |8 N) d0 g5 ^
        }
    - w+ \9 r6 V# t  M}4 L6 v) V9 n+ C
    5 `+ V' h2 O: q+ o4 t

    ( w1 L3 g2 y+ Z4 I* e  T8 _二、双向链表 12.png " P7 O. v2 u% [# C+ G* G
    双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。
    9 O3 s5 t  K2 G- D" z
    ! w" T6 E) \3 l- c- A' U& P! e# D# u, s$ D

    ( Z' t9 ^0 x. T! u
    8 x% C1 E* j! e+ T. v————————————————
      A! _7 C5 W5 r1 h: P9 O' p: j" G1 p0 E版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    5 ~+ }0 |9 O  w1 r- _原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468" e2 H8 c: h, C; ]: S. A
    ' V( }$ o* x2 m* g  k9 n; {
    6 M- `5 u$ X, }8 C

    2.png (256.36 KB, 下载次数: 272)

    2.png

    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-6-11 14:12 , Processed in 0.430306 second(s), 54 queries .

    回顶部