QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5335|回复: 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
    - L0 V$ r0 `2 [3 J( i* _0 p# V- x
    【Java演示】什么是链表?数据结构
    , p! p2 \" F, V/ K5 P% S& v一、单向链表
    # w6 [0 A4 V' R) M/ T! y6 m9 }5 v
    * @% t9 d2 C" p 1.png
    ! P$ X8 S4 ], j! j0 n5 c0 }2 n链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。
    - G# X1 k4 P0 M2 v& u7 [2 S单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。
    7 c: d5 o8 s4 j+ p: Y链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。" p5 P% s) i' _6 w
    * G* w; `: a; [/ N0 N
    什么叫随机存储呢?) B4 q2 a: g1 g* A, f0 d. U

    $ h4 n8 H) t, B4 w4 i& h+ V如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。0 v" {* ~0 v7 u& M) ?' F
    上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    - C( C' O% A' @9 }& U& b 3.png & }+ a$ Y7 V+ W' T0 n6 F, s

    9 D. E2 V3 `+ H, t- `" U, g

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

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

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

    4.png 5 l+ x+ X5 O0 s  O5 s+ E
    + _( L  {. O( W; \' C  O8 R
    /**
    / t- Z6 C1 ]9 q5 ?2 }& M2 W     * 链表查找元素
    ; ^0 \- I! w4 U* Y     *% n; {% i6 |* W
         * @param index 查找的位置
    3 E# ~( M0 I# P  s, v     * @return index位置的Node对象
    4 c& e- W( R! m8 u     */- w5 d# U5 j' Q
        public Node get(int index) {' [5 w" ~2 P) s, x0 A0 ~( Q& c8 _
            if (index < 0 || index > size) {
    2 I( a# J1 c2 {% H! S            throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    7 t/ L/ N& O& \4 `, Q7 z6 g6 d/ w        }% ]# W; G7 f9 j3 P
            Node temp = head;- A  I2 x' K9 u2 e% H) Z
            for (int i = 0; i < index; i++) {
    ; }- `2 D: ^# ~; M' F            temp = temp.next;
    ) L3 i6 g' ~& K, a* |- o        }
    4 \/ l/ G" [$ H: h6 C* s5 @        return temp;5 Z  _4 t3 P4 v! S& Y
        }, ^8 ^! k2 K' Q/ o

    ( G/ {/ j# k/ h$ b4 f

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

    2. 更新节点 5.png
    0 R! M( q3 i; J) T, M8 `9 |+ ~2 w! h3 @
    如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    2 g6 L1 c% ?: Z2 V, C如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)+ L+ ]% ]; q. L6 G$ |* B
    /**! O7 Z/ }+ z! y0 e+ s
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    , I, h2 S+ p' \. ~8 t, s' ?     *0 w4 ~. U8 L/ x+ u$ Y* f
         * @param index 需要更新的节点的位置3 Z# |) L' r; s" @+ o) d' u
         * @param data  新data
    # S) O1 U: ~& S0 ^9 M     * @return 旧data: D; ^3 e8 u' L, T0 h/ Y
         */
    / g7 ?$ R8 p1 b4 O  g  I    public int set(int index, int data) {9 b/ k8 s4 w9 @+ G5 o7 d. G7 R
            Node x = get(index);
    4 I8 P3 I; H) c* b! p2 A; k! J  {        int oldVal = x.data;
    3 T" f8 f. C9 D) }" y! ?% p        x.data = data;  Y+ L: z$ n1 p  x7 e) a& w( h
            return oldVal;8 _! }6 T! i8 ]" @4 P  v) V' |
        }" y) y8 `9 z3 t

    ' |" ]$ V/ C1 J+ o0 E: L3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入
      # w5 M7 O) e# ]0 n2 Z
    3.1. 尾部插入

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

    ! t5 d/ k! E7 F! L5 h3 {: j* |4 W
    6.png 4 s" D; @  [) j3 z' o- [" s
    3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。3 k1 }' K7 u) l: i, T0 L
    7.png ) Y" _; b8 a. A. L- r: V

    ; }8 k4 R- @( m% k9 P3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。
      , V+ T' p; t7 d  d* F# H8 T4 O
    8.png 2 q9 }* z  Z: }0 G3 u8 b
      Z) g& v8 x* }" |% _
    三钟情况的代码合到一起
    # L+ a+ a6 X% s' }! H
    1 w6 F- p# D- J5 z  z5 v0 F/**' d7 a2 ]- a9 S6 }
         * 链表插入元素
    7 A8 x' U/ P3 ~8 u     *1 u- t' K- z" @1 Z4 a, C2 q
         * @param index 插入位置) u, `0 \1 r( h/ X1 V) A3 K+ `) p
         * @param data  插入元素 被插入的链表节点的数据1 N4 t( T1 |* c" z& T5 n! `6 Q
         */
    4 E8 r* X/ s8 }( f+ l) x+ Q    public void insert(int index, int data) {
    + g2 }5 ^# g. \; v. ]- b% K  R        if (index < 0 || index > size) {: n$ X5 l* I& Q
                throw new IndexOutOfBoundsException("超出链表节点范围!");9 o% I& W, \% g# |
            }
    $ I. G# S$ C1 U. Y9 d6 t' T        Node insertedNode = new Node(data);
    1 g. ~+ e* B# U: A        if (size == 0) {
    , S! u: [- a8 Q& \6 Q2 z) Z            //空链表+ f; X7 ?3 f8 C0 O7 d8 A
                head = insertedNode;
    8 o5 G2 r& p& C6 [            last = insertedNode;- D0 N$ b0 j) ^& j  V
            } else if (index == 0) {
    $ l. }3 b( j  N8 s/ M' [            //插入头部
    1 j( c- ~" R; o+ [) ?8 N/ G# b. W- r            insertedNode.next = head;; y2 S* G5 g1 k$ \% z
                head = insertedNode;! `. \/ ^) q* y( y5 D% _
            } else if (size == index) {) b( f* [, _0 N/ _! ~# x; Q  ~
                //插入尾部9 @4 L: u/ `/ k) L0 X) g) t. h
                last.next = insertedNode;3 z9 n$ Q1 c1 r% B5 l
                last = insertedNode;
    9 E3 X6 ]  s3 J7 s" N4 r        } else {$ T; H) z  ?3 G0 J. X
                //插入中间' m7 W- K" R! R, Y3 B2 T
                Node prvNode = get(index - 1);
      ?$ U# c' _+ `# F            insertedNode.next = prvNode.next;
    / O0 \. R4 R, N, C8 v            prvNode.next = insertedNode;. s$ i8 _. a7 i6 o- }
            }
    : m; e9 p: Y' x2 U        size++;
    & ^" p9 W  y$ X, l6 U    }+ K8 L+ O% n  c
    ! R* V: x( V6 i7 K+ A
    /**
    ; {7 z6 [2 B8 ^3 A9 F     * 链表插入元素, H! g/ o- Y- X( ?- \7 c" @
         *
    ; D- c9 j0 B" p     * @param index 插入位置; e. N8 }0 ]: \/ f; Y
         * @param data  插入元素 被插入的链表节点的数据: X! F( l1 x' t8 n, }8 b* {) Q8 M
         */
    2 [1 ]5 y6 t0 @4 m8 v- f2 q( J    public void insert(int index, int data) {
    8 K3 m5 @3 H& E, _        if (index < 0 || index > size) {
    % o- w8 H8 ?/ N8 z5 J+ K% M1 D) }            throw new IndexOutOfBoundsException("超出链表节点范围!");3 p* F8 j4 S' l2 S$ U  x1 f! b
            }
    ( O9 |0 W- m/ c3 _* I        Node insertedNode = new Node(data);; @" Z0 [3 v3 D! y. R: Y
            if (size == 0) {/ T, v5 G1 o% j+ v' K) W% F; r* b
                //空链表& ?3 c' H: C3 X8 R6 B+ E
                head = insertedNode;
    4 P$ r. A& {! v! t# L1 E5 i3 N# W            last = insertedNode;# o4 f2 B& g' n; @
            } else if (index == 0) {8 X7 x$ f- G* c4 Q+ e  u* M7 B( G0 Y
                //插入头部, }2 X8 u, o+ n% ]3 e* r
                insertedNode.next = head;
    8 ~' z% r) E9 m, P' N9 r            head = insertedNode;, e/ D/ e8 _3 a2 H- \
            } else if (size == index) {
    ; k' a# ~$ A' ?' p            //插入尾部
    ' J: |7 D1 B9 V7 l$ T1 b9 n            last.next = insertedNode;
    7 U! f! {5 o' E$ Z            last = insertedNode;# V8 u2 u# j+ o! h+ ?
            } else {* Y8 F/ d$ S/ s2 f
                //插入中间
    $ O/ ^  S: e! O6 r            Node prvNode = get(index - 1);
    ) @7 l/ F9 q8 M            insertedNode.next = prvNode.next;
    4 q$ T7 p& r, C* {: ~            prvNode.next = insertedNode;. b$ ~, L- G7 k
            }" t% s7 ^5 I0 z, O, K) P0 K
            size++;  a, W/ B; Y$ w
        }
    3 A7 T0 b5 p( o3 K4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除8 p# j$ }! _# g
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即- u: c+ C  ^+ b8 a3 t1 }
    可。

    9.png
    0 v0 c9 W  J/ u4 j* |+ V% y# F) R+ m' q$ W2 o3 E; b! f
    4.1. 头部删除

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

    10.png
    3 ?4 O+ e( h8 Z( G6 L
    9 C* f" {* L- S/ J4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要/ x1 N& Y2 a, E
    删除元素的下一个节点即可。

    11.png 6 p7 }7 h$ B2 r9 k; D7 j

    ' C, g0 W8 h* o: m' r9 K' G
    ' k3 F! f8 i, _- s6 S这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
      B' N! Q( q& k# c6 O如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)
    * x/ j/ \  K$ _. J9 D/**+ j8 C2 ]6 K) Y, \6 f
         * 链表删除元素
    6 Z9 D* Q0 f$ `     *( o" P4 ~/ R. q9 G8 u* L8 d, [
         * @param index 删除的位置
    4 \0 h3 A+ ?$ I  x     * @return 被删除的节点  s: ~2 L; B- s! Q" y
         */
      O& U# _8 c7 E' y& k7 N- a    public Node remove(int index) {
    , @" K6 @4 l( G: y0 a7 Q2 N; y        if (index < 0 || index > size) {
    ) l. i2 q/ K: O8 R$ r            throw new IndexOutOfBoundsException("超出链表节点范围");
    0 J# V( ?& b2 W+ j% n        }; _6 M' ~8 W4 j* \# Z0 u
            Node removeNode;$ O2 [0 R4 _9 c4 k3 d$ Y
            if (index == 0) {
    5 k* ]7 a7 O; c6 S, `; z& K5 [            if (size == 0) {2 R% a0 K9 e' v+ ~1 D1 v& X: r! K# I
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");: Z8 G9 M  v# R  e/ Q
                }+ k* ~0 C4 n& M" |% O; R
                //删除头节点' H. _1 [. W$ g& [; x9 Y! @
                removeNode = head;& I$ ?. p+ O4 o' I7 C9 F. O
                head = head.next;/ b8 v  n& h& v
            } else if (index == size - 1) {
    4 i+ u: E3 T8 S2 n! n" t+ f            //删除尾节点' b6 ?( Q: _4 Q" z# P) m; T* u* U
                Node preNode = get(index - 1);
    2 Y, z. C- w# t5 J3 K% i8 }            removeNode = preNode.next;
    7 U  A- Z, @# F) i# `3 s; z- K            preNode.next = null;: x5 o+ {. D$ F" m
                last = preNode;
    & j; a6 z# d$ T; f: ^        } else {! X9 S/ a1 N, q' }! t" [9 R0 b
                //删除中间节点
    . x) E8 J* s0 W* @( F1 X( c$ j            Node prevNode = get(index - 1);% z+ M+ j, u7 l, s9 |* }# }
                removeNode = prevNode.next;
    ' k/ A4 u; O* G/ s            prevNode.next = prevNode.next.next;
    5 v7 ]' P2 p; B        }. e+ ~: p5 ~" H: i" H
            size--;+ l/ T3 Y1 n" R, l/ W( e
            return removeNode;& Q! C$ n8 {! N: G4 _
        }
    , l* c9 w3 k, Z# Z% j  \+ v& FJava实现链表的完整代码package chapter2.part2;0 \. Z. Z. C/ t$ c. s5 I
    0 E, x: s  l( q
    /**6 c2 G  }: O% r0 U$ I
    * Created by IntelliJ IDEA.1 P* n' g$ |, p. w
    *( f, p. D; U! B* s
    * @Author: 张志浩  Zhang Zhihao
    5 C' ~# C$ y: ~" d3 i, X * @Email: 3382885270@qq.com+ H- g" {" G8 q
    * @Date: 2020/5/37 N. `$ K! q2 W
    * @Time: 13:390 s2 U, O$ v; Q9 J; a: ]0 p
    * @Version: 1.0% ~% O0 V+ _8 T# e( Y
    *// I; j7 Z; T# j" i$ Q
    public class MyLinkedList2 {
    ; U! l$ {4 o9 u# `# `    private Node head; //头节点
    ; ]! p6 W3 M) i9 m! D0 t3 i9 Y    private Node last; //尾节点; y/ R  r$ v! z7 J- W0 ^% D* `
        private int size; //链表实际长度
    2 T+ |+ G5 m. N* z" |6 H/ Q+ f3 e6 m
        public static void main(String[] args) {1 Y( _" Z0 H( f. N/ \% V$ [
            MyLinkedList2 myLinkedList = new MyLinkedList2();
    0 E$ O  M, h5 h/ b( a% t9 n8 K3 d//        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    7 y! B& K3 X: r//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围( n$ |/ m6 u4 S
            myLinkedList.insert(0, 3);! ]+ x; y+ o' S) Q7 q" s
            myLinkedList.insert(1, 7);
    , ^- W7 X9 q! }, P, ?. I; O- J        myLinkedList.insert(2, 9);: C  D$ Q5 U% w7 D  h
            myLinkedList.insert(3, 5);7 L: U5 B0 ]' W! R* n) k6 M
            myLinkedList.insert(1, 6);% K& ^2 z5 f+ H  e
            myLinkedList.remove(0);* j: Y& \. x! z" x; s
            myLinkedList.set(0, 23);
    ( x% A/ x/ ]* Y' D' e6 Y        myLinkedList.output();! t' l( v- {5 O( d
        }) s; m3 c! n2 m7 M1 d8 ^# j/ Z
    , s: X6 }+ W- Z4 {
        /**) P. T+ d  P4 a9 H
         * 链表插入元素, T: E. Y. m6 o9 z6 B$ u$ }- q
         *
    * Y3 N' ~* ?9 w) d7 o     * @param index 插入位置
    6 H7 u$ n7 W/ \3 n     * @param data  插入元素 被插入的链表节点的数据
    $ \: w. q) P) ?& X0 `. Z# f     */
      y) g6 Y$ J& j4 ?    public void insert(int index, int data) {
    3 p$ O6 n8 g1 F0 g! M        if (index < 0 || index > size) {
    % n5 ]* R8 U) @3 `! U            throw new IndexOutOfBoundsException("超出链表节点范围!");
    & [. {$ {* c9 ]$ B' H7 j        }
    8 G& T0 H/ I% ~+ e! k        Node insertedNode = new Node(data);
      E# S5 ?) t0 F- b. r/ R        if (size == 0) {1 p  Y5 ~6 ], Q, v3 p
                //空链表7 z% s3 n/ V/ U; Q( P9 U4 [# B) b
                head = insertedNode;, t% x* A1 |. L% c
                last = insertedNode;, q8 z" ?9 W; V( [: F8 W9 z# ]
            } else if (index == 0) {& b& A; S( C% n7 |
                //插入头部% v$ _3 F0 F0 u
                insertedNode.next = head;
    " p/ B/ y+ q7 b* _3 m  `            head = insertedNode;, E% Q* F$ Z& ^4 |& b2 m
            } else if (size == index) {" K: \! u% _2 [, E4 `. }* u
                //插入尾部
    4 K$ H7 _1 T: v: D9 N            last.next = insertedNode;
    8 A- P* _, l5 K. ]            last = insertedNode;, @- C" i  y7 V4 z% o9 e
            } else {
    , ]- l) t& j8 x            //插入中间
    # m7 B; X- l5 u/ N0 B6 b/ S% E5 Q            Node prvNode = get(index - 1);' t/ e2 |' Z# V' i* `
                insertedNode.next = prvNode.next;& M9 P1 N; N8 D/ \
                prvNode.next = insertedNode;
    2 {6 a6 c+ W1 X8 R0 r# w        }, X, \8 Y1 k  x, t' F3 A
            size++;; F: |4 T5 B- d; f6 n
        }1 D( s% t% o8 j$ B5 k1 b( X

    4 {7 M3 ^. U7 P0 O5 \$ l    /**
    # G" k( i+ i' w7 V9 `# `( Y- _     * 链表删除元素
    * G# A- X2 \- l- X2 v$ {     *
    6 I# j% A- K5 t  p* b; a     * @param index 删除的位置' R; F" R& A7 G1 f+ _) ]% w
         * @return 被删除的节点
    ( N: @7 I) `! T$ Y7 r; l) c) ~3 h$ `     */1 n! o$ s( q7 x# y' I7 f4 u
        public Node remove(int index) {
    0 Y" Z8 N8 F# e/ F1 l        if (index < 0 || index > size) {
    7 H" ~) i. C% c, g8 W6 B# E            throw new IndexOutOfBoundsException("超出链表节点范围");
    1 a6 a/ Q. b0 u, h( ^        }/ l$ [  `9 D; {# g$ {" X
            Node removeNode;, q1 Q5 F: o+ m8 Z' t4 B  D
            if (index == 0) {; G+ M% n3 v- v8 w8 X! a
                if (size == 0) {6 Z) Y% \2 j  X& J* P
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");" \1 d, f& ]9 `; B
                }5 s4 ]  o5 ~- E! Y
                //删除头节点
    ! w! d% J3 E% S1 e) G) p0 w            removeNode = head;( |* P2 C, I7 f+ T
                head = head.next;
    / q7 O# o+ H+ r9 @$ e$ o        } else if (index == size - 1) {
    8 U+ m; D8 ?, [3 h/ O6 _            //删除尾节点
    ) P  t, ]1 }! R1 u  e0 q& \0 q6 M            Node preNode = get(index - 1);" h3 k7 g% ~  p. i: k
                removeNode = preNode.next;
    + p% ?, ^1 _* J. z5 l4 A            preNode.next = null;5 w+ k3 u8 G4 }, F3 g+ f
                last = preNode;. W" x% Y8 |7 K: Z
            } else {
    % r  A+ i. X4 h. U( i2 l            //删除中间节点/ }; U: Q: {& l% Z+ R: P5 g
                Node prevNode = get(index - 1);
    ! I7 V" [/ f/ Y$ ~; U            removeNode = prevNode.next;
    + |* H6 K7 b+ d* u6 R/ P3 O, e, x2 i            prevNode.next = prevNode.next.next;
    - y6 P5 A  l* E, @3 q2 n7 _        }
    7 \8 w6 [3 r( Q- c  I" J" m* X        size--;, R* M4 [1 y( D1 C
            return removeNode;9 l" t. _3 U& d2 I8 {2 l
        }- l8 Z* S- k7 w  n. D9 S% G

    ( h: |* H4 |5 F  \8 p1 w. G) T$ R    /**
    0 z3 S7 O9 ?& `7 N     * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    1 |3 F2 }- U0 ]     *
    - M9 B: e. d3 M/ g  H     * @param index 需要更新的节点的位置7 v; H# N( l/ ^2 N5 T
         * @param data  新data
    9 h  V9 m* }# t, }% O     * @return 旧data; b2 J( {9 O% O: s- o# ?( H- C
         */
    " g! {( u  o! H* r    public int set(int index, int data) {/ X' L0 X$ A+ f8 \
            Node x = get(index);& t/ ^3 x+ d1 R8 y9 w% f
            int oldVal = x.data;
    2 G. K; C! \7 y  T+ E2 A& P- X. g- m* J        x.data = data;) Z3 I7 n6 Q1 U( p9 u3 f3 Y# I3 A, j
            return oldVal;: e, l- |8 H  A+ }+ F+ h, G- L( q
        }! k! J0 Y3 R2 y6 T

    & |9 Y+ X( h1 c' a) t$ t! q2 j    /**
    0 B8 w$ J2 ~- ]. ^/ a) H     * 链表查找元素6 N3 t% H: O) f
         *5 D4 d: y: p2 F' p4 Y
         * @param index 查找的位置
    , o/ \& @& m" A3 V3 t5 y+ L     * @return index位置的Node对象' W' G' |! b9 @2 Y
         */" j4 S: |/ w) u
        public Node get(int index) {
    9 `8 Y  O5 r' n        if (index < 0 || index > size) {
    7 R6 F! z) C; A; ]. V' j            throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    : d- Q3 D, U* f0 j& a        }9 f1 a* `0 I; d( g. u% j4 C& q
            Node temp = head;" a* Q; O3 L1 Q0 K
            for (int i = 0; i < index; i++) {
    1 k6 {6 i9 n  B/ g% w- ^1 [            temp = temp.next;1 T3 Q) |" T/ u; b8 N
            }
    4 D- ?2 C; Y; G% X9 I        return temp;; e- o6 S8 U, Z$ Q
        }4 k' P; T7 [% z
    4 w4 X+ B9 h* o4 i% G
        /**4 q, E# ?4 ^1 b- x1 T
         * 输出链表
    8 n0 B" ]% v* D; \     */
    ; A; U3 {$ w$ O2 ~    public void output() {
    $ ?. u( J7 [  L        Node temp = head;) `& i# V+ m# \% U5 X$ C$ \5 i
            while (temp != null) {
    % w- s: @* u- a; I  o" h. \1 r6 \6 `            System.out.print(temp.data + " ");
    6 N9 i5 N$ `7 }' _            temp = temp.next;3 v" x" ]! |- Z. o
            }
    & M1 R8 c6 Y/ y3 L; F    }' U4 K' s- z/ \# Y3 }

    8 z. A7 c. @* ~7 M0 J, @, H    /**# O$ r* `2 s% }# E; P" c( l8 i; c
         * 链表节点  g! z; R) A4 P: q
         */
    * C# k# C1 t% p" e$ ^: }    class Node {
    9 f* E6 |0 f- _; T, d; s. L        int data;1 l3 k& Z$ u6 e/ \5 {% J
            Node next;
    4 M& [4 ~1 y  {3 }, p( a( e. z6 X) L: S- {! L" V7 O
            Node(int data) {3 Z3 O+ ~; @1 ^) o
                this.data = data;
    0 c. ~0 f, n6 D& o8 h% m        }+ U& G: n- x' V2 F" L$ }. i) I
        }
    " C( o7 j4 v+ ]0 s8 W2 t- q}9 s- v: X+ K- n) W

    9 h  B7 S9 x! e5 |2 R9 h) a4 X5 A, Y9 R
    二、双向链表 12.png ' N1 U! C  M; z9 I5 X
    双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。
    2 H! g- B/ i( K/ l# d. l
    . {1 l+ X2 x/ k8 d* C$ [# M0 E0 J/ P( p- B) [; H) [1 d

    ! `5 q' p& f7 K5 X8 L0 q: A% Z8 R5 Q  T* p' H: ]
    ————————————————
    / J1 m' p" s) d版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。2 E3 A. @& p: F! t
    原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468
    , Q/ o  B& s8 @2 X. Q% H7 p0 y! c& x1 Q6 `0 |* [& F
      e- u% c2 q3 j

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

    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-9-22 11:41 , Processed in 0.507378 second(s), 54 queries .

    回顶部