QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5026|回复: 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
    4 Z+ ?8 l8 Z8 z- }+ V( E
    【Java演示】什么是链表?数据结构
    5 W  _5 ?, ]( X- ^5 N" v5 [一、单向链表( `+ |$ p4 B, j6 J, l

    1 k9 w* Q3 }1 {- ^ 1.png 0 p0 m' _! i* t6 ]# p0 }: L
    链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。1 m; Q9 m  B( `
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。% X: G# K( `; C/ T
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。
      u6 Q' V* @, v$ c" S9 F3 l  j6 |% t; F: t  Z* x: k4 ^- v, a4 E3 b
    什么叫随机存储呢?
    " m" k, I- I, J: _- @! W( {* s" ?) H4 K; G( Z# w
    如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。, b+ x/ Y: i; e9 U( U5 P- T, y
    上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    . o: Y( L1 }7 n 3.png
    ( b. ]5 e2 V. y" A- {0 S/ a( P$ P7 J1 B) Q0 x

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

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

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

    4.png - u( f$ Z2 Z! m- B  P
    6 j, F: s( T7 S& l* A& |
    /**/ S; S0 m6 O7 N# J( t2 v
         * 链表查找元素
    + Q- o# F' {& {9 Q; a, ]2 U* R# ?3 L     *
    0 x9 }( `7 n2 T, [) }     * @param index 查找的位置
    9 T# P/ p; Y3 w9 e! }     * @return index位置的Node对象
    ' g! c# f9 f, Y4 W6 Y: m     */+ S, ^# }2 z8 K5 z3 {7 R7 r0 N! v
        public Node get(int index) {) {7 G% h: ~) {) W: U
            if (index < 0 || index > size) {
    % L8 M* Z+ U. n/ Q( l# a7 q6 v  V            throw new IndexOutOfBoundsException("超出链表的节点的范围!");0 B" Y! Z% j" @. `' O2 Y: l8 F9 e$ ~
            }4 G& a3 U+ W9 Q
            Node temp = head;9 F8 [9 X" u$ {" n$ S0 i' z
            for (int i = 0; i < index; i++) {
    % ^. ~. b) a  d            temp = temp.next;' [0 i8 T: X9 E3 v% f7 @
            }' k  M* q. j" j
            return temp;
    " N0 J& \- R, _    }
    2 ^' v/ G+ [% A& p" G: |2 G; Z6 U$ `/ ~9 [7 Q

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

    2. 更新节点 5.png
    9 w, ^& E9 y7 P8 M8 e$ _5 D6 o8 P+ R- W' w( l  h) T# C# n$ u, h+ f1 h5 b
    如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。/ z& A6 O9 U2 d) `# }
    如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)  i. I- f: W0 P3 C8 y  e5 s
    /**, b0 F' a. R9 e; z' }
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    ; f3 V+ Z1 {9 X     *
    0 _7 c$ {9 P/ D$ v& S, [  {, c     * @param index 需要更新的节点的位置
    $ j5 o4 @$ \8 Y2 k! p     * @param data  新data, k' g- F% `0 X' k% A
         * @return 旧data
    0 k1 C/ I4 B2 n4 C     */
    - D' v* e& p+ i. l* `8 j    public int set(int index, int data) {
      [8 W- h  H8 k% G0 O& Z. N- E' u; \        Node x = get(index);" ]  b  ^: V1 {
            int oldVal = x.data;
    5 i& p& a5 z$ y7 r" |/ S        x.data = data;
    3 u3 [7 v  j1 e; S! t9 A/ L! r. k        return oldVal;
    $ E4 q) G$ S$ h& L: |9 {: l    }1 q4 B9 d* t% K7 g

    1 u8 @0 C4 s: r, K3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入7 X0 L8 ]9 J& K
    3.1. 尾部插入

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


    1 O- S  R2 ]7 i! p8 W 6.png
    ( n& x  d  P( \1 K- Y( _3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。' m1 A7 K% G' p
    7.png + K! b2 ^, u9 Q0 X5 M; G
    : y# A) d6 D2 `2 I8 s) r% g) x
    3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。
      6 a# \2 e$ o7 Z' |& O
    8.png : O$ O/ T6 E3 C/ m. U% ~7 M

    8 m# m! ^+ N/ C7 h9 v/ d三钟情况的代码合到一起8 W# B7 H" b* I! b. F) j
    ! A* v1 Q) i1 z* L7 W- }( {  S$ w
    /**" s9 H+ W- U1 ^& M
         * 链表插入元素
    . f0 U1 |/ m2 [; |     *4 m4 @4 Y( b7 R; e* e8 u9 I/ A, q
         * @param index 插入位置
    5 y6 v0 U1 K4 g9 f, a5 G' o. b/ D     * @param data  插入元素 被插入的链表节点的数据5 G8 g) U, N0 m! r$ E
         */  ^7 W/ W7 B4 z  i* c- v
        public void insert(int index, int data) {  y. P/ }% q* s  I
            if (index < 0 || index > size) {
    9 t* v/ F1 X; x3 m, b8 s            throw new IndexOutOfBoundsException("超出链表节点范围!");
    - {6 r; a9 R, q. v8 q! |1 Q        }
    5 a% ?& x* T1 @: u' o        Node insertedNode = new Node(data);" o6 K+ ?6 ~5 R; A6 S! R
            if (size == 0) {* z5 N3 U2 V  d# ^+ ~& u* H
                //空链表: a# i' ?8 J) [" S8 _  H" c
                head = insertedNode;
    " z7 k: `0 X# Z* Q            last = insertedNode;
    + y1 l, X4 m  n3 `6 s: z% R        } else if (index == 0) {
    ) @$ |( S8 j6 j# L' u0 u1 Z2 M+ k            //插入头部0 ]) `/ n1 N% R, g# m3 ?1 h
                insertedNode.next = head;
    9 M% Q! B- r0 m; n            head = insertedNode;
    0 c) N+ c) u6 q1 W* I9 T% L- f        } else if (size == index) {& B# f# T, s- D
                //插入尾部8 M* _* W1 E. ~# E/ t; O- W
                last.next = insertedNode;- Q; P, D( C' m: _2 Y2 \
                last = insertedNode;* s! L( E: ^. u( N
            } else {% ?: k6 b+ p5 e6 R- `. v1 }
                //插入中间
    + f6 W; p! y& m, H            Node prvNode = get(index - 1);& e" l$ D8 Z7 u$ ]9 Y$ v
                insertedNode.next = prvNode.next;
    ( @1 B* W8 D% ~6 [* u& b            prvNode.next = insertedNode;; y6 s/ H6 B1 b( b
            }
    * R' I% I" ]6 h0 Q% G        size++;
    ; @  Z9 r/ r, P    }
      O$ K$ J9 k& n5 w
    # h, O. K* H( D( c/**/ m  H8 s9 d9 ^1 m! R; [" B
         * 链表插入元素
    * w) p& S  w* U     *' {; s5 L! |6 F
         * @param index 插入位置
      c8 k5 I! j" K* }6 f+ t     * @param data  插入元素 被插入的链表节点的数据
    : X- M+ P9 v# v' G2 J& W: `     */
    ; F9 p# P4 l8 S( D1 i* g& x- Y& o    public void insert(int index, int data) {( ^5 o* d7 G" P( N
            if (index < 0 || index > size) {
    6 s( W; \: F6 n) d9 |            throw new IndexOutOfBoundsException("超出链表节点范围!");
    ( a: \3 M4 ]$ f0 _% _; S# R        }" \' F( J+ ~6 O) z; x# d
            Node insertedNode = new Node(data);0 n, }( M7 c. Q+ \
            if (size == 0) {
    # G. z& ?% G9 ^4 _            //空链表
    . I$ s. i/ ^$ I. B/ J            head = insertedNode;5 h' X' F7 G9 b$ M1 D3 [( \
                last = insertedNode;/ V9 ^1 R: b- e* c; y, O
            } else if (index == 0) {
    $ P2 Y$ N1 d) ?  H' u( c            //插入头部
    ; a7 [6 s* X& L0 h3 C            insertedNode.next = head;
    / n5 C+ \, f6 v            head = insertedNode;: ^& V* d" A3 o+ a: K; A
            } else if (size == index) {
    0 f: ]! q8 O$ t+ v            //插入尾部
    & g4 E0 d9 n* K( l/ A, B) t5 D            last.next = insertedNode;& d; j6 K* C: H. a) P& z: z& {
                last = insertedNode;* b3 k+ h! {( q2 ]8 Q2 h
            } else {7 }1 N7 g  g, w5 y& D
                //插入中间! k; G  v! B" s7 H7 R
                Node prvNode = get(index - 1);
    # ]0 |: x/ ?2 o6 H' M8 d            insertedNode.next = prvNode.next;- q9 i9 {+ d6 L" D
                prvNode.next = insertedNode;
    ! [5 h+ V# N" [0 p: y# X7 i! z        }# Q1 ]9 r* J  A6 y8 B  m
            size++;
    & P# \& L9 C' b& ]" U  r# k$ C    }; \" N+ R/ l) l$ P( g/ q( g
    4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除
      4 A# Y/ C0 T/ {/ \5 `6 R  H
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即3 }) Q- P+ d. i- E. ^$ o) M
    可。

    9.png
    ; Y+ Y2 z3 k' w: v+ b8 T: |" Q6 @  v( b7 a, J! L: j
    4.1. 头部删除

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

    10.png 1 t! o* M9 t( [) A" D$ ?

    0 ^& g+ Z* c  Q( d+ \4 |. z. V* Y' n/ f4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要# d5 y6 n$ @  _, C2 D% _8 z
    删除元素的下一个节点即可。

    11.png % [0 a6 U% g0 _" [& \! t# L

    ' ^. G4 [9 _; _) @. Y- H
    + ~- ?1 [! X+ u& \+ m, |+ I4 \这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
    * b+ O; M0 g6 X9 b: K; M5 m如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)
    3 z8 P" h0 E* [$ y% N1 e, t! P/**: T; [! l3 U! d) H5 D! G
         * 链表删除元素6 ~1 ^; o5 [- G+ @# L
         *& l. |8 p( w5 j: H/ p& [& ^$ S
         * @param index 删除的位置
    * Q$ E2 O  x, @* f# U     * @return 被删除的节点3 b% j1 y8 L0 k( L2 {
         */
    8 W: _9 `3 J7 G/ ~. l: ?6 q    public Node remove(int index) {2 X! Q! Q' H9 h& J0 ~3 W
            if (index < 0 || index > size) {
    ) E7 ]* g% D+ f! ~, b2 P            throw new IndexOutOfBoundsException("超出链表节点范围");
    & T$ z, |, k5 N& U9 k, h  n        }
    ) X6 K  e. Q% [- _$ }  ~+ x4 @        Node removeNode;" G% _/ N( C1 c  z' {
            if (index == 0) {
    2 v" J* ]* w  c$ ^& E' `            if (size == 0) {
    ! s+ I( V4 ]7 D& \5 i! ]; N8 |                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    ; j; `, o. D4 g" f8 a            }
    6 ]8 b# c2 x1 v" r            //删除头节点
    ; x' ?- N$ k8 E  i# l# W            removeNode = head;; t3 z% s5 v# Z: T* A/ Q* T9 \
                head = head.next;9 c& \% U. s8 j- v) V& I8 B
            } else if (index == size - 1) {
    * v! O' @9 e$ s: B            //删除尾节点
    # }- j7 C- `+ J% {* l8 w* b3 i            Node preNode = get(index - 1);
    , V6 W  T- V4 a1 ?& R: w            removeNode = preNode.next;
    1 v# o( Y5 N6 I4 a$ W# ]4 b; p5 z            preNode.next = null;
    3 S, C8 i, c1 T  n            last = preNode;+ ]! {- Y' L" c+ ]8 ~9 Q7 s! u' w; k
            } else {" U; c7 A( f8 m* j  S8 b; M* E! p' M
                //删除中间节点  V- x1 T6 b1 @. ^/ W
                Node prevNode = get(index - 1);
    + a& f; m# W9 Z" r  U( ]- L3 k* ^            removeNode = prevNode.next;! \( R6 P" i& {, j4 B3 m
                prevNode.next = prevNode.next.next;7 F2 g+ v  f8 o1 n
            }+ p+ b) }4 s- [
            size--;7 {! @# h8 K( {9 L8 ]
            return removeNode;
    7 Z; P. b$ D9 }' i/ w! z0 I    }
    & i7 G+ Q  s. @2 g6 I$ OJava实现链表的完整代码package chapter2.part2;" _' B1 t* N9 \0 o3 c& O8 Y: E! d
      D0 Z2 O" e* i5 G$ N7 r- U
    /**
    # T, r. h: N3 {, |; s$ p * Created by IntelliJ IDEA.$ N! h6 T, I, z! ?$ z- _
    *- P* @! [- J$ w8 U* _/ [
    * @Author: 张志浩  Zhang Zhihao
    # w7 u- O! X+ s" u4 J7 P4 h* h * @Email: 3382885270@qq.com! _# l3 i9 g8 N' P& l
    * @Date: 2020/5/3+ }. p9 a! D, t1 H$ b
    * @Time: 13:39, _5 R! A/ l8 a9 t' {2 O) i1 _
    * @Version: 1.0# m4 k8 N2 M; [: _$ M. a- |
    */; U7 O5 g1 [8 ]1 f8 z
    public class MyLinkedList2 {
    : i/ ~! G4 J5 r' d9 \; y    private Node head; //头节点) r) u( H! i/ {' L' s+ L
        private Node last; //尾节点
    % a6 {- R8 j; M0 u1 Y! [. _* d    private int size; //链表实际长度; O( W1 n6 I$ ]

    ! H% l+ D2 L, V# `4 A; n    public static void main(String[] args) {4 a4 Y% g# T9 [3 B
            MyLinkedList2 myLinkedList = new MyLinkedList2();
    ) s6 o. M/ \' r* E0 M//        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作  M: t" v9 |; U9 Z& W& V
    //        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
    6 E2 s" I# g9 B( c- z% b        myLinkedList.insert(0, 3);% N0 W# b  }; Z
            myLinkedList.insert(1, 7);
    9 G9 D4 O8 N5 \* |% f8 N9 O  M& j        myLinkedList.insert(2, 9);
    ) l  E  n( _, a7 M' K        myLinkedList.insert(3, 5);" e! f9 M( W+ n5 ^! L) V+ p
            myLinkedList.insert(1, 6);  b: f3 K; t2 P) j
            myLinkedList.remove(0);8 F2 K9 F9 y) F/ m
            myLinkedList.set(0, 23);
    - E7 Z5 K: K' R* C% J3 A+ N1 w        myLinkedList.output();! ]* y8 Z; K9 {! s7 A: g( M
        }
    " v2 u+ C+ z: H/ s$ f6 [, `0 w9 W- \/ d1 d; u* ~
        /**( O+ R- U" y, r1 `
         * 链表插入元素4 F& [* a* a$ F
         *
    & T  x9 t" F# T1 z$ p+ [/ ]     * @param index 插入位置
    8 V  h# j1 S& ]4 S0 n* c8 I     * @param data  插入元素 被插入的链表节点的数据! Z. y) |5 h0 `. L
         */
    / |: H  H1 r& q1 `    public void insert(int index, int data) {
    0 V  O8 B' T8 e# R6 N        if (index < 0 || index > size) {# A& b# p4 J! u# u
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    1 Z! @- ]' x" V        }
    ) }/ U0 Y3 b/ R+ O' y1 T7 Q2 o        Node insertedNode = new Node(data);  m) [* T! z* H9 {2 ]2 E
            if (size == 0) {2 a4 L( _: W# k( y) C
                //空链表
    " Z" z# J; P# u2 U- z% K            head = insertedNode;0 h0 r2 {8 ?/ R
                last = insertedNode;/ s$ {7 l4 e! A6 c4 }
            } else if (index == 0) {1 R7 g* ~0 M7 a1 M7 @6 ?
                //插入头部  U" D8 g" A2 u" L
                insertedNode.next = head;5 I/ S5 V; r5 d, a% O
                head = insertedNode;
    ; q( z" [4 W- q" T        } else if (size == index) {/ f! Q' y% V( d. G" x  O$ T
                //插入尾部
    ( o5 _" M6 {- b            last.next = insertedNode;6 W3 b, C$ W6 E$ J: n  l, d
                last = insertedNode;4 x1 T9 G: n8 P' y# X) j0 B' ~
            } else {
    6 ]9 T8 n: g/ M+ g2 Z' l9 T) t, N* u            //插入中间% K7 G) f0 i5 E/ I% `" |( L
                Node prvNode = get(index - 1);
    1 q) \' A- d5 i) F( a            insertedNode.next = prvNode.next;8 T  b3 S3 i& ]6 m
                prvNode.next = insertedNode;
    . R) e- X/ o, v$ `2 i* X$ [, ~        }
    / Z! l6 A  y" }: J% V        size++;0 \/ d. o3 Q( t0 G% L
        }
    0 C& ^2 z% O% _" g* b3 ?2 m- @8 L& r  C% O6 N+ T
        /**
    ' W. r# e4 _  V1 ^     * 链表删除元素
    + z5 G5 s% w5 ~% j     *6 |. i* i* M+ b, E& c
         * @param index 删除的位置
    . A! s- {% z* i0 r' W" n% u     * @return 被删除的节点' P! [8 M/ V% n% }2 _$ X
         */  A7 O) r/ _& Z: l& ]/ Z. K
        public Node remove(int index) {7 I) y  |- d1 B7 C/ R
            if (index < 0 || index > size) {! d' L/ l+ ^  s" h& o3 S) r  w
                throw new IndexOutOfBoundsException("超出链表节点范围");
    * P/ T( w: v0 Q( J# m& G        }& @5 z9 U, T+ M. `+ @3 F- f
            Node removeNode;/ Y) D0 X% Z( L# q2 r2 b
            if (index == 0) {
    4 v; e5 w' f2 t$ Z. X6 w+ x3 Q            if (size == 0) {
    7 c1 U* j# J5 }8 C9 y" v                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    - r" r1 x# L, T+ a; H            }# ^' {$ p  R9 S; r$ J0 e. }
                //删除头节点
    * ]) L2 K$ Y0 b; `2 w4 {) o8 ~3 P            removeNode = head;
    # J. a/ u" o7 A3 d            head = head.next;: Q9 O1 q- c1 P. J
            } else if (index == size - 1) {- z7 h7 ]8 U8 f; K* a3 |, \7 k
                //删除尾节点
    , p9 O( W; @0 u            Node preNode = get(index - 1);' d  |" B% q% T6 ^! g# S$ S
                removeNode = preNode.next;
    : s/ `* b0 l# I- E% i            preNode.next = null;
    % Y& {$ n" @4 v' ~6 \2 G            last = preNode;
    $ V( c4 {7 T0 _9 }# b. U        } else {
      b" E6 a0 r& s) K9 E* D2 V4 X+ L  t            //删除中间节点% F- a9 i' e1 Z, s. x( K) U
                Node prevNode = get(index - 1);9 ^8 Y$ L. L; U8 F4 Z! r4 E
                removeNode = prevNode.next;
    ! Y9 \! a- c) o/ T0 g            prevNode.next = prevNode.next.next;
    9 C  h, }. Q" L# ]# ]) Q        }2 r; W. j, V% ]
            size--;
    : S+ E6 h2 K: O' q' Y        return removeNode;
    1 ?3 H0 }4 I2 r& ~) g' y; T    }
    & c( l  ]1 K: P5 J6 i* u
    2 @" x+ b+ W5 d" R! ?& ^    /**
    9 z+ u* l7 e( ?     * 更新节点 将列表中指定位置的节点的data替换为指定的data。: |  A- g% F) t: T' b
         *
    - B! F3 A$ u5 [+ v9 M5 N5 b: W& ^     * @param index 需要更新的节点的位置; `9 @2 P/ n3 Q  y) I& X
         * @param data  新data& p4 ^: y: C9 G) a5 g$ A: E
         * @return 旧data
    ) y5 l, Z. `( |( X. n4 N" o     */2 a8 I( d2 V0 X
        public int set(int index, int data) {  R( |- b2 a' ?3 n$ j
            Node x = get(index);
    % ^/ m; [; p% Q+ ^+ I( T        int oldVal = x.data;* l2 p$ K% p+ s8 y6 r$ w% q
            x.data = data;2 ^5 E5 G3 N& W
            return oldVal;
    , A, V2 ]# E+ P, Y3 p5 d3 {    }0 x2 o! `5 ?( n7 T' z
    " A+ L9 p% H+ r; w9 f, z: g, J; T
        /**
    ' L& j: S$ `+ l, F     * 链表查找元素
    6 ?- _' p* G1 v4 U4 W9 u) |     *
    " f- S  G  |9 S9 P6 _/ ]2 p  i' R     * @param index 查找的位置
    4 X0 Y) w: i0 y- ~4 w7 m# m- M     * @return index位置的Node对象
    # V- J1 s' L9 |  u% `! X1 G     */
    1 i2 Y4 B. A9 w2 x+ a: E8 H, v( O/ o    public Node get(int index) {
    / E# N: I' ?% G        if (index < 0 || index > size) {
    & V4 z) D# E  X" F            throw new IndexOutOfBoundsException("超出链表的节点的范围!");2 o9 x" ^& p4 M
            }& x+ r0 b$ I; D( B5 A
            Node temp = head;8 u' F8 P. O! N9 O1 w
            for (int i = 0; i < index; i++) {* n! R9 @; x4 T; X  d2 J2 ^
                temp = temp.next;, N- @4 w: `+ a# Y- T
            }
    : C) x+ {$ n( Y7 h3 m! }- g        return temp;
    # i, }' a- a0 A* N    }
    1 x3 ~! u5 Q3 M, p5 L9 i/ M" R; b3 l2 d0 f% s( Z# m+ @
        /**" ?/ Y: z- Y" }; A+ `- j
         * 输出链表  u4 ?, r/ L3 y- Q6 t+ u/ g3 m
         */
    ; H1 w% V9 w" j& d# B8 N    public void output() {
    + t( s) r0 v: p( U  l( W6 n$ ^  d        Node temp = head;
    1 J; y: U) {4 u4 L9 Q* Q. a        while (temp != null) {
    0 x: R( J/ U+ q) q8 v            System.out.print(temp.data + " ");
    ! U; ~$ y. W4 b5 y' O            temp = temp.next;6 E8 y1 m" e! ]6 b
            }# c" Q4 W8 y$ K, j4 j% m
        }" y/ G+ Z/ U8 H8 g+ X
    . j4 d* m8 v0 l- ?
        /**: j- K# K. {3 A: p+ R/ Q) L
         * 链表节点
    ; Q4 S" P1 z4 @6 p     */3 j5 o) o! O& m% J* G  v1 R. N) h- e
        class Node {
    9 k% i! @' A/ D6 ]6 s        int data;
    % x0 X8 S7 ^, P' @! w9 Y        Node next;3 O- @4 x/ n/ h) n

    # V' l- e; a  l8 l5 z        Node(int data) {4 [/ M; o9 g( s; g
                this.data = data;
    & d9 `: o7 t& X. d0 N* P! B) z        }
    ; s* F5 p8 Q3 O' l; E$ T    }/ \, G3 M& }/ f4 T/ p
    }
    3 S/ p  l" T" O6 ~: T4 s2 J
    ; d2 G( e" E. h. A) q+ }7 I- e
      {7 n6 R% k- W$ N" |, z二、双向链表 12.png , I8 u1 U  U* N! r  \0 |0 [
    双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。
    / c- j: P9 Y- ^' n4 _
    8 v* e% u9 F0 l; w6 u) G. o* P# {% s. f$ X' @& l. s" [( C
    0 i" b; m. g& D! E) r$ D

    0 Z* L$ R# a1 }( k————————————————
    ) S& v: I# C8 K: I  T( w版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    2 u8 d7 e* Y  L原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468
    - ~7 D& E0 Z' J0 ~9 ?, R  z; I4 s1 ?0 u1 m

    : C7 A  n* h. F& F  N: }6 ^0 P

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

    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-12-17 22:26 , Processed in 0.445187 second(s), 53 queries .

    回顶部