QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4738|回复: 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
    / Z/ L, g9 p: }/ x6 s/ x( q4 f% x
    【Java演示】什么是链表?数据结构3 N7 [9 D% v( N' v; q
    一、单向链表
    ) _( F) t# p! l8 g; P. C
    : D& ]! {9 g% X% s+ F6 S* r" w' \ 1.png
    $ k8 O1 x, g8 q. `7 I( U链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。
    % A- ^" D& `; e! j* O6 Z单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。4 V( X6 n: U6 Q& G
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。" ~, H7 R2 G. W8 E- L: O% j
    7 m" c6 {) U- D
    什么叫随机存储呢?0 @' S& ?+ w8 }8 K1 F9 N9 Y$ N

    , f4 F# c: ~  F& Z0 ^如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。: b; {5 b1 X1 }! S5 F% U2 P
    上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    4 Q# A% Z6 `1 L! _% n6 X8 K' ^, y 3.png
    , x+ [' ]+ e) }+ D1 C5 P$ l9 d
    # y" s6 ^/ c6 }0 x, F) {

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

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

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

    4.png
    9 o, Y4 u+ X: f8 R. {% d' g- s% o6 A  ]* N* J& ^
    /**
    5 A+ G1 W) m8 U& y" V     * 链表查找元素( @/ J' D, N: v1 k& R, n3 _
         *8 B  k7 B, a  Q( T! l8 e" G! o4 E+ K
         * @param index 查找的位置
      ~/ G& l' V7 {" R) G4 d2 z: \1 Q     * @return index位置的Node对象
    8 }, M/ F% @, \  X2 {3 H0 V     */
    1 B* b4 Q* z" I9 c( C    public Node get(int index) {
    0 ^3 L. h: B8 `9 D- e        if (index < 0 || index > size) {
    % n) w6 c! R! ~4 o8 T            throw new IndexOutOfBoundsException("超出链表的节点的范围!");. X, [3 b, ~- D6 ?& n2 }
            }+ l$ X0 d+ ^) w2 T. M
            Node temp = head;; G4 u/ n! r7 h/ u
            for (int i = 0; i < index; i++) {
    5 o$ Z0 l8 G8 a7 @- W0 r9 G            temp = temp.next;2 L, ~: k0 J$ @" X' [9 w& c
            }
    : p1 {: j* |& |- r" T        return temp;+ \+ T" k& q  G
        }
    ! ?: @- J$ |4 G/ V/ |6 v# ~2 R
    ( W6 B- T; J& R

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

    2. 更新节点 5.png
    + Q/ W: ~/ h+ ^( ~( c8 U" E' L3 ^( \6 D' [+ j2 `
    如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    * x) q6 n+ y0 U如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)
    # {6 Z- U0 V2 H/**; C" @/ [! T% L0 o. J
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    , N/ Z( d. u& S  u2 T     *, C- H+ s1 c. U7 T7 r/ t
         * @param index 需要更新的节点的位置& `" H+ Q5 L, Y; ]6 t( }% C
         * @param data  新data# V0 n/ i% ^  C9 w. g: ^) c8 m, G
         * @return 旧data( @1 T7 ]$ S6 t: z, C+ f; w- j
         */
    $ i+ ^  ?8 e2 C# {7 f    public int set(int index, int data) {
    3 F, j) m3 W9 l8 T* i        Node x = get(index);
    # j3 M7 V6 E" a- c5 C: u        int oldVal = x.data;" {4 m' p& G  @" y
            x.data = data;9 g) B6 B3 A+ O
            return oldVal;
    4 J& X& L% ^% a3 |! I8 `3 J/ ]! p    }- h) u' r- b7 {
    ( D0 ~5 g- e. c5 V. L; W" p. x
    3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入
      * T* I/ x5 O) K& s  @0 ]- m$ ~/ Z/ n
    3.1. 尾部插入

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


    0 L7 q6 M' f+ K+ b 6.png   f% f: C+ T, h- e2 ^  F
    3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。9 P$ |# C: [1 i# C8 k& J* s& [
    7.png % n) _9 u' I1 D
    ! ?2 ^7 Y  o8 ~; M
    3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。9 X6 p4 n7 ^+ h8 H* m
    8.png ' N% ]" H  [* I+ C: K3 O

    # w# w, ]8 }4 _: }+ Q5 G三钟情况的代码合到一起/ {3 u1 L2 t! _% ~/ q4 o+ a

    ! d% L& Z0 l# T: S: Q+ Y8 A5 |/**
    ! w2 _' u0 Q/ s6 q9 ^9 q     * 链表插入元素
    1 P4 S; u7 K* t; T# }     *
    ( |4 W! T4 L( S0 C. s* v! Q3 r     * @param index 插入位置
    1 ^! l- K2 ?& i- D: ^' O' z" v     * @param data  插入元素 被插入的链表节点的数据
    + ~) Q& T& F8 S6 C8 w     */
    8 B8 W8 T% k3 n" e1 y; \+ T0 v2 M    public void insert(int index, int data) {+ }! Z0 d8 `+ H3 q3 g0 P
            if (index < 0 || index > size) {" K+ u9 {: ~/ C+ j) y/ }
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    + I" D+ k3 c! C% g: r: d- L0 t        }+ q* p% x1 ]& Z/ J5 z$ D% y; h
            Node insertedNode = new Node(data);
      b9 O' b6 l0 }! L% B, o" u        if (size == 0) {# j/ B& E4 D7 T8 u$ \1 Y0 v) r4 |
                //空链表( Z/ D. x5 W( K. F! ^! X
                head = insertedNode;" G& S5 z0 b# p: a5 S% r, F6 J* B% ?7 b; H
                last = insertedNode;
    * X2 ?) X" q7 V$ h8 r        } else if (index == 0) {1 ?2 ]& h; E+ B$ p3 l
                //插入头部
    6 a0 I' h5 b/ U9 a3 @+ F: c7 e            insertedNode.next = head;
    ; t1 D- R0 U# l2 H7 S0 ^/ X: n0 t2 q5 w            head = insertedNode;, Z. h) b1 ~# r
            } else if (size == index) {, g" }- C% B6 m) _
                //插入尾部  q0 L, i. k1 l4 h$ ?; V! C
                last.next = insertedNode;
    " o& Q" [4 b: f' {9 o% U            last = insertedNode;
    % @" A: A/ o  n0 F7 e        } else {$ o. m5 [* r, r. [4 L, ]
                //插入中间* V3 |  t1 p( l' C3 ]  Z7 X
                Node prvNode = get(index - 1);1 o( n; n/ j' M
                insertedNode.next = prvNode.next;
    4 i8 l5 C: n- S" k4 A3 e8 W& c; ^0 P+ R            prvNode.next = insertedNode;* n0 s( F! x# \* L  M  ]
            }
    ! @2 I7 q6 ^( k: g9 _( V  j        size++;
    ' m7 s$ }% ?9 F) t5 K+ C/ `    }7 ^/ e+ `- [( g1 `# \. {5 {; T
    & Y+ |* F  G6 d1 u
    /**
    2 _3 d* O* G/ z+ f7 q* Q) E- Q     * 链表插入元素
    ) L+ ^( O+ ^+ `/ x3 v     *
    . W+ [! f9 Q* i: W4 T& ]- v" p     * @param index 插入位置: }) E5 e" Q/ ?$ y& [
         * @param data  插入元素 被插入的链表节点的数据
    / i; n( U7 ~3 U1 l* C( t$ I. Z     */
    7 R# p6 F; B4 ?2 M9 P; |    public void insert(int index, int data) {% k1 n0 K5 g8 q- p% W9 |9 |  k
            if (index < 0 || index > size) {/ j8 ]7 ~% O  }( L
                throw new IndexOutOfBoundsException("超出链表节点范围!");) n: c8 ^$ r4 h& U/ S/ }$ Q5 k
            }
    . w7 M$ D  p2 A2 D% ^; ~9 L4 T1 Q/ n' d        Node insertedNode = new Node(data);2 j' |8 E" J7 k& f- p# Z
            if (size == 0) {: J  R. M: @6 G& x" k: X1 ?
                //空链表# W6 \! E1 l% b$ @5 }4 O
                head = insertedNode;
    ' \+ ~$ G: L/ h* J2 q5 w            last = insertedNode;4 K0 I& m: ~) z4 Q1 ^
            } else if (index == 0) {) o  y4 q) T& U  U8 v, ^
                //插入头部; b1 d& _* a( ?1 R6 c
                insertedNode.next = head;
    4 Z) E- ^, ?9 M4 H  E            head = insertedNode;
    9 R* a7 \) E2 p        } else if (size == index) {
    % E! `5 \1 X/ T1 j6 ^. u/ q            //插入尾部  W4 [( u+ @" ?) u
                last.next = insertedNode;
    0 s& Z3 D6 P/ K5 r" l2 L7 R            last = insertedNode;, ~' d, X' z; H& Q! X
            } else {7 S" @8 s# w/ N$ T$ {* F
                //插入中间/ c: [& r% i- Q, `# |
                Node prvNode = get(index - 1);
    4 x5 {0 Y8 E) L5 L, F* T- Q            insertedNode.next = prvNode.next;
    3 i& D* ]- J6 J$ P! [; g            prvNode.next = insertedNode;
    " v0 x7 i% Q! p        }
    , V4 ?- \7 H- q4 }+ x/ W# G        size++;
    3 S6 g+ h. m6 e; b* `) D8 G    }2 Y, [6 v+ N0 p
    4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除; R: M, l' ~1 I6 J' a
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即; J) S, w1 P2 M% t8 S$ r" W
    可。

    9.png
    6 V$ O$ F- [- t+ Y! Q; J& r( u- a( y+ o* P; A  Z6 C
    4.1. 头部删除

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

    10.png % J' q) A! W: K8 m, k1 Z
    $ p; _8 m2 b, g; ?; N6 B
    4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要
    6 F6 c, q  A7 n, @删除元素的下一个节点即可。

    11.png 7 P3 ~& l7 q! @$ K
      P4 [9 h1 M3 ~  a2 c
    0 R  Q/ f5 h6 O! U, {4 @! m
    这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
    6 S. j9 N$ l2 o8 P2 I; A5 M' J如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)" o- H: R6 d8 c
    /**4 S  |% I8 T/ }
         * 链表删除元素% v4 \2 s2 G( S5 ^; a
         *
    6 Q( w4 I8 Q( |% T# I. Z6 [     * @param index 删除的位置+ ^) J  a/ a2 _. T' V6 T0 G: Y
         * @return 被删除的节点5 k6 ~$ t9 L7 N' h) f3 ?
         */
    2 j" f% y  i: u! s& V    public Node remove(int index) {* _8 y) H0 w0 z5 t
            if (index < 0 || index > size) {+ L! o  F: u7 I- _0 F; D2 }
                throw new IndexOutOfBoundsException("超出链表节点范围");
    ; K4 `8 y) t& b1 `! E        }0 W* l. v; r5 z0 M7 {! ~" W& k
            Node removeNode;# ~- ^+ A! \5 }  o) a/ D
            if (index == 0) {6 k$ m% Z7 q$ @3 X3 D4 X8 V
                if (size == 0) {
    ' V3 p7 }/ a# [                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    # }0 |( y* U/ r3 u            }( U. t- j. L  y' K( S
                //删除头节点# i' ]7 Q6 ^. l$ {! k
                removeNode = head;
    & J( w: J; _1 l            head = head.next;8 m, X6 q; i/ s( r4 s
            } else if (index == size - 1) {+ T2 t) C  ?0 @+ W; F, A
                //删除尾节点7 N7 d6 d5 t) @2 e
                Node preNode = get(index - 1);$ W' h  m7 Y, d6 a2 `
                removeNode = preNode.next;9 R6 J( o0 z; }& B  \% @
                preNode.next = null;
    4 c6 j) J% ]0 z( [( X& u5 d7 L            last = preNode;5 x  I1 A* |% s
            } else {, {* H0 b% z4 p% u+ d
                //删除中间节点
    % t8 F" R+ j% Y4 X7 R# ?! g            Node prevNode = get(index - 1);
    3 T$ t" k$ E/ f; S            removeNode = prevNode.next;
    + O% [. C% H- H; U# R" W' {6 b            prevNode.next = prevNode.next.next;  M) Q, `0 w0 z4 V& _
            }
    % U" x$ s- A* {; p- q        size--;$ Q3 M( Z: P' i
            return removeNode;3 z, w& }% k2 h" @) [* u9 T
        }
    5 T( N  \5 v% o. o2 I7 LJava实现链表的完整代码package chapter2.part2;
    3 {" h, F& `3 q- r" T8 _/ u" g1 a. C' f( Z; K* N- ?) W9 `
    /**
    $ E- q+ L* g& H0 I * Created by IntelliJ IDEA.
    - A8 J! F4 l* v, K) e1 o7 ` *6 p) \3 }& A6 q% i, W5 @* V
    * @Author: 张志浩  Zhang Zhihao5 f& ?7 I3 m4 z" `$ l7 R
    * @Email: 3382885270@qq.com
    8 i+ J/ E! B% z * @Date: 2020/5/3
    0 J3 I; k# F0 C' t * @Time: 13:391 l' g2 D( X+ i2 @: G$ x
    * @Version: 1.06 k/ a9 g: p# O) z
    *// W5 r4 I3 V8 Y5 e6 |
    public class MyLinkedList2 {0 {1 s2 m% ~+ G8 h3 J/ y; Y
        private Node head; //头节点
    * x" v9 D5 L, K' x) e$ _    private Node last; //尾节点. ^5 N, d) y) M; g: p" h
        private int size; //链表实际长度
    / c6 G# e, Y; f1 d! z+ {: m$ \9 p/ a2 w5 |. i
        public static void main(String[] args) {
      c3 F' ^; p/ a2 g        MyLinkedList2 myLinkedList = new MyLinkedList2();+ Q+ Z9 _: H  ?2 ~
    //        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    ! W' P' r! N0 L' u+ b# f! ]" i' {//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
    - N- u9 \' s; _+ r        myLinkedList.insert(0, 3);
    " Y6 ?& r, `/ ~2 I# m% Q        myLinkedList.insert(1, 7);
    / S# q2 q7 J$ d7 O/ L! e' }! M( e5 R, G        myLinkedList.insert(2, 9);! Y& L: |: ~* [" h
            myLinkedList.insert(3, 5);& V5 _7 E- g' D# h) ]% K- {! A; Z
            myLinkedList.insert(1, 6);* U+ J" p1 N& V; _% B& ~) b9 j" O
            myLinkedList.remove(0);/ A3 Z- W7 T; Q5 `6 R
            myLinkedList.set(0, 23);! X3 F- f. H- }& h0 B# n# W
            myLinkedList.output();
    ( Q4 C) ]$ F' @( s+ U2 w$ v2 N    }
    2 F( N9 e, W0 M+ U7 U" p( ]) f4 i* y
        /**
    ) Z3 F& o6 A2 P! l     * 链表插入元素
    : L. G1 g( s+ K; p- S; j     *% h$ O* ~7 e; S1 {+ x6 r, s
         * @param index 插入位置9 T* G% P! v9 \1 D
         * @param data  插入元素 被插入的链表节点的数据, q  q5 v' s) b: r  J' e
         */
    / H* o, Y" _' [1 O9 T  ^  }1 h& j7 y    public void insert(int index, int data) {
    # K( i, X/ k) T4 f$ [3 M" b        if (index < 0 || index > size) {- ~& z- A, N3 Q" _6 f
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    9 P0 o5 B, I7 |6 [2 \        }+ Q+ _2 U# N) y
            Node insertedNode = new Node(data);6 d- E% I) }5 M( E. \5 [* Y
            if (size == 0) {+ l4 y, ^" ^9 I( _2 N) X8 ?6 J
                //空链表
    4 q- M$ k+ Y) S* R4 j; }8 a            head = insertedNode;# \+ P. F/ e% b8 n! d& n
                last = insertedNode;7 H! Y/ |0 a* W8 B, j: X
            } else if (index == 0) {* a/ G( ?& y' p0 o/ j
                //插入头部$ _+ J& q: V. F  @
                insertedNode.next = head;
    # p7 G2 Q* p# _" x            head = insertedNode;3 f5 t8 v2 t6 }
            } else if (size == index) {# I) P0 |1 T! ]2 }2 t. q- m. e
                //插入尾部- O4 G- _% U- n% P# }2 e& {8 _, b
                last.next = insertedNode;
    6 `! f+ k9 _, ^; X            last = insertedNode;
    - y! u, `& l3 E) ?9 Z' S        } else {* T0 i+ E& v# S
                //插入中间
    # x: w" `/ F& H( ?3 a" O            Node prvNode = get(index - 1);
    7 ^  a' P, z. _& Y, p( _; g6 ~            insertedNode.next = prvNode.next;
    / Z: D3 d# C5 _% s) S& ~0 D+ {. k2 }            prvNode.next = insertedNode;
    , L$ g) D& w, B% b        }! F, S. m; k# `5 e1 M( l5 s7 x5 I
            size++;9 G. T% Y: H( d0 m! e
        }  f" d6 {; ]: F$ {- D6 L" w

    0 h+ e5 }' C4 l' z* f    /**, n. `5 {% n# f# E. t7 c$ d2 {2 {+ x
         * 链表删除元素
    4 |6 J* @; v( G* r0 B     *3 g: _9 r( i; v- V
         * @param index 删除的位置. w) \  Q6 d  Q6 U
         * @return 被删除的节点
    $ `1 G6 c% C0 X% `3 z4 V- S     */. ?6 A0 H# P2 |
        public Node remove(int index) {
    / Q0 c& A$ H' T4 D) ^9 g) T        if (index < 0 || index > size) {
    4 t* E7 p0 _: ^& @/ `7 O  l9 _" l            throw new IndexOutOfBoundsException("超出链表节点范围");
    - L& B/ @  ^. u+ r- A& L        }
    : W! |! F- F: N$ }$ v3 j        Node removeNode;4 d) }! f/ ~: q, y- S1 ]
            if (index == 0) {
    * J- B) U" e  ^7 s# G9 j            if (size == 0) {
    0 H3 \/ m  r$ b                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    % U0 g6 v( D" q0 C" `& z+ D6 X- X            }
    0 j: x6 ^) f/ S6 K, L            //删除头节点2 R9 a5 U' U2 }( p- u- Q0 Q
                removeNode = head;
    . L4 P, R2 \9 W5 |            head = head.next;" g, X/ R0 C9 q2 J/ O$ ~' }
            } else if (index == size - 1) {
    ; V) h+ p0 d/ X' ], M0 m& N            //删除尾节点
    % v/ Q- x' q: A            Node preNode = get(index - 1);# A- h3 s% }2 c, {9 p# z
                removeNode = preNode.next;
    " N% p; E3 {# b& s! J) ]# ?            preNode.next = null;
    1 s+ J8 j  c. j, {; T- I/ k            last = preNode;
    0 w- w& J" M2 w/ ?        } else {2 }# R" D) }' B% e
                //删除中间节点- G5 ^* z, B, p; ?
                Node prevNode = get(index - 1);- ~* N; q; }: E
                removeNode = prevNode.next;
    5 R* r0 _8 A3 O( s% u3 i            prevNode.next = prevNode.next.next;  x# B: F' F6 ?; c6 U( J8 U3 W
            }
    : I9 O6 E/ Z2 T! V, x# P        size--;, I9 {* Z6 I$ K
            return removeNode;7 {. N) r* U8 o7 u5 t- D# @
        }
    # v2 ~& f" s) p. u) r" T
    & ]7 f8 @0 G/ ?! y    /**
    , I: Y1 M0 z. m. \     * 更新节点 将列表中指定位置的节点的data替换为指定的data。; k+ r- \( @! e
         *  v7 J2 t& K3 P# B* ?! v- Q* q+ @
         * @param index 需要更新的节点的位置2 A6 Q& D$ T% J- T8 m; _3 z4 Q8 Z
         * @param data  新data
    * [: T; K( [9 Q0 B* k( Z     * @return 旧data
    ' J( g, C( E* z4 V5 g3 B) B% u     */, g/ ]0 \9 F" Q. b$ {4 [
        public int set(int index, int data) {
    $ N% b- u' g9 j! i4 {        Node x = get(index);0 w- Z' n: @' Y" P6 L4 P
            int oldVal = x.data;* D& K  y. w/ F
            x.data = data;
      }2 j9 V% s& g, }        return oldVal;3 O. @4 Y. s6 W0 I) k6 G2 y
        }2 `7 U2 W7 i: l, C0 x. H9 B% ~0 a
      Y! n, s4 n* T% l7 D: A  C
        /**, B5 M* Z) ~  H, [! _) l
         * 链表查找元素& p+ I  x1 o/ S) h) n7 z
         *3 N$ C( X5 s, q! ^! u% R* `
         * @param index 查找的位置
    3 `8 N/ ^" D6 T/ o     * @return index位置的Node对象
      l1 G: U. V5 |     */
    ( K2 i% k. _1 I    public Node get(int index) {
    ! X# q: u* w( H& a        if (index < 0 || index > size) {
    / B$ W  v! W8 _7 B2 \* R2 J            throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    2 q; e1 p! t$ ?* X) c1 v7 Z        }
    . {  f8 C  J: |3 M, }) Z- ]        Node temp = head;8 a& F2 t/ h# g  f7 V' L9 A( m' J0 ]4 ?. z
            for (int i = 0; i < index; i++) {
    0 Q6 ~9 n0 ^4 e            temp = temp.next;
    . l% C$ z, Z0 e+ K: q- ~        }
    + z: N6 i. C) q        return temp;
    # b' I2 Z) T6 ]- C5 N7 S: x+ r4 V: `    }( m$ T/ p' x% d$ y

    , d& i$ T( t1 ?0 p) {    /**
    - Q* D- P. i; x1 c! p! G     * 输出链表5 [3 j3 y+ K% b1 o3 Y; r+ \
         */
    & k8 X3 @3 V, u3 ]    public void output() {
    ' U# s. K0 J: Y  E; h+ ~        Node temp = head;
    + Y$ l0 {" @+ c+ g, K2 m' ]+ Z        while (temp != null) {
    & `* M/ ^1 u$ D1 l* [% A  v            System.out.print(temp.data + " ");" q. o8 M$ c6 ?! X# |6 L7 r
                temp = temp.next;" O6 `" }" `' X4 u) [
            }* [# z( y) E5 e- R% A. Z2 Z
        }' R2 s- ^1 \( u* _

    # Z+ D' p# e: Q7 F    /**- ]% g( ~+ |. F! W
         * 链表节点) `! ~6 [! l( }  n! s
         */
    3 Q9 W0 @& k& ~% K. }7 E    class Node {
    - |7 Q% W8 u8 F2 T' _5 d! R        int data;
    1 ?" R+ t% F/ }% S7 L% W6 k        Node next;8 S: p- K* K' m, b3 O3 C" P7 q- H5 r
    ) N+ K+ P2 E1 q, |
            Node(int data) {
    4 X8 `0 d/ V' Y8 I            this.data = data;) S7 Q% k# Y" M
            }
    : c: _$ U. v5 P: C  A2 k8 u    }: M7 }" y$ s; B- o& H* h
    }# Y: \1 G5 @  Q8 L  F
    " m% c6 B! A: U% H) K# U0 z  c

    # W0 ?, e/ W6 f+ T# J* \. K二、双向链表 12.png 9 w4 I" Q, s& k% z* h4 f
    双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。( P/ z$ c1 l- Y9 F' q
    $ v: q9 Z. L+ C0 z  c# A
    * \" ^' {) q: {2 C$ ?

    # b* k1 Z' ~! p" w2 e" U
    3 S* y5 S  O" n' g$ ?/ z————————————————2 b. |; K: L* a
    版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。# C8 [: c+ V+ o; S; C% V# U
    原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468
    1 [! x% c9 G) k. n2 b; }% J% F3 L, q# a* c
    + l) W4 i1 y+ Q5 D' T

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

    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, 2025-7-20 03:54 , Processed in 0.812103 second(s), 53 queries .

    回顶部