QQ登录

只需要一步,快速开始

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

    2 O5 M6 Z$ O( _: U% @. |4 {, d  G4 b【Java演示】什么是链表?数据结构
    0 @. S: F. _4 N3 V一、单向链表7 q: U! o% b% a: |' o7 r
    + o; `8 U4 t  T/ ^& u9 W5 O
    1.png
    $ ~$ n! ]8 o& E  g4 \6 g5 b链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。4 M$ q% n7 X; u6 V' ]
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。
    6 f9 @* D7 V5 c  m链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。5 r2 v4 P  O: R3 M" ^7 j
    + @9 @3 n% C5 f1 J7 k" }0 t! c2 r. I" ]
    什么叫随机存储呢?
    7 U7 \* V4 M' T) {' i/ \1 r$ K8 }) _0 U2 q
    如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
    + U" J5 ~$ a' b1 i上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    4 d' H  W6 K2 g7 {5 f% i 3.png
    2 Y8 I* p6 ^: Q7 p+ g: {, i& g" c+ f

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

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

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

    4.png
    # ?' p7 t" }. g" n' L* w4 u9 q' V6 {
    /**6 f  Q% M- x3 d( A$ U
         * 链表查找元素7 V$ v: e3 `2 s/ x
         */ b/ E( R: H6 K8 h0 W' a4 J
         * @param index 查找的位置9 d0 W7 \/ v" I" p* h. A9 M6 ~
         * @return index位置的Node对象; f! p# D1 s! @/ G5 i! K7 G
         */6 A8 O: o- s6 ^, r! a
        public Node get(int index) {, L! k( A5 h% y* i5 K
            if (index < 0 || index > size) {' v5 x( r4 W7 q( E8 V, g8 l
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");  A' j4 P1 w  A6 X" J, M  _, i% A5 H
            }5 {- b7 W; |0 i3 H5 U; w) y! w
            Node temp = head;
    ) P6 A2 R( R7 U3 l* k# n        for (int i = 0; i < index; i++) {
    1 L0 I2 m6 i+ x! T; O            temp = temp.next;# d+ {$ B7 S* ^! W
            }, t. U( i$ i. X; X7 U6 W/ Q6 q
            return temp;) {  Z1 U9 c" U/ P
        }3 T6 R- Y: G0 g$ `6 h

    : D! a' S1 t5 K1 s" p( I# A

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

    2. 更新节点 5.png 0 I5 W4 O2 ?5 ~1 L6 V

    5 Y' [, y: C4 L2 F% i如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    * [5 V- g/ e' o& p: O8 g如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)
    7 r! Q, S5 w6 r' ~; q. J" t" O/**6 p3 r, Z& k% t) I% l2 @
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    $ c8 t( }1 y3 I1 J     *2 o/ v$ m+ p5 h6 D$ e9 E% g) L- V
         * @param index 需要更新的节点的位置
    4 _2 r! {2 u2 a2 k) ?  z     * @param data  新data
    8 L& K. x! }! Z     * @return 旧data
    9 x; a( _# R) O, m3 H     */
    # n! J1 `$ v- c: l' k  [* K    public int set(int index, int data) {
    0 `: d2 `  T2 x        Node x = get(index);5 X! s2 b" ^; _& r
            int oldVal = x.data;
    , V/ Q$ d( a  e% e" U6 c. T) U        x.data = data;( L- J0 N* J; G+ Y* c
            return oldVal;
    - ^. H3 y. S- h: y% H- Z7 }/ ]9 T) Z    }; D( \; I/ E/ R% ]7 t6 ]" Y; X

    ( b& d/ D& R0 u$ w3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入
      8 s! `5 V6 e8 r' l
    3.1. 尾部插入

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


    6 h0 d- E0 M6 p- Z4 W0 x3 {$ ~+ T 6.png
    2 S7 ^, Y$ R; j. v! N3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。( B* n4 J: K* X! s' d5 T
    7.png
    5 i/ J! ]) d. K' S( G) R; T: L- K0 B7 H
    3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。
      # L& _9 E1 _; I
    8.png
      V2 ^9 @+ {5 H* L# [/ C( K3 d, d; C* z& {& W! S' v
    三钟情况的代码合到一起$ f& p; ~. N' {4 ^# ^( X
    ; T5 H1 Y5 W$ s' s9 ]
    /**
    / m( @0 Y$ b! f) C# s7 D! D     * 链表插入元素
    ; F+ H/ W( `& Q+ v/ u( _) K4 t     *: w" @2 M2 E: O9 \" R
         * @param index 插入位置
    9 }1 q8 @) j( d# g4 B( v     * @param data  插入元素 被插入的链表节点的数据
    / a4 }6 y# G; }7 q  B3 H     *// t9 V' C9 O, z6 B7 Y
        public void insert(int index, int data) {' e0 c9 S* y3 v6 c3 Y4 H$ A
            if (index < 0 || index > size) {
    ! t0 n  k" V! D) E9 v7 b            throw new IndexOutOfBoundsException("超出链表节点范围!");' x( T9 S) G+ p
            }2 I0 i6 Z7 H$ B. V9 c# X
            Node insertedNode = new Node(data);2 k& n. @" |: F
            if (size == 0) {
    + x: {+ H' B2 r5 m8 U5 p3 `            //空链表% z( _% J9 I' u- ?1 r
                head = insertedNode;. {" u) G+ S- j$ u; z
                last = insertedNode;7 }2 ^$ F$ h  W; c7 M3 Q
            } else if (index == 0) {& Z1 v4 q. _' B9 G/ [" ^3 h
                //插入头部8 c, ~* I8 b$ ~$ ~0 G, |$ @
                insertedNode.next = head;3 ]8 t: A7 z- Y: ^+ }* A1 J& d& D
                head = insertedNode;$ D* d+ r/ |& D
            } else if (size == index) {
    ) T. w" I5 i+ q! X' k; b            //插入尾部
    8 V( m8 s/ o+ i9 m            last.next = insertedNode;
    ; T9 s  I" Z% k5 ^2 E+ C. \            last = insertedNode;  Y6 ~. O  }: _3 F
            } else {
    & m, u0 k& d2 h/ M- A( ]/ @; @            //插入中间
    6 f$ a' x0 y- ?% _0 s            Node prvNode = get(index - 1);+ ~) I( c; K( ]- P# ?7 _5 p
                insertedNode.next = prvNode.next;
    ( }. E) L4 Q6 K' @! r* a* Q2 [            prvNode.next = insertedNode;
    ; }" |; j  t' a4 R, [3 T7 c, C/ G        }5 n4 S, I7 {/ m
            size++;2 `  }  Q$ l+ T" Y' o
        }
    5 I% j% A) Q. P# ]4 i4 g. `- x# p
    /**
      l/ |8 U6 z& _: K9 h     * 链表插入元素
    ) t) o/ z$ d6 g; Y# V* R; H     *
    7 }# r# C# C% E/ o  ]8 l6 i4 @, Q# o     * @param index 插入位置6 m, p  N* Y. F: L' \, m. N& i
         * @param data  插入元素 被插入的链表节点的数据* o- F. C2 T/ H3 s+ f, _+ [
         */
    * S2 h7 A) D) g7 _& L    public void insert(int index, int data) {9 w: v' K2 [5 a. I) e4 v1 C
            if (index < 0 || index > size) {
    $ \# U1 P8 a" a) D3 R            throw new IndexOutOfBoundsException("超出链表节点范围!");
    " X: ]+ ]& V% `$ s* K8 H4 ]: {        }
      |  x) c+ @7 E3 v' A4 v        Node insertedNode = new Node(data);
    1 S7 @! V8 T6 e4 X        if (size == 0) {
    5 _. R( u5 U6 ^2 `            //空链表$ o! S  K; r6 O3 @* s# O6 \
                head = insertedNode;
    - ]8 Y$ f) G- Y; @) F1 A; O            last = insertedNode;/ _  `* n: s! }1 X& |" }% M& j3 a2 J
            } else if (index == 0) {
    9 O3 Y& u1 R. x0 x8 \( i/ c" m            //插入头部  d3 L# S, q4 p+ d
                insertedNode.next = head;3 _( D( ?) {- O9 @7 m
                head = insertedNode;- ?/ L7 p: m$ B4 b" x! @' L1 W
            } else if (size == index) {7 q1 e8 S' c" y+ l/ G
                //插入尾部
    / \' `: m! m! J) y/ [  f5 |            last.next = insertedNode;$ F! J1 R) _4 b+ s
                last = insertedNode;+ H5 w9 \+ J$ v5 d$ s7 n
            } else {- n* q3 i9 t' O1 S- `0 x  G
                //插入中间  q. B5 W& y5 e: `: D4 e( D
                Node prvNode = get(index - 1);
    . ^# u, `8 d2 o; \            insertedNode.next = prvNode.next;. h, \1 Z! B* i% q
                prvNode.next = insertedNode;
    0 m) R, \4 K* ?0 Q6 n        }
    : F+ s) I) [4 M& G% f* b9 C7 \        size++;: n  r, }8 r) e% c
        }
    4 a7 m% S& w: \4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除1 ]  y2 L! F, g5 h7 K. _1 i
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即
    ) [" Q5 L& l7 u0 U可。

    9.png
    7 I( |3 t2 N6 O* `0 C2 A
    ! ?! o% J9 p' y4 f4.1. 头部删除

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

    10.png 6 |- ^0 r2 r7 x/ K
    & {5 h+ Q' ^$ o! h/ K0 f* _& R
    4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要
    ; ]% S7 H( C2 u( J" V删除元素的下一个节点即可。

    11.png 7 \  P# v$ m9 v* Z4 u! W5 `
    - v9 D# c4 X* _% P1 ]# h

    , S0 p: t; G4 b& a; G: I这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。) r6 G9 ^% i& E+ H! B
    如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)
    . c8 }( d3 x5 |# T# _/**$ O# V. O, z3 ]1 `) _2 v% b
         * 链表删除元素
    % _7 _0 M) z9 [( ]     *1 \& m& ?  h7 x( Z0 O5 G
         * @param index 删除的位置
    4 Q  |# X# v3 J5 B     * @return 被删除的节点
    , A5 ~- G8 G9 A% h     */
    : n. u/ [& a) O* p7 |9 k9 z    public Node remove(int index) {8 S" d8 G# B6 ]/ Y
            if (index < 0 || index > size) {
    6 p2 ^" }4 N5 r& \* b$ c# q            throw new IndexOutOfBoundsException("超出链表节点范围");
    1 h) r8 Z2 J( G5 j8 n# p$ b, ]4 R; [8 X        }
    7 t9 i( z' |, y        Node removeNode;
      f* m( i: b) h        if (index == 0) {" X0 m: e: c7 H0 C* B
                if (size == 0) {6 E7 P8 W* v5 H: B# H/ F* ~3 p
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");
      s" Z6 f, r9 b+ h0 A            }
    ) T$ S, v' V$ X- g7 }            //删除头节点% Y1 l' b  {4 p- O9 z
                removeNode = head;
    4 |1 k" @, D+ v0 _! M            head = head.next;
    ( G+ L+ x3 i5 u# M        } else if (index == size - 1) {
    7 f# }5 O+ h! i9 ~4 Q. Y; j, j7 {            //删除尾节点
    . D/ M: l5 a, P8 f3 E, o, ]            Node preNode = get(index - 1);- \! p+ X2 L4 W: a4 v
                removeNode = preNode.next;; _, T* p0 ~% s' A. b# P
                preNode.next = null;$ Q9 v) S, O4 v" g1 Q" m
                last = preNode;; c, o* D* F% y
            } else {- @5 C; l. @: \2 j! V: N' n2 q+ ]
                //删除中间节点3 k. _3 p7 b/ R& A
                Node prevNode = get(index - 1);
    ) q2 W4 x' I" q( C* X            removeNode = prevNode.next;
    % ?' V% X; Z0 x) A6 e0 e/ s, o; s            prevNode.next = prevNode.next.next;
    1 X- E! M% o- ^" ~% U4 k1 W        }' U# \4 T% [6 \% V
            size--;
    & n8 g% k* W0 _. Y' O6 E0 P7 e        return removeNode;" {; O5 x1 ]' l) k' I
        }( h$ X% h8 z8 a# [, n6 m
    Java实现链表的完整代码package chapter2.part2;) ]1 ?0 b2 s9 {% H: V) [, u
    - f# @( T1 t" X$ }& y' O
    /**
    0 z* g3 W/ a+ p0 S) g * Created by IntelliJ IDEA.% s/ H# Y. T# h4 }. X( }" p
    *
    9 c9 j0 N5 E' b' O0 h  L( G: t- z * @Author: 张志浩  Zhang Zhihao+ K& N* r- v( B2 F3 o% x
    * @Email: 3382885270@qq.com3 \( b1 A$ j7 m/ m# m5 Z. B
    * @Date: 2020/5/34 T) t8 |6 s# x3 U4 |2 F# Q
    * @Time: 13:391 z& ~5 K& H  A! ]& U7 _* O: i
    * @Version: 1.0
    . r% F( ~) S. M */) |6 p7 w% t' R6 j8 h
    public class MyLinkedList2 {8 \% l) k4 f, [* _% f2 R
        private Node head; //头节点
    # _: I4 r$ X! r5 L    private Node last; //尾节点3 \) \2 i4 s7 f
        private int size; //链表实际长度1 d. t/ \0 x' i' I7 ?% q9 e6 J0 M
    5 [: m- y7 T8 b0 H9 p3 N8 P4 K
        public static void main(String[] args) {% F) a# {2 ~4 @% A' I% `) v% l
            MyLinkedList2 myLinkedList = new MyLinkedList2();2 I/ x0 ^( ~; w& _9 i* j
    //        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    ; p  D! J9 |: D//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
    - `. v& T1 E% y$ D* S) {! R        myLinkedList.insert(0, 3);9 E' {( |$ X" o  o
            myLinkedList.insert(1, 7);
    ( I0 L. {5 i5 b( V) d; w1 c        myLinkedList.insert(2, 9);
    & u9 L$ X: g; e! Q7 T        myLinkedList.insert(3, 5);; K) @0 ~' ^* K& @/ f& y6 ~: n2 @9 _3 U
            myLinkedList.insert(1, 6);# u7 {$ n' u. m9 j* H# u3 @
            myLinkedList.remove(0);
    $ z7 U: |. h; {, [1 M        myLinkedList.set(0, 23);
    ( J1 Y% Z, ]% K9 K4 x- F3 Q        myLinkedList.output();
    8 F# f8 Q3 i2 I$ @    }3 T: `7 B3 V* K# {) y
    4 u2 J, @! D/ P& N3 o
        /**
    4 _  j1 g! ^$ ^: h     * 链表插入元素
    ! ~8 s+ k* N) `- |     *4 h& W$ ^$ R& M. C& c) G
         * @param index 插入位置2 I, w& d! c  E3 T7 a: w5 A- i
         * @param data  插入元素 被插入的链表节点的数据
    % U) \, ^9 G9 W, l+ b     */
    - ~  t9 b6 J+ K/ ^    public void insert(int index, int data) {  b3 [+ }1 U" x. I; X
            if (index < 0 || index > size) {
    1 z1 A  C9 k7 K* }& K# S            throw new IndexOutOfBoundsException("超出链表节点范围!");
    : r2 S7 O" z. {$ U  |3 G        }
    * D5 @; q7 V3 c- T- w% |9 O        Node insertedNode = new Node(data);0 o. j* I$ @" I0 P3 o1 m) a
            if (size == 0) {" ?& t  [. @6 y
                //空链表0 n* ?, T; \" x3 p0 F, C3 s+ i. ]
                head = insertedNode;' V7 m9 Z+ |6 T
                last = insertedNode;. b9 C. |+ Z9 n  `) l/ v2 [1 y+ j3 p
            } else if (index == 0) {3 t4 Z1 o( p- l* t7 V/ A4 @$ X
                //插入头部- @7 i0 u+ C& r/ K3 L$ K
                insertedNode.next = head;" z5 P! I1 T. D5 l1 V4 O9 U
                head = insertedNode;
    # M3 G: R% u; o+ l! R        } else if (size == index) {" l( f. \, E& F/ _3 e
                //插入尾部
    . M6 r$ W  N" U1 L3 a- t            last.next = insertedNode;  m6 r7 v, ~  u/ c4 b7 V: w3 o
                last = insertedNode;: J9 r% X" v& C9 L: Z
            } else {2 _7 g3 @7 l. d$ M% e% @
                //插入中间
    # _5 N1 c4 w4 O. _! U# e& ]            Node prvNode = get(index - 1);
    ' {. a% C0 ~0 F8 l            insertedNode.next = prvNode.next;
    0 Q# @( J8 B8 b; H$ r            prvNode.next = insertedNode;
    3 ^3 W9 P9 W% L( D        }$ U4 U  Q4 \  r2 t
            size++;4 S9 d% g6 [( y
        }3 I. D0 N4 y2 O# W% F) b

    : I# G+ A! k9 R; M) c& N, x    /**1 _& M  ?$ ]5 p+ N
         * 链表删除元素
    ' z$ @' d5 ?. N/ Z* b6 K     *
    9 d+ n% g8 g. j& V7 Z     * @param index 删除的位置
    - E  }# n2 n* t6 i  g9 r- v     * @return 被删除的节点
    7 L5 H, G$ c1 c( y     */. C8 M( M) q4 t# L, g8 Y. ^
        public Node remove(int index) {
    - h' p2 G5 X9 i$ {3 o        if (index < 0 || index > size) {7 Q5 m) P, ^2 _  P
                throw new IndexOutOfBoundsException("超出链表节点范围");, [: }$ G# ]- w! `+ ^! e
            }
    : F& P3 ~: B: {$ y$ A        Node removeNode;
    ! f6 {7 f' l/ q) \3 Y        if (index == 0) {
    5 [/ l1 |- P, D3 G( h0 M+ V8 E            if (size == 0) {
    ) H' X4 w& w( q4 O1 L                throw new NullPointerException("当前链表为空,不可以进行删除操作");8 N7 i6 A( F' @
                }1 E# {9 K) f, w/ `! b- `
                //删除头节点
    8 G: K. }& j2 N& U+ @            removeNode = head;
    " e) ?% `( `% h            head = head.next;1 s& L  k* k3 h& ]
            } else if (index == size - 1) {
    $ r2 M4 Y+ H) d. w. C$ J- |9 x            //删除尾节点$ i, H+ J- x! {* c8 P/ Z. Y
                Node preNode = get(index - 1);
    6 Q/ f# y& ~+ B6 o            removeNode = preNode.next;
    & W0 i+ K4 V, s; e. d, u, W            preNode.next = null;
    9 d  U  [* f" A0 ^3 n            last = preNode;' ]- p* D- @, W- a5 n$ H
            } else {
    2 X8 Z# P% f! b) H; t! |            //删除中间节点
      L4 L* }3 d- j" T+ Y) _! p            Node prevNode = get(index - 1);3 t7 c( j% U& G! x( `
                removeNode = prevNode.next;6 p1 V4 }/ z" E& K0 D% @
                prevNode.next = prevNode.next.next;4 K+ X0 ~& E! c: h# C# ^
            }" A8 Z/ K. f9 y4 i
            size--;4 I+ P7 ~3 ?( F+ U
            return removeNode;
    4 s& g5 Q9 r- w    }
    0 _9 k+ ~% ?, G1 @. j& v; e7 _) d: {$ r5 V  e
        /**0 ~4 O/ U( U" U. M' \; ]7 ?6 u
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。+ l3 a7 a6 w; q2 m& y* S
         *4 {. c9 G2 |1 B, `
         * @param index 需要更新的节点的位置
    / v  I) A# ~6 U3 G4 i6 ~     * @param data  新data
    ; ]% J7 ?9 k" d     * @return 旧data
    / o2 U$ d5 e7 n# c0 V9 u     */
    / e3 X) H( t' p    public int set(int index, int data) {) d& W% J; V3 ~2 [" T9 t8 T2 t/ c3 B
            Node x = get(index);+ ~+ Q  t/ @: e0 n
            int oldVal = x.data;5 q! `' P6 o4 [+ G: E
            x.data = data;
    " P, k/ l/ D) b) B; o+ b! c, M        return oldVal;; o3 r. D+ k/ l. L1 s% K* D
        }* Y% c; w; L$ i3 c* n# c

    6 C6 }& K. Z. r    /**7 h5 `/ H/ ?: K9 b' [, `! T
         * 链表查找元素: G; k  s0 s( w2 L9 f6 h
         *. y8 }$ ~1 Y, T5 z' b
         * @param index 查找的位置
    * @. J1 y2 |8 X' \: h     * @return index位置的Node对象" U. |; E+ J  Q* K8 F/ F: F! D
         */+ n% j# M1 r; q3 s2 F* j& x
        public Node get(int index) {
    8 Z2 r, E& r- N        if (index < 0 || index > size) {
    2 R, ?4 @8 E% ~+ j1 ~            throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    7 R: |/ i7 u. Y        }
    3 d  ]6 r# F$ K! r$ r1 S; r        Node temp = head;
    ' ^; ^. p/ K' j4 D$ h7 o5 u* t        for (int i = 0; i < index; i++) {; E7 T5 `  b& T+ q+ U- p! ?
                temp = temp.next;
    ; y# \% x' u# n        }
    / e* y; t( f9 C& D4 A7 z/ O+ E        return temp;
    : E  f- `% c/ k5 g; X) K( z" ~    }3 Y! d- t5 Z- Z2 u4 Y3 B7 ~
    3 U! J! F0 ^- I' [& \
        /*** F* c# r6 W9 ~5 @! B) K
         * 输出链表/ g* O' ~. Y% W, D
         */
    0 i% ]' Z; a) P# @* z3 |# w5 J6 v) ]    public void output() {* z% c  \( e6 i4 O7 }8 J
            Node temp = head;
    5 }& G$ g# I; y0 S$ Q        while (temp != null) {
    * B2 ~; R9 @3 R; G0 j' m            System.out.print(temp.data + " ");/ c+ J% R) _: z) X/ z/ r
                temp = temp.next;
    ' E0 G- R; O+ A        }
    . ?  C: \& K5 {) X  h$ g    }
    : S$ J9 A! p  k
    0 W$ S* D0 Q7 L6 w    /**3 U4 V9 F$ m! L  ]3 _' ^1 c7 _6 V
         * 链表节点
    $ L1 e, H8 v9 d7 I  d     */& {, T0 ]2 N8 c
        class Node {  j( j* ~3 q; {0 d5 r- K
            int data;+ |* y- D8 T9 d- p7 t, [; S: L
            Node next;9 f7 A" g4 z$ m* T$ I2 g8 m4 }1 L

    + ?) s6 Y9 W' K0 p0 f+ b: z; S* f        Node(int data) {
    , E& k9 X; s- z0 O& |            this.data = data;# `& Z) e- M4 U, c
            }
    + r* O: M7 u$ W( x    }
    7 q+ f8 G0 {& i" `}
    6 D- y$ V/ ?  W% S- V' U3 K  c$ q+ O$ [/ v# s- _
    . |" Q2 W5 n) n3 z, y2 ?
    二、双向链表 12.png
    & k" z. v4 ]: p: z9 w, c双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。3 }& x8 b6 o) W

    " M; x' k" b2 u/ ^0 U5 i
    6 a: w8 N2 e# _8 C# a- n! r
    - P5 z0 S9 z0 n/ `6 y
    3 ~5 `5 D5 E6 U8 a8 T" J————————————————
    9 g) [5 Y0 m1 Q- D9 I0 j% }! b版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ) v+ @& u! @8 X3 X$ v. N9 |原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468
      L' {2 W0 @/ Y' V( _% Y3 J( u. E; R
    & J( l1 p7 _. U3 j% ?3 r& [; ]' d% D4 U8 h9 U3 _

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

    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-4-20 00:00 , Processed in 1.191222 second(s), 53 queries .

    回顶部