QQ登录

只需要一步,快速开始

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

    $ }8 {$ d7 G5 v9 J* D) f【Java演示】什么是链表?数据结构! x$ C& R7 M' d1 a2 h1 S' T
    一、单向链表
    % x+ r# H: O, r. P, s% ]- W: {+ ^7 F# M
    1.png
    0 N5 o& z# V- N5 Y( n# d链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。
    - U5 R% w) F5 d: t' [* T单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。5 _4 I7 a/ \7 A+ f5 |
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。
      {/ O1 }  j) _, t+ I, ?4 G( p3 G
    什么叫随机存储呢?- \9 [' I: `' x+ {+ C
    ( o8 W# \# ~( A# g5 c
    如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。: c3 ?3 i) ], s4 c0 L
    上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    # I! b1 p. p1 u9 T) { 3.png ( C" r6 Z/ X% g) x7 g; @
    ' G% L7 x6 m' n8 n6 R) {) b

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

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

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

    4.png
    9 P  u; w: I4 D5 h
    % q4 P; K; C7 |- @. _3 F, C/**
    # X  S1 T( f+ z( v! U     * 链表查找元素
    - x* y, m  O6 G; h# T- b6 }     *
    ' w4 K8 W, S' U+ A$ Q4 E5 A     * @param index 查找的位置
      _4 [' r! J: B- z- R: N3 a" z1 K     * @return index位置的Node对象
    ! h7 `2 I9 s  {: T     */' M& v( ?4 ?) _$ H$ \* k
        public Node get(int index) {
    % O% z& ]8 Q& t) E; R        if (index < 0 || index > size) {* V' |. N+ i; d3 `3 H) g
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    4 |/ G$ y- }) K- P; J. }1 X        }
    ; T% p: i( r" E3 v; s- @+ b        Node temp = head;  C1 p$ T3 y' ]
            for (int i = 0; i < index; i++) {! ]* @4 n) S0 p
                temp = temp.next;6 z- K1 I, D2 W0 c! K
            }
    % |) x6 R. x: `( y* _4 Y0 i        return temp;6 l1 m, n$ t! J, F$ C7 q
        }( l: `; K" ^' Y

    3 g; Q$ J8 W+ }- B6 E  M% C

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

    2. 更新节点 5.png
    * Q/ s5 u% h7 ~& e3 D8 `9 [9 R$ D& \, ?) w7 r" s# b" W
    如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    8 N- O! g# x& s6 q' @/ A如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)
    1 W" O3 Q1 h9 H, ?/**2 s8 e: p# F9 @
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。9 r6 Z- Z5 L% p
         *
    % [7 C) _" i: B+ N0 k9 Q     * @param index 需要更新的节点的位置& X4 P4 O' l* A$ q* `. @
         * @param data  新data
    , z( p+ G. p/ F2 y2 C: ?, I* E     * @return 旧data
    * F7 _- |) K! ?+ j& E     */
    , F# s, m' ~1 X" G, M- t' Z    public int set(int index, int data) {
    9 N$ w; G% v, t9 a9 n        Node x = get(index);/ f0 U3 I4 Z5 d  L# r/ O
            int oldVal = x.data;
    ; _8 {2 p* Q6 T3 E        x.data = data;
    1 e8 C" b  c3 T( r6 o        return oldVal;7 n9 M) L3 i! i8 I+ Z# i
        }
    * V$ l5 m$ d! N; A: R: {
    $ l& e4 x0 C* \3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入* N8 s. Z. b/ N( d
    3.1. 尾部插入

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

      o6 \# }3 D+ F0 k9 x" D
    6.png
    3 X3 K: ?/ f" n# h8 Y/ I3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。
      4 s! {% h0 T4 }; Z  I
    7.png 0 p' D# A7 t' [, K
    7 ~6 F$ J, K/ a: i- h
    3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。
      ! T$ n" K$ H& v0 y, _8 N$ g
    8.png
    * l& n9 |* o! {8 [, F% `4 {1 j8 E
    三钟情况的代码合到一起
    + a% {' m9 ?! D
    2 t) U' S0 W  [( N/**
    / ^3 b& R+ _) m5 Y( T- H     * 链表插入元素* @( e( F. C/ H
         *
    6 p! i7 G0 e* U" Q( Y     * @param index 插入位置
    ! }5 o" J2 H1 ~& W6 ~' Z     * @param data  插入元素 被插入的链表节点的数据
    2 ~" s2 z1 q5 |5 A( ]- g: @. [     */
    . d; K8 K7 W& B2 o! y3 A, R% J; H    public void insert(int index, int data) {. }( z; A3 Q$ N% Y& R+ i" m! `
            if (index < 0 || index > size) {) C% m. X& X3 R2 v
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    / ^! |( I9 r/ E8 v" @, ^        }
    1 @9 b' B" p1 X; j% P! V# E        Node insertedNode = new Node(data);
    ) n9 p$ b: k  W' s        if (size == 0) {
    ! N7 E: `; x/ [            //空链表7 o5 F( P# s  J: A1 b
                head = insertedNode;8 L. c1 s9 `6 A; B! ?6 C
                last = insertedNode;
    % a- C' K4 E- _        } else if (index == 0) {8 T% t# |9 q( W. F7 O
                //插入头部3 D0 E4 h' m# r2 J
                insertedNode.next = head;
    % @8 B. I+ m' e) N, f# d, f            head = insertedNode;
    ; X$ z# j0 E; m0 z# C        } else if (size == index) {# Q% ^3 P+ s+ G- g6 C
                //插入尾部2 n/ Z7 ~/ `( L3 ]; i: m
                last.next = insertedNode;- N* }! f' i- m! S8 G9 _( m
                last = insertedNode;  k7 X9 g  s3 A. k) b
            } else {! ?5 B* [! S6 C7 E5 m
                //插入中间
    * d* l0 F0 }7 S( z0 f' ?            Node prvNode = get(index - 1);* B# l% [4 y7 \+ E% ^! C
                insertedNode.next = prvNode.next;
    . x2 V/ n) y. p. F' b* O$ z2 [" U8 \            prvNode.next = insertedNode;
    ; m% S1 U3 j/ c8 a        }
    * O5 U5 m* h6 b& J" o! Q        size++;
    & n% N0 C! X. _2 F    }1 D3 p9 N' S1 D" Q9 \1 ~
    / k2 a7 k0 D0 t3 r/ h: L9 r
    /**- g' w( x  y) y2 a# A' c
         * 链表插入元素. S- F& g) ^% {
         *
    ! b9 A+ M# Q- M% H: L; D! X     * @param index 插入位置# @% j2 v/ C; U
         * @param data  插入元素 被插入的链表节点的数据
    # }3 K2 Q. g; e* H, _     */0 {( I7 r/ E. a
        public void insert(int index, int data) {% Q/ }- k( S& J+ q* x" ?
            if (index < 0 || index > size) {# m$ \8 O  Z; n# M
                throw new IndexOutOfBoundsException("超出链表节点范围!");7 E  p/ X" ]3 G6 a" n5 X
            }
    3 b) B. g# ?- h/ p        Node insertedNode = new Node(data);
    . c. u0 Z( h0 }+ K" G        if (size == 0) {
    : D  _4 c% P$ ]! k0 r' B            //空链表
    & Q- w: _( u. ^' l' N            head = insertedNode;9 x9 P/ N& I" L$ N$ U9 k
                last = insertedNode;
    . j1 O+ Y% [& @- k4 w9 C6 [5 v        } else if (index == 0) {8 ]+ F" ?+ j. Y/ Y9 r% H2 }
                //插入头部
    / e% R( G+ D. T; @            insertedNode.next = head;
    ! F- B" }  D! g6 w$ B! C7 v. m            head = insertedNode;
    - Y3 f- D' l2 r( [0 e        } else if (size == index) {
    3 S; d2 z: \: N. x0 G& ]* T1 v( O            //插入尾部( L& l' c& l7 z2 f' v" H
                last.next = insertedNode;* o( q6 U2 Q5 u
                last = insertedNode;
    8 r* h+ v- `9 \1 X0 r7 J, O: U        } else {# ?# ~" `3 V- C: H' l, l" k2 f
                //插入中间' `0 U& y3 X! j, |
                Node prvNode = get(index - 1);
    . q2 l* T, C7 }! ?+ b6 D            insertedNode.next = prvNode.next;2 }, {; u/ V) `
                prvNode.next = insertedNode;
    3 @7 y! c3 E2 J5 N        }& b9 Q$ ?2 ^! s/ h" A/ ]7 M5 B
            size++;( E1 F4 D" w# m; q, T
        }
    ' D! o# R  y( Q$ J! c4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除
      4 Z/ \. q! f* i# ]  O% ?, |
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即
    ; d! P0 t, r4 I可。

    9.png ) }3 `2 l! |- F2 x( s: @

    % u% {: ?' U! T$ X3 B4.1. 头部删除

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

    10.png
    + ^. ?7 F; |1 m" H* t9 n
    6 o5 E& n* u3 F* v! A9 I( n4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要
    * a, N( e0 S- B" J) m删除元素的下一个节点即可。

    11.png ; J4 t7 z( P$ b5 K' A6 ~+ e6 F9 ?; b
    7 J9 J% X: n9 R1 |) n
    5 G& x; g& b& z% g/ \
    这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
    # z/ r5 ]& T$ j/ \如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)
    ' S0 b! z% f  Q/**
    / P6 Z" b# g0 a     * 链表删除元素
    $ J7 i3 }' k; z* q! d2 I  O+ X     *6 k6 C# o! x7 J2 N" l' x
         * @param index 删除的位置
    . g7 d4 o5 }3 a     * @return 被删除的节点  W3 I" I: p5 f. A( Q
         */
    : M, I. d- y$ K) s& f    public Node remove(int index) {9 t( V  v- Z8 P# C  C
            if (index < 0 || index > size) {: {: {/ U5 P  s
                throw new IndexOutOfBoundsException("超出链表节点范围");
    % |5 O1 b+ s, p; T        }/ U' J, i- u5 S5 r4 i, K( \- }
            Node removeNode;
    * J4 ]& \& }+ Z2 ?        if (index == 0) {
    6 G2 V3 t3 T8 H3 N            if (size == 0) {
    : l* I/ s& W' g: v8 E( \                throw new NullPointerException("当前链表为空,不可以进行删除操作");" b5 a! |/ ?+ g* x- j" ~; S6 L
                }( }7 [2 q4 l! K! t/ L' C9 V
                //删除头节点5 b) U* y1 H7 {( X/ c
                removeNode = head;+ p9 H+ N) h' O' K+ D# [& G
                head = head.next;# w( I- p5 g5 S! [+ N2 c- W2 M. o: K
            } else if (index == size - 1) {
    + u4 S, U% w: `            //删除尾节点) \  q: w5 C: A; H2 a0 _8 ]1 `
                Node preNode = get(index - 1);5 X* j! O, X8 Z9 L/ c4 P* G! h
                removeNode = preNode.next;
    6 E7 o- U4 e. q8 N- P            preNode.next = null;
    : D, v2 l. ]$ [: ?/ J8 T            last = preNode;4 E  U0 J0 }4 {( u  U
            } else {$ u. g0 N% r9 l- k: ?
                //删除中间节点1 u0 b$ ^2 @( j# S0 h5 {& Q
                Node prevNode = get(index - 1);
    . B; R9 U1 Z& z  Q, Z& S            removeNode = prevNode.next;
    - H5 V  d% n) ?2 X1 K. _7 m            prevNode.next = prevNode.next.next;3 O6 y& r& O( s  {0 z
            }
    9 B0 Y# g8 H. c' }' i        size--;) Y& j7 C, F+ i. U2 d" _8 N
            return removeNode;: O% S* i2 _# x
        }
    & w" f  C$ K& c3 H* C! CJava实现链表的完整代码package chapter2.part2;4 R) ?# h; o& w

    6 ]( a8 S* C8 ~3 q& @+ W/**2 i8 s; D0 t. [  H8 d' [- q
    * Created by IntelliJ IDEA.- q; r, O- @! \7 L4 u6 f
    *1 N& a( C1 d: D+ M+ ?, O5 _
    * @Author: 张志浩  Zhang Zhihao9 M7 R* U" B& P1 e5 ?3 q+ J7 O  m
    * @Email: 3382885270@qq.com! D! J( d; Z2 h0 r5 D
    * @Date: 2020/5/38 }3 X. e. @, _7 u) U, [
    * @Time: 13:39
    6 V( T+ W; ~% c0 \' ~ * @Version: 1.0
    . f* u8 V2 h$ L6 Q) I" [6 t */, \9 y8 u7 _4 m$ y% q: I$ H
    public class MyLinkedList2 {1 A$ B, ]. A1 B4 N
        private Node head; //头节点
    6 a+ }$ o8 e7 z$ h- a$ {5 k    private Node last; //尾节点) k0 u2 j2 f) y& Y
        private int size; //链表实际长度& @0 _. V- R* O9 X

    % M4 E; X+ ?6 L, A, D    public static void main(String[] args) {
    , N; k& G2 y+ ]4 ^5 `; i2 w        MyLinkedList2 myLinkedList = new MyLinkedList2();, f1 K% g  u: D* G# T8 I
    //        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    - o' u3 f9 n# x5 i//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围1 D4 ]7 \  r- ?$ U: x) x' K
            myLinkedList.insert(0, 3);! y( R1 g+ {% H- ?; Z+ A( K2 `
            myLinkedList.insert(1, 7);. U( }! j- ]% ~7 z2 G6 o- c
            myLinkedList.insert(2, 9);* v' x9 B1 p1 q- Z( J: G
            myLinkedList.insert(3, 5);: T( C9 i9 h# q! T$ C8 M4 p8 |
            myLinkedList.insert(1, 6);+ n3 W4 G2 a! N, _# i1 {, I6 E+ g3 \
            myLinkedList.remove(0);
    " r" E# ?2 V4 C3 R0 h, R        myLinkedList.set(0, 23);% s. v8 P' l* {- Q7 `8 U
            myLinkedList.output();- D+ {2 c' _9 D% J) d
        }2 l: c! j* }/ I

    " F% M8 D) r& F1 J7 b) Y, w6 C    /**- N8 G. k" f8 f/ w! z
         * 链表插入元素! i' y, U% @: @' D& d
         *( i- _. m% C: A! j
         * @param index 插入位置/ s" a8 X2 r/ d+ {  ]' f
         * @param data  插入元素 被插入的链表节点的数据
    ( s, U# n3 y% ^* s, D     */! g+ p1 {) g' v+ T, W  E
        public void insert(int index, int data) {) Q  _9 f: d6 J- R& |+ K8 S" d
            if (index < 0 || index > size) {
    ' w/ x+ e, Y4 l$ A# K            throw new IndexOutOfBoundsException("超出链表节点范围!");
    . `% T* L3 x# J4 T9 V, h; n        }
      v3 g8 ^* g2 T1 L        Node insertedNode = new Node(data);( l$ C7 N* @  P6 G. Y
            if (size == 0) {
    ' U) h- g3 R& k- N/ c            //空链表
    & V$ c5 q. H1 t6 C            head = insertedNode;
    . Q5 T% T4 r; K, _  {1 q4 O! D            last = insertedNode;
    9 H: q+ k, Z# h8 _        } else if (index == 0) {
    1 ^, x( k( I; g5 g  J% z            //插入头部4 F) y. u5 N8 ?+ c) N
                insertedNode.next = head;% p8 e0 Z- |9 Q; H; E% B
                head = insertedNode;
    4 C8 r1 B/ L7 [' e6 d. E        } else if (size == index) {% y% `* k( @4 f6 {/ K' K- K; Q
                //插入尾部
    1 l( v% A/ P4 j            last.next = insertedNode;) z2 m( T, o) U; p
                last = insertedNode;+ ?# C; O' y# D3 d& `+ L6 C
            } else {
    $ x) o, x, t1 A  v* S: F) }            //插入中间
    : N1 d% I7 S+ f- O- L' X' w* }: d            Node prvNode = get(index - 1);
    6 k7 U4 b$ I6 r# C+ Z) ~$ x            insertedNode.next = prvNode.next;9 I1 w* |3 C4 ?
                prvNode.next = insertedNode;7 u5 ?! o6 }# q& K9 a; E7 u$ e$ H- V
            }
    % h5 z9 v4 ~6 a$ \) v8 y        size++;
    2 f3 [4 w7 f8 E: n    }" T" P8 V1 j4 J) ^

    7 c( a2 x9 b1 p2 X    /**
    ' |! z3 Y7 W+ ~! r4 e     * 链表删除元素
    " l9 B! R9 J& C) S0 c- t, ?     *
    3 r& C, i' n: y% F. S     * @param index 删除的位置" p2 [7 ]1 k& ]+ Y
         * @return 被删除的节点1 H6 }6 c$ t% v
         */
    % h* W2 t( u1 n% Q; w  i; M    public Node remove(int index) {3 M' ^* H, a3 O) h
            if (index < 0 || index > size) {
      \! \$ N$ M2 `. h2 Y% s0 H% i            throw new IndexOutOfBoundsException("超出链表节点范围");* P8 K  }' D- R9 x
            }
    9 c6 t& ]/ S2 J" ?$ d        Node removeNode;5 ?2 ~6 R5 R' m# w5 C, L
            if (index == 0) {' Q, Y, `# J7 w. c0 D
                if (size == 0) {9 }$ A. @( W2 w5 i0 d) ?! ^5 Z
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");) {% {7 Q, g6 t" H8 @* [
                }
    , S0 C" V8 R9 |# T( B            //删除头节点  T1 j9 o+ y1 T9 f% |
                removeNode = head;  B' b1 K: P1 F* t+ m5 |9 \
                head = head.next;
    . X/ g3 i7 C1 E- |; A% l        } else if (index == size - 1) {1 O- s! \. L# @# s3 t
                //删除尾节点) T- H7 x9 E) w5 z1 ]
                Node preNode = get(index - 1);
    # S; [# ~8 c* E4 j            removeNode = preNode.next;
    ; l& B4 ~, |6 X: R            preNode.next = null;
    + ?9 k) ^9 m1 ~* q            last = preNode;- b" l/ G! k' Q5 K0 r# R
            } else {8 ^. R# J- Y9 D! ^
                //删除中间节点  u% ~( G8 c( E  X
                Node prevNode = get(index - 1);4 k5 I7 d( Q" `4 V7 z4 }+ c, n
                removeNode = prevNode.next;
    4 E) ~5 J( ~0 ^7 Y# P/ ?% S            prevNode.next = prevNode.next.next;9 W0 p/ l5 s5 J. y# D. Y! k
            }
    7 H8 T6 T: k$ ?" S        size--;
    . O4 p4 O& p2 g' W6 K        return removeNode;0 {6 m& W$ k* T4 _" u
        }
    0 D3 j0 g7 C& l+ g1 o& e* w8 N4 J9 C- Q
    9 t& Z- l' d2 S    /**
    - J3 N+ v, b# p+ a/ e9 g0 R1 w     * 更新节点 将列表中指定位置的节点的data替换为指定的data。' s. Y0 \7 U% A$ }( H
         *8 j( b9 [6 F+ g* d# G
         * @param index 需要更新的节点的位置2 H5 `( C$ V: o$ ]2 Q* B
         * @param data  新data) z* M# a( N+ j. q
         * @return 旧data4 {9 s4 @' m9 G1 d. G; Z1 Q6 k+ V
         */% n7 |% f+ g2 w" [
        public int set(int index, int data) {
    ! W4 ?8 Q7 s7 O        Node x = get(index);
    $ \& f1 P/ Y5 A& K6 ?; M. C8 G9 v6 V( W        int oldVal = x.data;( _4 H" t" E7 C# [6 l2 ?
            x.data = data;
      A  K$ d3 V! g" G0 a6 t% ^& r        return oldVal;5 |; D4 L: T" P+ D- G; L/ r
        }, o0 Q* j/ e7 w

    1 Z+ m6 Z9 k( ]    /**
    ' X1 [  _3 v) O8 V  D' U     * 链表查找元素0 p: F! n2 _- W% }6 C9 K; }% B
         *& B( K& S$ g( _) D6 M
         * @param index 查找的位置! L1 w. ^2 ^' a) t, e& D, |, B
         * @return index位置的Node对象# J# r: I9 l, G
         */* N$ _/ x9 r$ B3 H, q) d- C
        public Node get(int index) {0 H6 b9 F2 ?7 g! ]  T, m) ]0 i7 @
            if (index < 0 || index > size) {& o" t, U! n# a, n. G8 o4 [
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    ; P4 J( X$ V3 E        }  n# {' d- }4 d9 w4 x
            Node temp = head;( k% q) i" G0 Q- e) f
            for (int i = 0; i < index; i++) {9 ~- Y' L( `3 l* m( i
                temp = temp.next;4 M, H  x/ C9 c
            }; Y: @8 |: a; [8 i
            return temp;
    2 l6 z. }2 N, C! k4 [+ n    }
    / A' \4 V# v4 U- t: P& V9 z
    # J! U4 F1 G# R( o+ Q/ u: y    /**
    # _* Q' J5 {: P, f) w     * 输出链表
    % z. w  v( \# n" T$ \2 {8 j/ e     */( h2 A' P' o  y. ]5 r& |, b8 t2 j
        public void output() {+ `' }- K0 k; j3 u1 _  w3 E/ p1 @
            Node temp = head;$ Q* ]& q' A% r+ n
            while (temp != null) {8 @# @, y0 l0 m* ?$ T
                System.out.print(temp.data + " ");
    2 \) B" U: q! g6 C; ?; f+ t            temp = temp.next;/ o% g" s$ a" ^4 z( D
            }  v. X) i" q9 R
        }
    + S) X) t0 _7 H) h- X9 [$ n$ ?2 n. ]0 Q7 f, ?/ {# o  d6 @
        /**5 s3 M# H% T* ]' Z) @7 B
         * 链表节点
    ) B: ^4 q3 B$ L0 j     */
    : e- m2 {' [. `+ E: O9 R; ]    class Node {
    : c+ }% |. H; O3 h* r# e! g4 H        int data;
    5 W6 w; o. T7 P0 q7 U        Node next;1 t5 v( G( ?  R. b8 W
    5 T* i5 d9 ?) p+ ~5 H4 X
            Node(int data) {
    + x& F+ |' L- m, z: v3 M/ B            this.data = data;
    $ [/ m4 T4 \$ L9 Q  u, \        }0 s2 T) a# p0 G$ O: E+ a
        }
    & }. @) ]7 q$ O0 O/ [! G}- t! |  X5 l7 S1 Q
    ' A9 d/ c1 ]. ~! m9 [
    : c4 Q1 V& q7 x4 `; R
    二、双向链表 12.png ) R9 U  |! G6 [! I% j
    双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。
    & U- V# @0 m& {) _
    9 q2 F; q9 l* F* u+ c/ ?1 K' @* L/ {6 Q2 l- C2 I' G/ h
    & Z4 p/ e- c4 }( @5 C' ?+ i# a

    # B4 U! s* ?& i; Q3 t% b  M————————————————8 p' P' ?$ X# c6 O, B% {
    版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。. s$ r( [  d' z5 @' n
    原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468  R- U$ g$ N8 r" [5 W
    9 q, C5 l/ N, [0 {3 T

    0 D, v: }2 K$ A3 d, W! `0 I

    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-7 23:35 , Processed in 0.744897 second(s), 53 queries .

    回顶部