QQ登录

只需要一步,快速开始

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

    / I4 T; K+ w! s+ z4 X, b【Java演示】什么是链表?数据结构" V) Z8 L1 ]; ~0 b( \! a) B9 [
    一、单向链表# V4 i+ X& \5 ~9 I

    ) ?  N" }; i0 D  J. | 1.png ! M4 ]2 A' ?/ T
    链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。; b1 Q( G, q9 n& d& z# Q1 j
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。  r: k/ U8 r/ G/ v
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。( d  @7 {$ b) I9 Q

    9 a/ H+ F  o6 T! u9 y0 Y1 |9 I' V# u什么叫随机存储呢?+ ]1 f6 B$ g  J; l; `1 h
    * g9 U- ?! m. J. W
    如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
    3 m, s( p  D. S  e) _' [4 \# X上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。! N' a- C- p! |; v) ~8 K
    3.png
    . J! Q4 N' h: g& H6 v" E3 X0 d; @" f) Z8 m1 \, h' l* Y

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

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

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

    4.png & I, X* l0 U$ t1 K: g

    4 C- `+ N7 t8 {) g9 B4 r/**' P  Z; k# ]8 l7 Z& e
         * 链表查找元素
    & C) i8 f2 y0 B3 T  b6 B6 u; O     *+ Q, t" b' T9 \/ k3 H6 N3 _: T
         * @param index 查找的位置
    + v- h( N) H& x) x0 w+ n: E     * @return index位置的Node对象
    % j5 J  M. L. d     */. p: o" y3 o" i( h
        public Node get(int index) {/ B5 U) Q) ]% V1 u3 W3 V$ U& F$ N' b
            if (index < 0 || index > size) {
    % q! ^/ ^. s! I3 [9 T: r% O            throw new IndexOutOfBoundsException("超出链表的节点的范围!");. {+ t$ l% L$ d1 |5 X
            }
    , A: [: c2 ^  Y0 B, R- J* q$ n: c        Node temp = head;
    / }% i2 ^5 `+ @1 T" ~        for (int i = 0; i < index; i++) {
    + o- r) ]' P$ i' E7 R2 G            temp = temp.next;
    2 {8 s0 E+ b( E, d8 ]7 l) N  ~        }2 j  h# q& y0 j
            return temp;
    7 Q5 Y* j8 x8 v    }7 k5 a. [+ t, z* x4 }

      e0 D  L- J. r: y& ~  T% R. O& a! Z, M" S

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

    2. 更新节点 5.png
    9 `$ A) j( I& [0 B- w: J9 r
    - s% P3 ^5 D& Y; u4 G  V, d1 `! _如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    6 @( C  x) P. Z' c3 V如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)
    5 U+ e+ ?0 b% q9 |  q/**
    , `" u  e7 g0 s2 l  G     * 更新节点 将列表中指定位置的节点的data替换为指定的data。# k  N1 H/ `1 [/ @2 W3 U0 x
         *! D) \. X8 j; f& f
         * @param index 需要更新的节点的位置8 K2 |1 R4 [$ I  U! f; J) z+ z
         * @param data  新data
    , {+ j4 c9 R# w( n6 {! C3 ~* R5 A     * @return 旧data4 Y" E6 b" L$ ^" Y
         *// K9 J" N: }( G/ Q9 u
        public int set(int index, int data) {
    , t- u; f. ~' a/ j. N. D7 |        Node x = get(index);
    6 g) T" p: d+ f1 L        int oldVal = x.data;
    4 v6 ]/ Y* a3 \, }( s        x.data = data;! X; u% C; E/ o9 X
            return oldVal;* ^6 G; u+ `$ \7 [- s6 e) t: U
        }9 s$ S5 y0 E$ h9 T
    $ Z. e* H" S: q, q5 K1 Y& V
    3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入7 I1 |2 T0 P3 I9 g
    3.1. 尾部插入

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


    4 U5 {$ a- p0 [- \0 R4 f; g4 a+ z 6.png : g$ Q  w4 t# e1 ^/ I/ L/ I* l
    3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。8 X+ y4 {& p$ {) e4 U) _# f! v4 N
    7.png
    % _1 t. z. k0 o: P) ?. D
    - t3 |; y2 w. o* f( w3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。+ ^4 |" x  V; @$ Z
    8.png
    . Z  `. G, ]. F4 \& b
    7 q5 m" a$ ]( n+ A' f三钟情况的代码合到一起
    - N4 f+ J9 w! M& @( L5 f* k0 Z" C" i9 l% B; p+ x5 h
    /**) |8 L% c: k$ T# U+ E
         * 链表插入元素4 N. c$ e* I+ P0 ]
         *
    , Q7 F" ^7 L7 d     * @param index 插入位置# g! t0 ?5 K( j( _; ]- ?
         * @param data  插入元素 被插入的链表节点的数据; M4 X1 G* |* ~; ?* n
         */
    * M' t0 l4 X9 f* }/ [. }5 Z' y    public void insert(int index, int data) {
      @/ h& c/ D+ ^& i: T. T        if (index < 0 || index > size) {* u9 _# ^4 u$ _+ o( A- l
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    6 S* v0 h; k( E. x) c        }
    2 f2 p1 T# |3 G( Z+ k+ d1 G        Node insertedNode = new Node(data);
    : F; k) z" l2 r1 b4 n9 N7 e) h3 l# @( y        if (size == 0) {
      F( m1 _1 k% d# ]7 S            //空链表
    0 r, Q8 E4 f5 Y+ D- E! k4 @1 _            head = insertedNode;* y9 [$ V. E$ |8 x
                last = insertedNode;
    ; q) v" ~- c) m        } else if (index == 0) {
    / y  C8 H; P7 W% n6 |8 H            //插入头部; e, n- N2 t7 I! H9 S
                insertedNode.next = head;
      Y% ]4 V8 y! I2 v. X1 L            head = insertedNode;
    , K! Q; x% h! }5 I        } else if (size == index) {
    2 x2 b# b$ S: x7 i7 P# Z            //插入尾部8 M2 {# r. L1 g6 c1 [
                last.next = insertedNode;1 p& \4 J! Z( Y9 A$ [" @8 l2 d
                last = insertedNode;
    * N3 e- r0 _, N. {- @8 G8 X- Z        } else {! @* b. Q3 b' [1 @# Y
                //插入中间  t0 W& s% k* p
                Node prvNode = get(index - 1);# k6 G3 W: f3 L
                insertedNode.next = prvNode.next;! O0 D% p. ]1 S$ I5 U# A/ j8 O
                prvNode.next = insertedNode;
    & J- x! p6 Z6 F% S5 I8 E6 b* g        }! z6 E/ J1 X8 y7 W7 h! Y* a
            size++;9 \& w1 j" M" C) {& D9 a( I) e' @: a
        }& ~( I# J* L1 ], {/ z% p' R
    3 ^9 V" M- i1 d" Q
    /**( C: J" i  I  Z) `
         * 链表插入元素, i6 E/ R. D6 ~4 I) k
         *
    2 Y7 p: B4 E8 q3 }* n' G     * @param index 插入位置
    6 w  ^0 F$ P8 \6 Z     * @param data  插入元素 被插入的链表节点的数据3 f1 l7 i: P' R) w
         */5 y3 G0 w. N* V; @) o) E4 f
        public void insert(int index, int data) {- s8 _. u9 t) @1 V4 F3 F: j
            if (index < 0 || index > size) {/ k+ J2 k  U  j+ K4 b
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    ( q8 o+ ]& z  |2 k% t& i1 E# E        }, M& m5 Q6 s$ W7 s, H) K# X! }& f- V
            Node insertedNode = new Node(data);! ?0 k- I* E" x8 p- b% ?
            if (size == 0) {
    6 _1 J% T0 k4 r            //空链表* J" w7 A; @. p, z
                head = insertedNode;
    : }2 k! g$ o9 V- E7 T' z! Z0 x            last = insertedNode;
    # p9 Y- J9 s9 P) t: g0 \        } else if (index == 0) {  u7 m9 }" W7 P% e4 U5 q; J
                //插入头部+ S* Y& D0 H; k+ S" N8 M5 |
                insertedNode.next = head;) P: ?; ]4 G1 \/ |. D+ d0 U
                head = insertedNode;
    5 M" l' p, p6 u: Z0 v        } else if (size == index) {
    ; I* y* x' T( R) [/ }# ?0 l3 _. G            //插入尾部* z8 y* L+ f" `. h3 B: \
                last.next = insertedNode;' u1 B7 ~4 M: ?2 t! o
                last = insertedNode;
    . k$ N: Q( n$ C        } else {+ ?# X* E2 N* u! N- L1 I" I
                //插入中间" P, v5 V* t, t$ W1 |+ `2 b
                Node prvNode = get(index - 1);
    2 t2 }) w& Z8 ?+ l            insertedNode.next = prvNode.next;
    * D: ]. F! y. j/ K" ^. r* \            prvNode.next = insertedNode;- ?3 D- w* T6 |) y; _
            }
    , Y' S, a3 d/ P1 D        size++;
    # S1 H5 M+ k: h0 R5 f; \    }. u( z2 i# U' u
    4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除
      ( A8 ~0 T8 e" c: u. U# }
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即4 ^1 Z7 }6 m) {' V9 B1 M
    可。

    9.png ! o( s( [9 x! E( ], [

    ! ^0 D! {% u( Q7 i, G4.1. 头部删除

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

    10.png ) l& g4 G) \6 n: o; v5 T$ W% L

    2 x9 J- ~& p9 {# e- r4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要
    $ l3 b# {! B3 W4 a& r) x4 c2 w删除元素的下一个节点即可。

    11.png
    6 I2 p6 c$ u, R
    7 _, \3 {( c& {% `
    % _, S$ e/ r. S1 Y3 D  h这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
    # ?# i9 @' m6 b- V4 m; Z* @# W如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1). m' a8 `& `5 ?; O/ M/ q! s& ]/ K
    /*** u" v# {! t9 ]/ ~1 l- [
         * 链表删除元素6 y3 M0 V% E4 a7 o4 C  ]
         *" G0 h" C, k  S$ Y: v* I" A
         * @param index 删除的位置4 \$ o: `" l% u3 V# C
         * @return 被删除的节点
    2 J% B3 z+ i8 \8 O" S     */
    8 V, u5 P5 f8 o( `  W0 R3 T0 c    public Node remove(int index) {1 R$ I6 w1 y  l
            if (index < 0 || index > size) {6 V6 a; r, [" z
                throw new IndexOutOfBoundsException("超出链表节点范围");
    7 U: X6 x& Q! G5 [7 n; }0 u        }
      U3 Q# G7 G& P# ~' O        Node removeNode;+ |5 F2 ^& o  Q/ |8 I
            if (index == 0) {
    % l. Q& _' h3 V            if (size == 0) {2 p4 j" y' K7 _3 m7 u2 h) C
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");/ j6 `9 ~8 Q+ H  y
                }
    - n* A0 D  e) a' H7 O% }' }            //删除头节点
    6 Q2 h* U2 }  _% j1 d3 \8 {% ^. P            removeNode = head;
    7 X+ u$ l" V- N% l8 \; F, W            head = head.next;
    " q: O' j6 w( i$ K9 {        } else if (index == size - 1) {- T# Q7 `# f$ A: E" e
                //删除尾节点9 e6 P1 c/ _" L# X1 g' a. ]
                Node preNode = get(index - 1);% h5 ~2 J# a  R1 b  Q7 l
                removeNode = preNode.next;. B, p7 d$ J' |% n9 i; f
                preNode.next = null;
    ; T! Y2 i1 T; i, A            last = preNode;
    / h( h. W' g+ f1 ], f$ {* T/ `        } else {& `9 R2 M5 W# n& [7 c8 T% s
                //删除中间节点9 v0 J' ]6 S) c" [7 c
                Node prevNode = get(index - 1);
    + x' O# v5 ?) [. E4 e% z; Y            removeNode = prevNode.next;# j2 u7 g* E3 X" s: N% J, ?; B
                prevNode.next = prevNode.next.next;
    " n  W% J. e* H- O        }
    4 R* l. k, Q/ |5 X& |9 h+ `. Q$ e        size--;. U* Y0 F+ c+ ?) Y; c
            return removeNode;
    2 A) r9 I( }8 h  E2 v    }0 H5 a" Y2 R2 e7 C
    Java实现链表的完整代码package chapter2.part2;8 }; S! Q6 \- L0 c2 \3 t* H

      k' d2 F9 Z4 @" d1 ^/**
    ( ?4 f0 s) n( K4 g7 R * Created by IntelliJ IDEA.1 w9 n# e6 H( v
    *
    ' Z: s  V. B  E5 @7 I- v * @Author: 张志浩  Zhang Zhihao
    / z4 l2 n3 H# b2 O2 N) v) M * @Email: 3382885270@qq.com
      X9 L2 d/ r6 a! z$ t6 [, J * @Date: 2020/5/3
    8 V/ E+ w! x3 x  g * @Time: 13:39/ c# \4 R' K, p6 _0 l& Z
    * @Version: 1.0
    + U4 f) v% |, m% @ */6 I$ W" c+ R9 m1 J& j1 \) A5 P
    public class MyLinkedList2 {: T/ W$ I3 ?9 s" H6 P
        private Node head; //头节点
    % J1 z! q0 H$ y) t( k0 H    private Node last; //尾节点
    ) C( t3 u- b. N4 O1 m3 N    private int size; //链表实际长度% Q7 ]  ~. |2 S+ y1 r

    : B* t# E. {3 \* p% B. j1 L7 }    public static void main(String[] args) {. ]* V8 w* d+ I9 o( c& m0 ?$ u
            MyLinkedList2 myLinkedList = new MyLinkedList2();' f7 S3 @0 ?9 v
    //        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作0 T) u4 q) O0 d, Q% Y
    //        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
    ; u. l* I" M# M6 W6 g        myLinkedList.insert(0, 3);( C1 T$ d: f7 R. C. Q
            myLinkedList.insert(1, 7);
      Q9 V( U6 N4 j  p) w3 Z' g0 L        myLinkedList.insert(2, 9);5 g. A6 S2 V, ^9 o& Q
            myLinkedList.insert(3, 5);/ |, P4 u- {* n- ~6 a9 R
            myLinkedList.insert(1, 6);3 u( S8 Y4 G/ ~* ^6 k/ s8 _& @) y! E
            myLinkedList.remove(0);( m# U7 }7 Z5 p# \
            myLinkedList.set(0, 23);* k0 S$ {/ _! b! Y- ^! B6 |$ g, H5 ?
            myLinkedList.output();2 Y$ F) j. l4 @
        }
    % s: f. z# u" @* r
    ' ?8 S) N1 d4 q! G, g8 A0 o    /**
    5 g5 C. h. S) D9 j1 |+ t     * 链表插入元素5 \/ R3 U8 Q0 s4 q
         *
      Q. y& Z, U, [     * @param index 插入位置
    1 |7 P8 p* c/ O     * @param data  插入元素 被插入的链表节点的数据& B- w  K- Z7 J" X* h
         */
    . U, Z- E0 y/ m8 K* f7 `, z  t' z    public void insert(int index, int data) {
    : z: p" V7 {+ M( f, U$ a; R        if (index < 0 || index > size) {$ l( _% c) ~8 b
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    & p+ p! |  x1 c( I: T- W1 `        }0 p9 L6 `) k2 r
            Node insertedNode = new Node(data);
    ( v: X* t% r. T9 J  W- m        if (size == 0) {- q) }7 |  d/ A/ `
                //空链表
    4 W" ]  a! p! ?+ R            head = insertedNode;$ P* c# F2 e6 r" r7 k8 S
                last = insertedNode;
    + q8 C' G# C' @# s) I        } else if (index == 0) {
    ! C! h9 A8 i5 r            //插入头部# A1 p& r& y7 y$ e0 R
                insertedNode.next = head;
    * _+ z. s/ M$ U& B            head = insertedNode;: p; P% G; E4 D( S4 i
            } else if (size == index) {
    - A  G! W: x$ i* e            //插入尾部
    ; A0 R7 T4 K1 ]+ }7 D0 r" l/ o- d, P( N            last.next = insertedNode;
    - e  Y8 c6 _/ ]/ N9 N8 m9 Y            last = insertedNode;
      `8 `7 G; Y, Q' }! `" @        } else {
    / S8 W# C0 h# {1 s            //插入中间" l0 X) d- q! k! J5 [0 ?5 q
                Node prvNode = get(index - 1);) U; r' E( L' H4 H& r) Z' o
                insertedNode.next = prvNode.next;
    ) O  N+ F3 a  ^1 {: w$ W; ]& _; j; a            prvNode.next = insertedNode;
    / z% V% F* d6 H        }5 ?/ O9 u& p' o- e
            size++;
    : Y6 `( h% Y" p7 s7 W    }- _) e) c2 v8 b4 ^

    / C7 n" X& Y* O* w$ c    /**. {/ ?8 l0 r9 S  _0 h
         * 链表删除元素
    - }" s+ f* ^& u7 v  E! ~% K, z% l     *
    - }+ X1 A8 l* S- h  x( e     * @param index 删除的位置
    . \. [1 g) F  d# U2 U     * @return 被删除的节点
    ' N% K' C  m6 M1 s: k2 s5 {8 r     */
    2 y. Y) c* d/ i0 ?4 n    public Node remove(int index) {: |! w1 {/ m- y3 B
            if (index < 0 || index > size) {0 ~9 G& j7 [6 M9 f. f# I
                throw new IndexOutOfBoundsException("超出链表节点范围");, \& b7 Q3 O" N7 r1 q
            }( ?4 F  R; i! t6 u. v4 q
            Node removeNode;
    3 v; p. ]% ?9 S  h        if (index == 0) {
    + I- |. F2 i2 Q0 `) M2 h+ C            if (size == 0) {1 K5 S! z$ u" c' k  L/ }5 p
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");9 p3 g6 {, G3 c, y. x  a
                }
    2 O* c- e5 D1 M& ?1 s/ c            //删除头节点  F$ q1 ]( t/ k% K) i) ?
                removeNode = head;, y) P% R9 J2 k2 {5 P/ e) P
                head = head.next;
    * h! o" o& V% k        } else if (index == size - 1) {7 ?( ?( j: r. G6 ]
                //删除尾节点
    * z8 \7 `+ K  U- E0 t( g) Y( S            Node preNode = get(index - 1);
    . Z0 Y) Q% [" a0 _            removeNode = preNode.next;
    0 f9 t7 ^& w' ]# C1 E. X% s3 l3 W            preNode.next = null;0 k. ^2 ]; b4 W5 q  `& F
                last = preNode;) O# h- ?7 S1 h" d0 s# y+ C
            } else {8 L2 w3 n5 e) ~4 L$ S
                //删除中间节点2 Q; ?* x; c) @# c5 {
                Node prevNode = get(index - 1);6 i) L; p: c8 ?! H6 k& d9 S1 V9 k
                removeNode = prevNode.next;
    ! f1 n6 @9 F% q8 E- Q' ~5 s            prevNode.next = prevNode.next.next;
    4 i* I' M# H$ H6 N4 d6 }! X# B        }
    0 w; P- Q2 }" I8 k- {        size--;$ V3 ~( \8 t" W. V5 `  F
            return removeNode;. R  G% l6 g4 e# G: l1 q0 S
        }% f) u8 `% d3 a/ a, z
    3 B( `4 ], c' }3 t' x
        /**
    2 I* g, u0 F" s) F* F/ I6 W     * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    # t5 B8 d5 |9 U1 Y9 c     *
    , G% p2 i& w% Y  R     * @param index 需要更新的节点的位置
    9 M& k! {0 q# h+ g     * @param data  新data: Q- I  A  Q4 H
         * @return 旧data8 Y2 O4 j. L8 Z# S6 M
         */. O, }+ Z" ]3 S+ ]
        public int set(int index, int data) {
      e" f# a4 }* @# N! z        Node x = get(index);; e( b0 U6 \  a5 C& C
            int oldVal = x.data;8 g3 m6 S# b+ j! h9 b4 g$ P+ }
            x.data = data;+ t( v0 d7 _+ ^9 U, {
            return oldVal;6 x3 l, T8 ?& A2 {
        }7 c7 B/ u+ {8 l' h4 G" g. q! ?  w

    9 H9 }% F: V+ \; n2 n    /**. U3 j  X$ P2 u7 Z3 B1 N
         * 链表查找元素" I! s+ F0 x- j) Q9 J8 K
         *; b7 f, Q% J$ C0 G4 Z
         * @param index 查找的位置. y7 w1 I! B  ^, q. i7 m
         * @return index位置的Node对象
    1 ~2 b9 n0 u5 Q5 _# ]2 D1 A* h     */
    6 Q, _1 d* O8 w) R0 m8 D    public Node get(int index) {3 [5 q! u( j  \' S, q9 I0 k0 m
            if (index < 0 || index > size) {
    ( O7 s- J6 ]/ N/ m' E- u            throw new IndexOutOfBoundsException("超出链表的节点的范围!");! O' Q5 E2 v( f- }) y+ j
            }
    : G; T( m( t5 E% B/ X4 r        Node temp = head;7 ]' J% w7 \! [3 L
            for (int i = 0; i < index; i++) {
    ( h6 d( `: U# T" i3 Y            temp = temp.next;
    2 U# C# M" j- c5 _        }. ^5 g# r+ k, e2 d0 ~8 B3 m
            return temp;
    ( Y3 A# I" f) o    }
    9 ~7 q/ L* G" P0 I- w" J: D+ ^5 E% }/ J( R0 L1 o, I
        /**  X1 ^  ~! J) _5 g
         * 输出链表1 `: x4 ^) q4 j$ y: d/ T! ^) ?
         */
    2 ~: U/ R$ I6 l9 |0 b    public void output() {
    0 }8 _3 A6 t5 Q+ H) x& v2 o9 ~1 |        Node temp = head;
    ' M9 u. ~$ y. |* N2 G        while (temp != null) {
    . N: b: H: O. ^; Z) N            System.out.print(temp.data + " ");' w8 l6 Q1 k+ g5 U4 P8 g3 k
                temp = temp.next;1 X# y+ m( J8 D' s
            }+ B. s$ X; Y# L8 g7 Y: K* A
        }
    ( l' Z0 o% N3 e+ m  j
    # d4 k4 U# _5 B" ]1 T    /**
    6 U5 B) L7 K# e     * 链表节点/ j% R8 M! u  Z# j5 B
         */
    ; B2 W* n. `+ \7 U3 o    class Node {( {8 J, k9 c" y) Z4 G2 U
            int data;: \4 Y" U8 F" U  K) M# y% ?
            Node next;
      n' V$ T( d; l; A! t, l6 @( I2 {7 N
    & x. q. i* p/ F" l        Node(int data) {% T8 Z; c% U8 s$ w) ]
                this.data = data;, w5 Z/ K: b) G- s: z4 n8 B
            }5 _) m) f9 j  t4 _# C
        }+ T( ]# D- T: r% [3 }0 |. i& ]' E0 @
    }8 b9 n8 o1 U9 B5 @0 |' b$ c
    # ^$ M1 h1 q  m- A" Q

    : E1 r, g: |! A# g* Y3 |二、双向链表 12.png
    # A: x$ m& Z2 S, ~6 X双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。. `5 M4 T& i% @; S" o4 }0 y

    : p/ b% N3 V9 C0 ?2 Z8 Y- Z" s5 U8 _( X5 I" t! R

    - w. M$ m$ W: p6 b
    ) ?2 p$ ]" l9 e6 A! N1 @. L————————————————: H, e; U: `/ g, u
    版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    $ u$ X  L) {6 B3 p* m& t原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468
    $ q0 N  G% T  |' x7 @# M) d& H" I6 T
    - O2 d/ e( p3 `5 t' U  T, ]

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

    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-8-1 03:29 , Processed in 0.623310 second(s), 59 queries .

    回顶部