QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5187|回复: 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

    % \6 a1 b2 M) w# W' h- K+ q! `【Java演示】什么是链表?数据结构
    + B1 R8 _  z8 m  O/ l一、单向链表
    . R  Y  N6 }" `# H% W
    : P5 F6 f0 O0 K  r) A8 p 1.png 1 R/ ~( L+ _7 Q& _* [7 K5 }7 K
    链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。3 f/ o/ l$ d' {8 I6 [
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。3 K2 |% Y( w7 J+ ~6 @1 R3 q
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。
    # B! w8 j. K& Z" K! d
    9 }, _) }) p3 s* Q什么叫随机存储呢?
    ( {4 W3 O4 M! g6 K/ R
    5 N% n* {4 ?+ \$ F0 d  L3 U如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
    4 t7 y2 n8 K; {7 f. T9 `% I上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。/ O+ h, G' B6 m
    3.png
      U8 ~7 ~$ w# c. C4 H2 ]( W
    - k- }$ V8 A$ {0 p

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

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

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

    4.png 7 {8 ^" g4 A) a) C' s2 o

    " y1 i4 B$ t! u3 }2 d/**
    - d/ T9 s  _; J: f     * 链表查找元素
    0 c# n+ ~1 r  v5 V8 ?7 x     *
    . z! G) c  h# f1 Z$ j2 n; K2 [2 V     * @param index 查找的位置9 s9 Q$ C, T. X6 p$ s# @
         * @return index位置的Node对象
      }* g' W3 m1 C1 D! I1 q2 A: r/ A     */  S; O  a* d0 F
        public Node get(int index) {) w# j9 k2 ^( M  n1 ^2 @5 x
            if (index < 0 || index > size) {
    $ i$ X& U, t0 P0 L5 _; i3 D            throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    ( o* R' [5 ]5 l$ o        }
    " n" {6 |* @9 x& A. d. B" R5 J        Node temp = head;% L, D/ s' \3 J: a1 O
            for (int i = 0; i < index; i++) {
    $ ]$ y; i6 Q8 K$ ^% O$ w) r            temp = temp.next;/ @! X( Z) G7 _: d
            }  W; A* s/ W! `6 _( p0 x; Q8 c
            return temp;* B. _# H/ a- F  V
        }% n0 l3 R1 E1 w
    / @% P+ n/ ~) w! I% ^! R; Y- A

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

    2. 更新节点 5.png * @5 y4 B5 w7 J% m3 e
    ; Z* F) m% o* m- _8 w; e, |2 L
    如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    . K6 T0 h; _' ]; E! A, q6 z4 S$ O如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)
    6 _8 ]2 N( T: d2 N) m! I) ~# A/**5 Y4 M) `& G6 `& i5 J) h: Y
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    8 j9 }! r7 w) Z( H6 T2 E     *1 e" A0 k- b/ Y0 r7 c
         * @param index 需要更新的节点的位置
    4 N9 B* t2 X( C! F     * @param data  新data
    , ^) |- T/ }- J! E! @     * @return 旧data# Y/ M' g6 {7 x; H1 G
         */# g+ u4 _3 x' ~. v5 n3 ~1 c/ M
        public int set(int index, int data) {
    ; B. x+ C6 q% F- ]3 x1 |        Node x = get(index);4 o5 F* k, E& ~; R& I  a
            int oldVal = x.data;
    & Z$ q4 G. [( \* r! I8 ~" p' o        x.data = data;; z" o: @  k  \/ P
            return oldVal;, d' V7 T) M# p4 _: ^+ A
        }7 r5 x3 {; Q7 O& q$ d0 l
    9 H0 o; n) U2 B! X$ y8 R% `( z
    3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入
      # K, n) _& K4 H9 H  U
    3.1. 尾部插入

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


    ; y0 \& I0 `+ N, o 6.png 2 q+ s  g. i8 o% X# u- p2 n* G# n
    3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。
      1 S0 S! \# u/ K6 C, |$ [
    7.png 5 ]7 G1 D0 D  m  b. G
      x  a- Y) ]" |
    3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。
      5 S' [9 K9 y" L  }# X7 b
    8.png
    ) E6 R% y7 |4 V( b4 h% H, S/ \8 d; W- o8 w" T: y
    三钟情况的代码合到一起4 U0 \' E7 C8 k" C' v+ y0 ^. ^4 f
    + M7 {# g6 C* ]( v/ T: U; V8 h
    /*** F1 R; g' H5 i4 z  }
         * 链表插入元素
    8 O4 M; l  K3 e+ T' I6 h     *
    0 U6 C+ L: q$ Y6 F2 F8 `! Q/ R     * @param index 插入位置
    ; g% }; S* A$ Z% e$ U/ E7 ^' p! K     * @param data  插入元素 被插入的链表节点的数据/ v: |' T, c. x2 s, P2 Y1 x2 u2 I
         */1 [0 ^( @$ |9 M0 x5 B
        public void insert(int index, int data) {
    , ^, U8 [5 u8 I( N0 w        if (index < 0 || index > size) {+ g, e9 \  \3 {0 N6 W+ O6 r4 z
                throw new IndexOutOfBoundsException("超出链表节点范围!");  Z" z# u3 x, W- ^1 @. U; g
            }
    . Z' ~0 \; ?7 ]4 f( j        Node insertedNode = new Node(data);
    3 ]7 L- ~/ n" W5 H0 f2 K        if (size == 0) {
    : n- B- F5 L0 g& x  i5 P) k7 G            //空链表; U3 m3 B* v: P$ s) H( Q5 d8 T
                head = insertedNode;
    . s6 {- ]: g& W) C! {- L1 g% u( r- v            last = insertedNode;1 g1 n; @, _1 Z6 ?( [8 z% l* }
            } else if (index == 0) {
    " l; D! \$ v1 [9 G' l3 v            //插入头部1 X, M$ f/ F+ E0 n. A8 k  H
                insertedNode.next = head;
    ; |2 K/ h0 N7 h( @, S            head = insertedNode;4 V6 `( o3 X$ J& n6 L' u# A$ Z0 _
            } else if (size == index) {+ L8 o1 g' k  M4 P+ p" u
                //插入尾部( {2 d5 W9 b7 @, i: i: V
                last.next = insertedNode;, T# r9 t- ~: u
                last = insertedNode;
    / w7 z( w2 w/ b  Z, Y1 I        } else {
    ! z# t+ z' @" ?9 G6 r" w" `            //插入中间8 k1 }" x$ K8 K! K+ X2 D
                Node prvNode = get(index - 1);
    2 P! d# i" G2 Q! U+ F            insertedNode.next = prvNode.next;& h( N' E+ Z! l3 b8 i
                prvNode.next = insertedNode;
    9 X* \3 q0 {6 E  N2 E8 D1 f$ D        }$ q, ~7 G! b1 a$ X
            size++;
    5 S$ {4 D6 Q) H; R9 g. P: Q6 x, S    }& o  P' z3 }& g: }& x  j: y& o% F: r

    7 b- [+ {. O$ u! {/**; `) W- G6 t  ]
         * 链表插入元素! r# Q8 T" p* z/ s
         *7 f% S4 O* Z& Y5 M
         * @param index 插入位置
    ) {1 u  G6 o0 X2 x2 P     * @param data  插入元素 被插入的链表节点的数据
    3 o& g; m8 g7 J) L# T$ p: @- {     */  q8 ~7 a4 j- ?3 ^/ ]
        public void insert(int index, int data) {
    ' o; D. M: E) D! k$ _# `        if (index < 0 || index > size) {
    / P* b& m% R7 w6 r, Z            throw new IndexOutOfBoundsException("超出链表节点范围!");
    + O) u( @2 S: A        }+ {7 n& ]' r$ G% `+ g
            Node insertedNode = new Node(data);
    / r" A' t; T2 m        if (size == 0) {
    8 q& b; U3 F1 A& A$ V  s/ f7 G. f            //空链表1 v9 n  {2 `5 I: I& ^. N/ U! a. I
                head = insertedNode;9 r, v9 t) P0 P% O7 z! E
                last = insertedNode;
    2 c! w: m! h& h1 P6 H/ Z        } else if (index == 0) {
    ; E1 ], @" Z; p2 v' X            //插入头部
    $ A5 a2 R" @+ X  Q- F9 O            insertedNode.next = head;
    ( n4 p" m& _5 a  j. h- D            head = insertedNode;
    2 f+ a$ D9 d. i8 }        } else if (size == index) {
      a4 h0 n- |1 A            //插入尾部
    3 B$ n4 [( s) c/ I- `            last.next = insertedNode;
    0 ~$ @8 `: [8 @6 I! t: \            last = insertedNode;! H1 U, T7 {" j; G' ]' D
            } else {6 o& B' E* w& k3 K2 j  T
                //插入中间
      M  _. H* i4 S, X            Node prvNode = get(index - 1);* |: i* ^0 f% t$ N' L$ g
                insertedNode.next = prvNode.next;2 {* U1 o$ i+ ^; f1 C
                prvNode.next = insertedNode;1 X& \6 A9 |& ]  K4 w" F
            }' Y) O. b) P$ X$ x8 ^3 ?
            size++;, B6 b+ \# u1 ?, u* J
        }
    0 [& E0 i# T- r7 J) p7 b! B4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除" d' [5 v7 H, z* ?$ M  V) Y: U
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即
    6 G1 W( T4 P6 W- Y. {6 S4 k可。

    9.png 5 b9 ~4 _2 R$ D/ m# a6 J
    ! f& c3 I) T$ V
    4.1. 头部删除

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

    10.png
    4 c8 V. J8 Q& ^; q! k2 x, L: V/ r* y  T/ |2 X) ^; e9 ]& Z
    4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要* W; o$ r& J# x
    删除元素的下一个节点即可。

    11.png , f1 l) e" P2 \! J( X
    ' z  ^0 V8 e) \' f1 h: f& |2 t
    9 k3 f' A- [1 S! e" F  S2 ~5 \; b
    这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
    5 ]( c) f0 N' G; a5 g2 h5 B如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)
    ! a6 t% @* j2 s/**0 p5 q5 r$ o/ {* A7 }
         * 链表删除元素
    ' t, Y$ X, ^* W5 w7 T( t+ t     *4 T& r! |* @9 u( @
         * @param index 删除的位置, u2 A  I+ ^9 B1 I* u$ ]  l. |, d
         * @return 被删除的节点
    ) y" F4 G3 a* J# \- a- X     */
    $ ~8 w# F1 Q6 F2 K    public Node remove(int index) {
    ) `$ T$ E+ }. F9 ]  t9 ?  ~        if (index < 0 || index > size) {
    5 |2 b9 Q, f" p9 q) O4 `3 }            throw new IndexOutOfBoundsException("超出链表节点范围");
    . ]) P1 @+ k# [2 G/ d' `5 ~        }; d. Q3 }+ q. g" h
            Node removeNode;
    # s: u6 F6 U1 p! W% y. l! e        if (index == 0) {2 {8 {- Q1 Q$ G/ v: H
                if (size == 0) {) V2 t& j5 m3 g! d9 m3 S
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");
    1 M* ^4 K+ Z+ T8 `& Q2 U1 x* H            }. I9 q) G  A1 o$ W8 O  {: Q
                //删除头节点
    * Y9 ?( m6 J4 T, V            removeNode = head;
    & \, Z! j: M, ^: h& h# d            head = head.next;
    ( F$ b  q+ p* {" e- O        } else if (index == size - 1) {' L1 m' D' u1 @. U6 z. P
                //删除尾节点
    * I1 E# J4 w7 T# K, D5 m            Node preNode = get(index - 1);9 F9 h& ^" b6 Y9 o8 |% z: ^/ p
                removeNode = preNode.next;( Y( K2 `% s/ p9 Y* y
                preNode.next = null;, y( Y+ w% }6 G- T/ E
                last = preNode;; j6 |3 H+ `3 G0 ]4 B3 I
            } else {! _$ X0 o8 E1 |4 n2 `
                //删除中间节点
    1 P, C8 ]9 b, I7 o: {, M9 A            Node prevNode = get(index - 1);) t) g1 I1 d; H$ e: k
                removeNode = prevNode.next;- w! r; u0 d  ], D4 w3 |" H# U
                prevNode.next = prevNode.next.next;
    ' W* A1 e: o& y% W7 j$ N8 e        }9 n/ Y5 q9 ]8 |- s! r# Y) I
            size--;
    " X" x- Y9 p6 H9 G        return removeNode;/ K6 s% l% j. _0 z; V
        }
    ; j) {9 N# r6 N- L1 k1 lJava实现链表的完整代码package chapter2.part2;# V9 _# K* k  P( d' r1 {8 }6 o7 U  j

    . z: h, y% {! `* ]/**
    4 b; D5 u/ [: C6 F" l * Created by IntelliJ IDEA.
    ! j3 u2 e( _! y; ~$ a *- h. x3 A, S+ ?; B6 b7 E! \6 \
    * @Author: 张志浩  Zhang Zhihao* {) ]+ b* q, v) E0 x. l" u, S
    * @Email: 3382885270@qq.com$ u# U, e# _4 n4 l& u: \$ Y9 k' v7 j
    * @Date: 2020/5/3
    ! K& v2 d( A4 v( Z * @Time: 13:39, |  ~- V0 n$ s5 O
    * @Version: 1.0/ X+ w3 x9 Q* ~! `  N0 w
    */
    , t  \& _/ _; X+ `! G! |public class MyLinkedList2 {
    5 I8 X' C( K# W* C' g    private Node head; //头节点
    & o$ f' d9 h2 U$ o    private Node last; //尾节点
    ( F+ b  c2 R) U8 x# b    private int size; //链表实际长度
    5 s6 i0 t8 R( n- p; B5 q& @$ N  f$ J
        public static void main(String[] args) {
    " s0 _; ?  H- ?1 \* R# h. r% f        MyLinkedList2 myLinkedList = new MyLinkedList2();7 f/ ~5 {3 A+ D( J3 L/ N4 n4 D
    //        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    7 r% b& Z3 U3 C  h4 t' G//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
    5 O8 g1 l' K; k2 d8 P; H        myLinkedList.insert(0, 3);
    7 r; Q' p9 Z* c2 X  j        myLinkedList.insert(1, 7);
    7 l' a2 a7 [& ^# u8 l7 }( v        myLinkedList.insert(2, 9);+ W. H6 [- c% V+ D  a
            myLinkedList.insert(3, 5);
    # p2 F0 Q2 `& X* |; q& z* t) O# F        myLinkedList.insert(1, 6);8 F* i( b3 z% q" s7 g' g
            myLinkedList.remove(0);2 |. x8 G( C0 ^+ y
            myLinkedList.set(0, 23);
    , v/ I! Z' q+ W# p& ]2 K9 f        myLinkedList.output();1 `. m1 E( h& e' @0 w1 V+ q/ p
        }) M: m/ ~4 z& f$ y

    , r! q* D+ D3 }    /**0 A1 v% \* O6 _! \% p* J2 j
         * 链表插入元素3 i1 s! @  p6 \4 K
         *5 N9 g8 L6 i8 t. v" k
         * @param index 插入位置9 Y. w* D0 r- r/ z  Z
         * @param data  插入元素 被插入的链表节点的数据: s9 q. ^# D- F
         */
    5 R8 Z6 A+ m. a- ~+ ]) m. G+ J& U    public void insert(int index, int data) {
    $ h7 T9 j" C/ i" ~1 S: W% {        if (index < 0 || index > size) {: z% w! Z, R% ^9 O
                throw new IndexOutOfBoundsException("超出链表节点范围!");3 H6 U& n0 g- f8 X
            }
    ; x! G7 l- j! t9 O6 M+ N% R        Node insertedNode = new Node(data);6 V. f* l' n! ^- r
            if (size == 0) {
    0 x; I4 P. k$ H! q2 {# ]" J            //空链表
    2 O# }" X$ h' b1 u            head = insertedNode;- h7 B) Z8 q5 p  W
                last = insertedNode;
    # g  t+ h- K7 r$ g2 ?1 W, u        } else if (index == 0) {8 b" z( @' P; G" ~
                //插入头部% D$ J+ x5 W5 Y8 F5 i2 f) h$ B
                insertedNode.next = head;' c1 y/ z% G# o% T) c
                head = insertedNode;
    9 E* j' a! H% |+ U5 L        } else if (size == index) {7 k& ^; L) n' I* j  \* N' `
                //插入尾部
    ' B% E! {6 R9 p% D  X( U: }            last.next = insertedNode;
    9 O# {, U7 c3 M- Z            last = insertedNode;
    0 D/ g- G+ X4 N; b5 ^        } else {
    ! x7 ]$ K; @4 m0 ~            //插入中间1 e* T; F4 j9 N# t7 _
                Node prvNode = get(index - 1);! v3 Q: C* U2 b' M/ f# F) v
                insertedNode.next = prvNode.next;
    * n' ^; `* D* f            prvNode.next = insertedNode;
    + _* x+ x2 u( M0 C1 E- H4 J        }
      g/ ?. X7 A1 T: V  ]        size++;
    % W9 f" F9 R. T: G) P6 N    }
    1 }) \1 v/ _* V& J
    ( q2 D( f2 K7 o' O    /**1 c& A) l! z2 K, [5 m2 D
         * 链表删除元素" k7 Y: _$ Z8 ]$ M( |
         *
    / C$ D' I1 [! c1 @" R( E     * @param index 删除的位置7 S+ a  j% P7 S- H
         * @return 被删除的节点- `  s: r; W& f* Z
         */
    0 b2 q, R/ p7 M/ g% ?    public Node remove(int index) {
    * g, C6 f$ c) A) t        if (index < 0 || index > size) {
    ! e& X2 w/ E4 O- k            throw new IndexOutOfBoundsException("超出链表节点范围");* [1 ~' B* Y+ N  [
            }
    4 F. x6 v8 J- A4 O% C        Node removeNode;) Z8 G0 g, p; z( Q$ h7 Y$ j& F5 A
            if (index == 0) {
    2 r/ J: r9 m1 E5 R$ t% V, ~/ r            if (size == 0) {4 Q: B3 i9 F8 h7 F
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");
    , j# T/ [1 I) h/ c. b            }: u% e! u2 R, C# r
                //删除头节点  R) M+ v2 D: W; j5 ~: N: k& E9 N
                removeNode = head;& H* e8 p, Z/ L$ _: ?: |& f
                head = head.next;
    1 a6 d& l& ~2 U% ^& l        } else if (index == size - 1) {
    . k7 l6 r' E4 Y+ {            //删除尾节点5 V2 G; P  E8 @8 ~8 v) S4 F; B. }
                Node preNode = get(index - 1);" p. u  r- X, C
                removeNode = preNode.next;
    8 }+ W( ^  A, Z. o            preNode.next = null;! y$ N! f) G+ I: @
                last = preNode;
    7 E& K( [9 i7 a1 J        } else {
    % t, n. m3 o7 r; i3 I, M3 C            //删除中间节点$ h0 s2 a9 H: F% w
                Node prevNode = get(index - 1);+ o5 T! E0 }+ P0 R8 t) _
                removeNode = prevNode.next;
    % f' M4 j+ p! q0 I/ m3 _# I            prevNode.next = prevNode.next.next;
    , x" T0 w1 w4 H8 B( F        }
    6 ~% @4 W. [" `1 g) i( _# q        size--;, n3 m' z( o9 Z$ w7 D: N0 o
            return removeNode;( I% l! m2 e1 d8 m( B5 Y
        }$ s+ C( z# r& P  ?# n: A' e
    7 e* R; p" E6 v4 X! }8 ~$ c, V
        /**
    8 G) ~% z- k) X6 o8 }& J% p) g     * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    " ]3 R1 E' ?& D     *2 `6 F# y( m! C+ G1 A. S; r6 N
         * @param index 需要更新的节点的位置
    7 q0 [4 }1 U6 A0 g2 D# w/ {0 x     * @param data  新data4 m# C* G; v; L4 j% i
         * @return 旧data
    ' b; a2 X% P$ n  ?& r     */# a$ l  b* H3 _& {
        public int set(int index, int data) {$ S8 Z- p; M% B, R* J9 f6 A
            Node x = get(index);
    9 f1 Z  ]- K' u; J        int oldVal = x.data;, s1 n9 ?5 A' R( S
            x.data = data;
    % m) n  O' O0 g        return oldVal;) g3 m% H( t+ z4 k% }! o) Q( _/ f% j
        }$ q' ~2 f. }. D, p$ F$ S. Z4 Y
    5 ^( I( a7 x, y1 d/ x+ O9 B
        /**
    2 C6 v3 A9 h6 D% r5 ~3 |     * 链表查找元素
    0 v- z6 i& }7 X. h8 m6 A     *
    , ]9 {5 b- i& ]7 x  i     * @param index 查找的位置
    , X' u- ^) \1 L( i) C6 f+ ~     * @return index位置的Node对象, `2 s  j" {& p# y
         */0 j) c& j- M% A
        public Node get(int index) {
    . Y" ~3 U1 l! _1 R! F        if (index < 0 || index > size) {' p6 u& _$ P% b2 b; ~
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");- z5 |8 W' F  }# W% D0 k
            }
    / X" u, \3 T/ @  p% g/ I+ w( S1 V8 y        Node temp = head;) T3 |, ?. o0 U
            for (int i = 0; i < index; i++) {5 j" @, o0 D; \6 {9 o& V% O  X
                temp = temp.next;
    $ F& g/ y% o* `1 q  ~5 e        }
    2 o8 D: k) D" \. f# j        return temp;7 R2 y# B% |) ~
        }
    . p9 N) M9 v2 l! `2 O
    $ E; e. B4 l7 X4 Q3 x) Y* z8 T1 ]    /**2 |/ j- M  e( U! w2 s
         * 输出链表
    7 T) u2 }# b$ X     */
      g6 z* V9 Y/ O. a& w( T4 S  S    public void output() {
    4 C, [" ?) U* ^        Node temp = head;
    , u! Y( Q% C7 c" L        while (temp != null) {
    & {9 [8 i! ?% W6 d3 z6 p            System.out.print(temp.data + " ");8 D9 x# J) R" V
                temp = temp.next;3 G9 @. m4 B6 E. v
            }9 v# C, ?( U' d) j6 C7 m
        }; q5 {0 W( {# m% ]7 A' W
    - m5 N) u8 O  g7 Y8 h
        /**% u. m! Y9 D# y, f4 c
         * 链表节点
    ) Z2 N4 @1 ~; D) K% M7 n/ X0 M* {     */
    : S. I/ n$ a1 K  I# s; A( u  e    class Node {4 `1 k+ X/ p8 r% s. w
            int data;0 A5 {+ x, U# K- z
            Node next;
    : J& y( w$ {: J  p+ e1 |5 X& K8 o/ K9 y/ {
            Node(int data) {6 f# l2 W, L9 R7 O: P; f1 U; g3 h
                this.data = data;. M! N- P) ]- l& V
            }' K. `% `' d, o* V6 m
        }8 C. }2 u$ p  ^5 c
    }! b/ ]/ w( {, V
    ' ]3 d$ T! I  M

    * c5 y% r) p$ M  B, H# T0 f二、双向链表 12.png
    3 D! r9 g+ n$ p+ s2 V双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。4 U, F+ P+ w0 a- w. A3 Z2 Q

    9 e" F+ ^6 F2 V/ d; F2 U3 u& U# l+ {" y
    1 J6 s; R1 r$ s$ r& ~7 `

    4 ^# w) M' T3 ^# O1 k————————————————( w* R6 {0 u( z
    版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。  ]0 P1 x* n! v! n: y
    原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468
    $ ~9 W6 m# f: Y+ O/ g  R  R3 d, z# L% N' _4 h1 t
    . W; ^* ~7 Q8 F% e* V

    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-14 12:53 , Processed in 0.568290 second(s), 54 queries .

    回顶部