QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5253|回复: 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 i5 H; A5 h: ]8 V: m7 g【Java演示】什么是链表?数据结构, F; H/ p9 D: n" Q: t
    一、单向链表( T1 W; F8 A9 ~  M, M$ O1 V( U% q$ o1 Z
    : z: f+ ]% P% |+ O! v5 i1 a0 v* D
    1.png
    + S( f3 b  B3 @9 `2 H$ |链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。6 {6 [( I* l8 l6 w
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。7 r% U" z; ?( I
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。2 b/ X* \0 T5 B: _, X; @1 {7 D/ @

      Q- V/ m" }' Y# }0 R: G  Q什么叫随机存储呢?+ |7 g$ S; x. \1 B# u

    7 {' g5 s. |2 O( s0 K/ T2 l如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
    : ?9 V% C+ j4 t+ M" x% j0 M上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。  c' @, t- C) U, I( u
    3.png 2 _% e* y4 J) H/ h1 r

    4 q5 c2 g+ H. Z" v- ^+ D

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

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

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

    4.png % |/ H& ?9 s4 a! s6 d, V1 K
    ( y/ y4 C3 g( T/ m9 {: x& I3 `
    /**- c/ g, K+ q' ]8 j. s( c( i9 k3 U
         * 链表查找元素2 j' t0 [) y5 \+ u9 o
         *7 m' z- z+ h* e8 c& R8 |9 t3 [
         * @param index 查找的位置
    ) Q) y* @  p% Z     * @return index位置的Node对象$ ^$ I6 j/ H  W
         */$ U$ j$ i; Y0 Q' D
        public Node get(int index) {9 s5 X6 P6 V1 ^, t3 H, `! N( d, w" S
            if (index < 0 || index > size) {- n9 o( V% A4 |: E) t. U/ y: x% T& D
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    ; Z# x2 @0 K6 p3 W        }! O+ K" c/ O( t& {# X
            Node temp = head;+ K& r, d4 d% ~+ G& {
            for (int i = 0; i < index; i++) {
    0 B2 i5 k+ x6 ~$ o2 P            temp = temp.next;) t8 Z$ e; B6 I4 _' d" c
            }2 x  N5 C$ N2 c1 A% C$ n) ~
            return temp;2 H* v. v- }! r. m  D
        }7 C$ Z# }% U! h7 j; _0 G, `

    1 {: {: V7 O% [* C8 f

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

    2. 更新节点 5.png
    ; s" @5 H! A# t* Q7 ]0 h
    9 R6 l  X8 d6 Y( q9 t! @如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    4 s" i/ U+ _* N/ |' c* P2 q* p如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)
    7 n7 c" ?& @" ?4 e/**
      M8 I! o3 O" e  q1 r0 K* X+ t# Q: P     * 更新节点 将列表中指定位置的节点的data替换为指定的data。7 \# D: }" V: S( c. s7 ~
         *7 i6 B% l$ s$ p/ f* |: b6 h
         * @param index 需要更新的节点的位置" h: \% i1 |2 z0 ^
         * @param data  新data
    $ A4 {. |8 o$ g2 g5 k( @     * @return 旧data6 ~8 }( ?& D. v& W
         */7 V, e$ {6 N) A6 w! I
        public int set(int index, int data) {
    6 D6 d9 i0 J, o- L        Node x = get(index);
    6 r( ~5 B: ]2 W        int oldVal = x.data;
    / Y7 b6 u9 G% `- M        x.data = data;" F& o; s- x$ t; Y
            return oldVal;
    " f5 B0 P: G; @! L    }
    3 n6 f, p, b3 A, Y2 c' l
      @0 ^$ P8 y8 Z! K# |8 W/ n3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入3 v0 y" m, f" l! r6 i6 J
    3.1. 尾部插入

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

    + q( x/ g/ I3 L' ~
    6.png
    + n# w" {' F  w2 Z7 f4 ~7 J3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。+ x1 ^# h+ d: T0 D+ `
    7.png
    1 S( Z/ D$ G; E- y  n# |5 {& K) T
    % w! Z( l+ W. [. M% H# g0 U$ p8 W: H3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。" L& z- p2 A# s) d+ F& x5 i) X/ b
    8.png 0 F4 b- G% D3 m; x: A& Y2 v
    $ C0 Y& |) u6 e. x, r" n+ I
    三钟情况的代码合到一起
    * S* c5 N2 {9 X& j. \/ \6 Z* Z& s, F6 W/ Q" Y
    /**
    ! e7 ]1 e7 f; f4 f     * 链表插入元素
    ! x) w+ r+ y4 S5 N- L3 f+ {     *
    0 ?9 h) u) }2 ^9 T! A, m, C     * @param index 插入位置
    ; s/ F3 q  s, i- K' W! G( J     * @param data  插入元素 被插入的链表节点的数据$ s2 J* L# C/ }
         */; m* d' j1 O& T6 ?
        public void insert(int index, int data) {, V8 w2 W; K* H5 I- c/ I9 _
            if (index < 0 || index > size) {
    ( S9 B( R- @+ P            throw new IndexOutOfBoundsException("超出链表节点范围!");
    ! H8 O" ?1 w8 J: E  s$ u3 l        }
    # z; \: ?! a4 u7 M' b        Node insertedNode = new Node(data);7 m8 d: u3 s+ M& j
            if (size == 0) {; m/ E0 E7 D: k9 m$ }
                //空链表3 B' U3 `( [  H" z0 y  d: G: @: a4 B
                head = insertedNode;5 V$ B* v6 {8 [# T6 t4 n  G
                last = insertedNode;
    * f& w. v& @8 R3 Z$ i  @. p% H6 l        } else if (index == 0) {2 n" h1 T* ]* I) ?1 @
                //插入头部
    " `/ F5 S! w1 V) H' }            insertedNode.next = head;
    0 L+ `/ f6 ~! K! f* y  a1 w            head = insertedNode;
    - D9 B# w  f5 m& C) j        } else if (size == index) {! A' b" y. l2 G* J2 c8 E
                //插入尾部
    - T. R* V( @( W4 q+ V2 I( Z            last.next = insertedNode;. g+ I6 `3 q3 `/ t$ A' O
                last = insertedNode;2 F( Z2 p' @: T2 z" z9 }9 R& v
            } else {/ B$ z' x5 Y, j# n  _8 |) H
                //插入中间2 g4 E8 \1 u( g! U
                Node prvNode = get(index - 1);  C- Z1 ]0 h/ F& ^- s' I
                insertedNode.next = prvNode.next;) c$ y. o) }* M( H- y! {4 m
                prvNode.next = insertedNode;8 X( a( G3 H9 }- X- ~+ r  Q' }& i
            }
    + I) D8 E/ ?, P7 @' |        size++;
    - |7 A8 w4 r2 h2 g" h+ b    }1 S, }5 x+ M( @; c( t6 F( _* N
    0 u0 j/ T1 i5 w* X, Y6 S' j
    /**/ `- r  T3 e4 {( n/ d9 z, @
         * 链表插入元素; B2 \1 ^7 z; y5 D. T/ a# P  s
         *4 r3 F2 ?6 ~1 [$ d' F$ F1 {
         * @param index 插入位置
    9 \1 z5 s  ]: o     * @param data  插入元素 被插入的链表节点的数据4 k* X% g( `, J0 w2 W
         */& M0 w3 d2 f  S; s
        public void insert(int index, int data) {) }" n6 B/ E5 X
            if (index < 0 || index > size) {
    ( W% L4 z4 V3 P            throw new IndexOutOfBoundsException("超出链表节点范围!");3 C8 n8 g: _$ V! ^7 s( i
            }
    * B5 A& l: b! {$ U' E1 d$ F5 K3 j) u        Node insertedNode = new Node(data);
    " A! C* H% H! c% m        if (size == 0) {7 Q& |$ B8 c2 m* A
                //空链表
    7 G4 x' ^) L9 z; c* O            head = insertedNode;! k$ c( _; j2 b1 ?
                last = insertedNode;
    ) A0 I8 w* n! q. W        } else if (index == 0) {
    7 Q. K9 O1 _& x5 G9 U5 R) K0 ]            //插入头部
    : U, m1 C2 n' x5 d$ F            insertedNode.next = head;2 f4 o6 x2 J  x* A, d& ]# J
                head = insertedNode;) l, m4 ]1 C5 \7 e( K& r
            } else if (size == index) {
    . l) y2 K) I$ M" K- G; b; k            //插入尾部
    ) y  B& p" \! a- o# ]) F( Q            last.next = insertedNode;
    " ^  W6 \' n* m% B* D- {& S  k            last = insertedNode;: \0 Q, j' k) O
            } else {7 x1 |8 a: R: \' X4 x
                //插入中间
    0 }; B% o4 D; b# S# k5 F1 n3 d- d            Node prvNode = get(index - 1);
    2 ]! s& m# B9 M4 D$ h            insertedNode.next = prvNode.next;
    . W& a+ J# P; v1 H8 ~  p7 ~* {4 r            prvNode.next = insertedNode;1 ]% j8 p0 {/ a$ [6 b
            }, G  k+ s# C6 ]3 m
            size++;( f9 p4 r, H( q9 K0 `
        }( d: {2 a1 J9 j. h. ^6 D, p* F
    4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除
      : w8 R- s" A1 j8 M$ b2 l
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即
    2 P4 ?( I" f4 K* ^& Q可。

    9.png $ [1 P) p: l+ Z3 f' h

    : E( h! q0 Z& _* M6 R7 X  n9 D4.1. 头部删除

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

    10.png
    5 B! ?3 C9 ^$ t( G- S* e
    ( I1 W- A. ]0 t3 h" E4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要
    ' G+ V& [5 @7 q0 n8 ^$ V删除元素的下一个节点即可。

    11.png / J$ e/ F8 M; g1 u* J
    3 R. D% p" S" z1 |- l- G1 _
    ( t6 u* {; q! p* \# I8 P
    这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。+ A2 e6 v& M# p2 e" ?7 j0 v
    如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)% w( K/ [* X9 [$ n" x
    /**/ S3 k' h! Y9 V. v* C, u: Q- x; w3 O
         * 链表删除元素2 E  P& y# q0 F
         ** x" A  T+ q: N' _3 W
         * @param index 删除的位置
    # o2 a' T- x: q! e- M9 M% i, ]/ D     * @return 被删除的节点
    6 V- W& O# v' Y) P3 M     */
    7 Z+ N% l) q8 Q8 C$ k    public Node remove(int index) {8 V- Y2 ^% R& @4 T" p
            if (index < 0 || index > size) {
    " L) Y  e- D# F. F( y% Z            throw new IndexOutOfBoundsException("超出链表节点范围");
    + z% K2 B6 ~6 e. h3 l        }
    - h4 `( y6 e; v        Node removeNode;# g! p: X$ `/ e" m7 z
            if (index == 0) {
    9 |! M- Z8 o0 u4 B" ^2 x: g            if (size == 0) {
    1 V$ a6 w( W) P" {' w/ k- _                throw new NullPointerException("当前链表为空,不可以进行删除操作");6 X: k. r/ j8 M) ?" ^
                }4 I7 L0 @3 o  l! \
                //删除头节点2 F+ `- g5 W8 n* ]) F
                removeNode = head;
    ( m# S/ o# I; I, t2 v            head = head.next;! M1 w( f+ J! R; D& W
            } else if (index == size - 1) {' \2 L' z; U) d: S9 @
                //删除尾节点
      O8 H! y( h# U' V3 z% a0 v% L            Node preNode = get(index - 1);
    + ]% I7 C2 g, m7 Y% f            removeNode = preNode.next;& `- v" p9 |' V0 O* \9 d
                preNode.next = null;4 j8 \2 G. ^2 `
                last = preNode;
    9 R9 z- U+ s0 W% r        } else {
    0 m! k9 Q1 p  q1 {% Z4 Z+ s: P$ P+ A            //删除中间节点
    ' W* R* D' y7 F: E            Node prevNode = get(index - 1);
    9 W9 e9 P; A  n& i2 H            removeNode = prevNode.next;. U2 z) P& a' r' q0 t' @* n
                prevNode.next = prevNode.next.next;
    / R: X. f0 u, U3 D" V        }
    8 w* Q: r0 Q$ T& N( [. J! l        size--;# X" [" q8 T! v2 ~
            return removeNode;
    1 j* A6 W; u0 ]" A$ S4 i$ b: N' `- v  u    }
    * R, r& P9 q0 C0 l# T4 kJava实现链表的完整代码package chapter2.part2;- D  B) b: S! `* J) |, @6 M

    8 f: t3 \. S# r& \# e% l7 J/**( }+ l3 }# S1 I: Y1 t
    * Created by IntelliJ IDEA.0 j' L+ J( V, S& W* e2 J
    *% L; c+ Y- d2 V* t" l2 J
    * @Author: 张志浩  Zhang Zhihao
    ' Z3 \& p6 e8 m1 Z: z0 B4 O2 A& @ * @Email: 3382885270@qq.com( G  _7 t7 `7 @& @, w6 T
    * @Date: 2020/5/3, Q1 ?6 z( H, @# }6 T4 G- J- t( p
    * @Time: 13:39$ \8 q6 _/ z- T  n$ M
    * @Version: 1.0% ^9 a; }, ^% l+ Q
    */
    6 @7 F6 ^- J& T  u) ]% E% v( w# \public class MyLinkedList2 {# |9 L% F4 Y! W  r
        private Node head; //头节点0 L/ ]' ~, e+ W9 k1 _: H( f
        private Node last; //尾节点
    ; R# `6 D% b$ u5 p9 m/ Y2 d4 U    private int size; //链表实际长度* t6 n0 r% S- f5 v

    , t" a# @' t$ Y. Q8 ^    public static void main(String[] args) {
    " C4 p( `  c) Z9 [& Q3 h        MyLinkedList2 myLinkedList = new MyLinkedList2();+ G: J  V+ H; t% ~+ S" I
    //        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作" Q8 y$ |7 a* s: g0 T% _0 w
    //        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围1 D; X" f( q; B$ T/ M5 i
            myLinkedList.insert(0, 3);9 W/ M$ x! C4 S: v
            myLinkedList.insert(1, 7);
    + m0 v0 L) |* X        myLinkedList.insert(2, 9);- A- ^" a& T$ X- L" [( |. k+ J
            myLinkedList.insert(3, 5);
    # d2 I' E2 ^/ P        myLinkedList.insert(1, 6);
    ) a4 e, j, b$ _4 L        myLinkedList.remove(0);
    ( F! }" B" k2 j) c. ]6 Y        myLinkedList.set(0, 23);+ Z- j" h1 a% `! [+ A6 ?7 j
            myLinkedList.output();
    : m. A- x  V  \) [, _    }
      k7 x2 V5 h+ o; c" M# F  h, j% d3 ?+ B1 `
        /**- `# J. ~1 F! [- S/ t
         * 链表插入元素- b6 e) B% Z# H) t) Q( H
         *
    2 K. j: s1 ^3 G3 F9 i9 W! _) r     * @param index 插入位置$ e2 [; r! H. t+ w
         * @param data  插入元素 被插入的链表节点的数据3 R6 X/ e9 g' X# w! [/ i  v
         */
    & c7 I2 w5 D5 t+ U    public void insert(int index, int data) {
    $ U2 @: J2 z0 ?( o        if (index < 0 || index > size) {7 s; w% d1 H3 q1 C
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    5 F: j: Z8 H! {& v' i- k* x        }
    8 t4 @$ X+ O$ g* m' l1 z1 g        Node insertedNode = new Node(data);5 N( ^. S$ F' z2 ]( h
            if (size == 0) {
    9 O/ a0 ^3 _5 V( M! U7 S            //空链表
    - s, a7 {0 b4 G  \            head = insertedNode;/ a& h' V' O1 P2 \8 h
                last = insertedNode;
    # j# Q+ l0 Q0 E# p        } else if (index == 0) {
    % I6 Y2 c! K; s; \9 E0 J( X            //插入头部6 l$ U: B# R% k; l  _
                insertedNode.next = head;
    # l) ]" x. l% a" ^$ Y9 Y! V2 D            head = insertedNode;& K% Q, \- C4 j/ a- R
            } else if (size == index) {
    ; S: r7 t$ g$ x' A: z            //插入尾部
    6 f& r0 l. `3 p1 U8 G* q            last.next = insertedNode;- P+ u  Q; m7 I/ w6 J  Z% a$ {
                last = insertedNode;: P3 v& j: l" m) D
            } else {8 |5 J# {- f* I- y/ f7 I5 t
                //插入中间5 F( a9 {$ T. W  M( g
                Node prvNode = get(index - 1);
    8 q0 Q, R5 ?+ a' |! M: T            insertedNode.next = prvNode.next;9 M3 Y2 @9 T2 ~* Y" U
                prvNode.next = insertedNode;, ~+ T3 Q3 l- D. I: J
            }: o+ C. z% K# N' B
            size++;
    ; e/ Z1 [0 |; T; ?9 |# ]    }! M  Z2 ]7 D7 O! Y5 y0 w/ }

    * d2 v# k0 P/ L/ j' M( e( `    /**8 y: H' C; s9 B5 e2 R
         * 链表删除元素% f" ^  [( C" u7 @9 M4 [
         *5 q8 X  ]# W7 q9 i: s5 n
         * @param index 删除的位置
    + I# t) v, M# d) I0 R     * @return 被删除的节点% Z, ^% f, W1 h$ j1 C0 V1 `6 W' M
         */" O) o; R4 P7 Z  }
        public Node remove(int index) {
    , }8 {2 {1 a9 o+ g        if (index < 0 || index > size) {
    " X" N2 Y& ~  |' J            throw new IndexOutOfBoundsException("超出链表节点范围");
    , ]/ ~1 B+ z# w! V5 x9 z. G        }' o; ?' n: p5 R
            Node removeNode;
    ( w& J- t0 n1 k1 R; _6 ^        if (index == 0) {
    0 N1 [4 |( c: {) n. W; T8 y            if (size == 0) {
    ( a* c/ e$ {  E' z4 L3 L# S                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    ( i/ i" ?$ y  }- ?+ D# L            }
      {, _3 q  S" c# y( s            //删除头节点/ a) _7 ]0 a/ a# b  l
                removeNode = head;
    , w1 K6 V! z* f0 M2 m6 D6 |            head = head.next;- A; D: D, H; k; U6 K
            } else if (index == size - 1) {
    6 m9 f6 v) E! t( B( E6 c            //删除尾节点" o. t6 H, Z. f5 z. y
                Node preNode = get(index - 1);' E, Q' Q1 X  z1 s0 o
                removeNode = preNode.next;
    , E% J' T+ p+ i  @: |            preNode.next = null;0 g) M3 d+ S; t. R+ Y$ x+ Z1 ]  A+ O8 n
                last = preNode;: }5 g5 J" Z$ K" u
            } else {$ _1 B5 O5 i0 s4 n! p. x
                //删除中间节点
    1 N0 F3 P4 P; G            Node prevNode = get(index - 1);, S' F* g; l- S5 [
                removeNode = prevNode.next;8 \2 I) e6 z- Z
                prevNode.next = prevNode.next.next;
    : G6 k# Y, P, H; u, l" u: ?' o2 `3 o        }7 N4 X- g5 z3 V! W7 \+ n( q8 Q1 V% T
            size--;
    5 A+ O: R4 B( d- `# M# C        return removeNode;, ]) b; H! C' n
        }
    ( M% A, S, U: A. E) ?+ a) `* n. r% c2 B# L" Y' n
        /**
    * S9 g9 q/ I% M     * 更新节点 将列表中指定位置的节点的data替换为指定的data。. l  T. j1 M! K+ o9 |# N5 G; M
         *
    % s' S! B; f% ?6 |4 R  ^$ O     * @param index 需要更新的节点的位置3 [8 d! @* J- ?; S7 @* x; O
         * @param data  新data
    1 I4 l$ ?1 x- q, D     * @return 旧data
    " B5 R) g3 \/ H5 n; h  D0 \     */0 W/ R) u* a) X
        public int set(int index, int data) {
    : \9 u" d4 D" T, I! ~        Node x = get(index);' d  }9 M- [' m5 H( k( @& {. O3 T
            int oldVal = x.data;
    $ K2 b7 K0 K8 x; h1 w5 F4 K        x.data = data;
    # c) W- I% P$ M' e; o; G/ M2 l, E2 L        return oldVal;
    ) e) ?2 `7 j6 k: x! |' ~- R    }. d7 k4 C' v& c" v
    % k) ~; }! s/ O( `+ d, \' M
        /**
    . a, w4 X. w/ m4 l. j3 Y     * 链表查找元素
    & j% L; Y) @! W  e     ** M/ f) X, K  }+ b: M8 I2 O: z
         * @param index 查找的位置: ]5 [- N& {7 `9 J- A1 ~% s
         * @return index位置的Node对象* E2 C6 B' t: Z  D3 i9 j
         */* z- ?) P( X  e3 J- h& P
        public Node get(int index) {
    + ]8 x/ `# T' r' d' E) l9 m        if (index < 0 || index > size) {
    6 Z& j% T4 w/ S0 s8 |2 M# `) r3 O7 G# K            throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    " N! A  a' \# Q' ?) g/ A! S+ G        }
    ' s5 H1 K9 c; g# U" p5 k        Node temp = head;
    % T  d2 d" Y3 P& V' F4 {        for (int i = 0; i < index; i++) {
    7 t5 k' Z0 g, h7 X# W7 A            temp = temp.next;
    - Q3 C+ R) Q  I( J        }6 e: O( c* G2 Y6 |' r( y  p
            return temp;
    7 L- z. |% _/ P( }4 I) c9 J. J4 `    }
    + R# F+ S" Q% g) ^6 }
    & H, L+ N0 k# |" P    /**
    2 z7 i# l+ F/ U, {( [     * 输出链表
    $ s/ e* u4 Q$ q! s) x" B; `2 W1 F     */' Z% Z7 r; F1 u, \" e* A
        public void output() {* S% x+ p% \! a) b( ^
            Node temp = head;3 n8 a+ a# m1 o' }4 N+ q
            while (temp != null) {
    : ^3 Q0 }' N$ r7 a8 T9 [8 W8 j: a            System.out.print(temp.data + " ");
    + Y. m+ r; `7 x. T# c6 Y# T' a            temp = temp.next;
    7 t/ b1 {1 C. w* t' M        }4 J5 I: P0 J1 B; p! Y) K
        }
    % `* e. V2 K* a% G
    ; K5 e3 U6 U+ Q" X' A1 A) l) I% G    /**
    5 U$ D) E# i, W; d/ |# `     * 链表节点
    + D, R& B" u# ?3 A  w( i     */
    4 y, B  X9 e2 {" B2 X3 B- s    class Node {, W$ E' ~' w5 ^7 ~
            int data;5 P% E8 ?, ~/ w7 W* k5 p0 ]! W: S
            Node next;6 ~; F) @+ ]. U6 I5 `+ t4 t
    7 [, L6 b6 ?% S" C; g0 ~( }
            Node(int data) {
    : }; }  o$ P% K. }            this.data = data;
    " j8 C9 \9 e# L4 n* |# g  S: g        }4 I1 ^5 s& G" F1 Q8 L# V6 N7 a
        }9 A1 S2 Z9 r8 B) D' m
    }
    ; t8 x/ g# y6 c- ^& R5 l+ O' p, R6 P2 `; @, H  k$ p0 B* L8 z
    " j: U( }& q) r) M6 D6 A
    二、双向链表 12.png & t" c; Q' f8 {+ x3 @9 N, z, k+ ]
    双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。
      D& p. n$ c# m) t7 \9 ?7 _
    + E, u0 J7 J9 y% r$ B! \6 {: h+ f9 F( d. H, c/ b

    7 V7 J+ l' `  g& {
    9 E$ F/ p! O2 f2 Y' _————————————————+ O2 e9 k- u) b6 R6 q8 j5 p* D+ |2 L3 ~
    版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    3 {) T* b# v9 a  X原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468
    % Q: f; G3 l0 `& A2 ]& \, s& j, k- o8 @: n* X% m) x
    6 k1 \, H- p, X( n5 a' Y! t! g

    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 21:01 , Processed in 0.357013 second(s), 53 queries .

    回顶部