QQ登录

只需要一步,快速开始

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

      @) N9 o7 B3 E% ^【Java演示】什么是链表?数据结构
    + J: u7 C  a5 T7 ?一、单向链表4 S+ y! w. e, }; P5 M+ C& X
    3 a$ ]- Y6 O" E$ O6 c
    1.png % q1 R  P7 U: b- ]
    链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。1 e! p' Q- |% \) [# Z" v' {
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。! I1 {) X8 m6 M' @4 ~; e$ T: K
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。
    ; W" h. f& a2 X& Q2 w- D
      N) y' |4 h# _  G# J) a什么叫随机存储呢?, K& I: |' b+ w' {0 u+ i  K

    $ c) c3 B8 J: d) j$ |* U如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。; _& ?+ Y  r- }7 a# ?6 ]+ d
    上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。5 l% X0 l# |0 J. u+ k: b
    3.png
    1 O8 L, J/ x; W
    ' S' g& T! p0 U8 G8 N% v

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

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

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

    4.png
    ' Y0 `$ F4 ]& a) _& N7 X( l5 a  W3 H" f, x8 X
    /**
    6 ~, ~. n3 \. F* L* N     * 链表查找元素, m& d" X' p( u# d! |1 i7 K
         *
    5 Q6 b0 b& U+ w9 [( p, H     * @param index 查找的位置
    2 L* N9 E$ [  u( W' n     * @return index位置的Node对象1 S  k" U( b. w- x  l8 Q+ Y
         */8 u" O4 H4 ^/ t4 I+ u
        public Node get(int index) {8 o! D$ ^/ b, Z& z9 J% E4 c* {/ _
            if (index < 0 || index > size) {
    5 ^7 Z. b2 q$ M+ z4 z. c            throw new IndexOutOfBoundsException("超出链表的节点的范围!");# K' g1 U# @2 q
            }, l: ]) p1 L9 Q. a5 R3 }% ]) J
            Node temp = head;
    6 ?+ T- f9 ?: g7 R        for (int i = 0; i < index; i++) {
    & R+ n0 ^# I6 F8 \: }            temp = temp.next;( {0 J3 @! D& p3 N5 `5 D
            }8 d* q' O* U" N: c
            return temp;
    ; ?6 U) x3 X; J) t    }
    4 p' R0 S3 s* V% n% R' V; O3 H! E7 d& H

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

    2. 更新节点 5.png - e% ]/ \% ?3 [8 @
    5 O* `; C9 U' N0 Z" b9 ^9 g
    如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    ! j) w2 s! H1 o7 K0 u( S# Q' M如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)4 h- Z0 j4 j  A7 K' v8 k3 K$ b8 D
    /**
    , w# W! ~# ^$ {& \* f+ U     * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    6 l$ w5 ^5 o% f: L1 V     *3 C, i3 {6 \/ w! M* ?
         * @param index 需要更新的节点的位置! O& K" G' f9 X5 _% d) G: b
         * @param data  新data
      k% z" ^6 O; V. k1 B# X6 ?     * @return 旧data
    7 A4 u: N/ F: l2 l$ z: |     */
    4 i& f1 G* S2 c" S/ j9 F4 |    public int set(int index, int data) {
    * S% F6 \3 Z$ a4 c3 G; O* `+ }. y        Node x = get(index);
    " L/ F5 [+ R0 m: A2 F/ }  f        int oldVal = x.data;# y& `7 i' m7 J3 Y5 o
            x.data = data;
    ! V: f; _5 }3 g) s/ X        return oldVal;1 o9 a8 W7 U) z
        }
    0 w! B6 q& `( _( S4 O! W- S- R  e- @  r! r/ N, G
    3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入% K$ D8 b, v% S+ d0 n/ s( ]0 ]1 V7 E. x
    3.1. 尾部插入

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

    - `. L; }1 B3 w! \% D
    6.png
    4 x) F3 ?6 f' V! w8 O6 W- i3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。
      7 U$ ]1 t% L' l  y( N" m. G4 t
    7.png 9 F; b. W9 p5 L
      ^. ]& A  ?/ \$ \0 n
    3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。' i$ o. x/ ]' g8 ~+ |8 z/ K
    8.png ; [: X2 i7 }! `9 C, v) E) E/ z: o

    ( C4 a' t: i1 q$ A8 J8 f三钟情况的代码合到一起  G* Y0 {7 N  J1 e# g2 e" u6 W

    0 I  n' C, M9 o. }/ U3 K+ }/ ?! g/**( r6 ]+ T2 m# H5 x+ i
         * 链表插入元素
    ( J1 Z+ i, v$ t8 W+ u6 k( P     *
    % U. Y* U: h) i! ~) [6 k; E     * @param index 插入位置) U1 ~0 m4 w! W4 _2 r" \) `; o
         * @param data  插入元素 被插入的链表节点的数据
    / G. V9 z" S: g* m0 U     */
    * D7 \( n7 P( r    public void insert(int index, int data) {
    2 |7 k& O& k/ T+ y, B1 A        if (index < 0 || index > size) {4 C( P- V" E  Q4 K3 }% N
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    2 [1 U, }" Z& Y% T" w% O        }0 j* I& \. D( L0 T1 g
            Node insertedNode = new Node(data);
    ' S# }: }# Q2 y" A# |& C        if (size == 0) {
    9 O) ?) @/ @) ^2 q5 a! L4 l" {            //空链表
    ) d* a' @. q. e( R            head = insertedNode;5 s% g7 Y: a) D' y0 H
                last = insertedNode;( \* X# `+ F. E( z9 q: c. K
            } else if (index == 0) {
      B4 h3 `% B* C" F, G) r            //插入头部
    9 m' v+ x+ n; n0 g+ X6 v1 ?/ ~( M- D6 L            insertedNode.next = head;% Y8 M5 o) S" Z# j) V
                head = insertedNode;. z/ j1 i" Z$ _5 P! a6 y
            } else if (size == index) {
    ) I9 s5 _$ _8 S3 X1 m            //插入尾部" T$ Z% {* t; }
                last.next = insertedNode;/ c3 s- f. z2 \" M3 P5 ?3 t
                last = insertedNode;
    5 f( q0 ~4 O6 S        } else {
    + e* Q, Y' b- {# l9 j, K) |) O            //插入中间4 q8 m9 I: ^' Z* r. V7 b
                Node prvNode = get(index - 1);8 h+ s4 D' H8 I+ L
                insertedNode.next = prvNode.next;7 Z% n; S! m! o- v2 h* S1 ?4 q
                prvNode.next = insertedNode;
    & z* X; L" t! h* ?+ O3 Z: v        }# s! L& f. V: {# Y0 f  H5 H) v
            size++;
    $ C5 M5 p# `' i# j  N    }
    % t& j; y6 c/ R; C3 |
    & ^; {( o4 s- o9 j2 l/**: P8 n5 X  f/ Z0 D7 F
         * 链表插入元素
    , l; b% X$ q  t0 i6 G1 m- J* t8 P     *1 e$ C: ]7 C, ]9 v9 X. s. w2 @
         * @param index 插入位置
    ! \% h7 P& f8 V! I2 F0 E; O     * @param data  插入元素 被插入的链表节点的数据
    ; l" {: u0 b& D     */% [' D8 `! M- c# M( _
        public void insert(int index, int data) {' t7 l4 h& J( w" Y; G7 N, h8 c
            if (index < 0 || index > size) {" \, N% Y2 I+ S+ n: ?
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    " a" ^0 h* f8 F& Z# i( J        }
    ; i2 n9 _" y$ q        Node insertedNode = new Node(data);
    + |& k: R/ D; o/ u" R        if (size == 0) {
    . t; O5 X( g# W- D; K% \% M" c            //空链表
    ( n" ?" I+ e5 d3 m            head = insertedNode;
    ) D0 o. ]$ _% k. N# L! r7 C            last = insertedNode;
    : z: s0 U6 N2 J& R8 `1 `' k        } else if (index == 0) {: @# z3 y& F& }  A9 p+ {' v
                //插入头部
    6 r6 E+ D3 ^( y! _* _- Q  b% w8 f* M            insertedNode.next = head;
    0 C' t2 J( C0 x: f; f            head = insertedNode;
    6 M# Z- `  o4 ?# G5 v" D        } else if (size == index) {% Y! R7 a9 t& Z' d
                //插入尾部
    ! g. g9 R+ b" e            last.next = insertedNode;+ @$ J% D* z# r- ^% X, o: W. g
                last = insertedNode;& @; H' u4 e7 e
            } else {
    4 D8 o8 F1 P5 ]1 E2 a& Y            //插入中间
    / l; {0 ]$ V3 w8 U1 b            Node prvNode = get(index - 1);5 q: f  r/ ~3 {- {# z5 y9 M
                insertedNode.next = prvNode.next;
      I, Y3 \4 K5 i# l, L7 l) V            prvNode.next = insertedNode;& L3 M- s6 j$ x/ W) {7 w
            }$ R+ q# s- p3 i# h5 m
            size++;0 X+ ]/ R8 F# E7 ~' b
        }
    " A$ K' G7 s- z1 O7 t4 c) e4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除
      # b. g& Z! C  s! ]! e
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即
    0 W4 V. W0 e8 l; @( |8 @" f: a可。

    9.png
      Y8 K! H- Q7 p2 c- I' j& V& ^' G' _4 T+ Y* _7 t9 c
    4.1. 头部删除

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

    10.png 9 L3 p" B& ^6 v1 W1 }) {
    4 k5 Z! e: T: R! |4 x) [
    4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要% e" z0 i5 K2 d8 t7 T- v
    删除元素的下一个节点即可。

    11.png
    0 F5 f5 B7 ~, p0 p" _2 a# X; @; Z3 R3 s! w) \/ E1 r

    - d0 M$ K1 x0 m% c& K) K这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。% \* a! I8 e. t' B
    如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)
    3 E" o8 z: G) `2 n/**
    3 H( W! y1 B4 L0 U     * 链表删除元素: M' i( _" ^: b" w) [% D9 C, L
         *
    7 ?6 s) X- E* n" D3 p) W     * @param index 删除的位置& A+ C- H" n6 o8 c
         * @return 被删除的节点
    & {9 X1 W9 L$ M     */( N# `0 j" }1 g6 M
        public Node remove(int index) {
    1 N* S9 o1 m$ T$ b/ S. J        if (index < 0 || index > size) {
    ; k# Z% v( \+ l, e+ i; |8 n            throw new IndexOutOfBoundsException("超出链表节点范围");# {& d; m' \" ]
            }- ~. }( F- ?) g& v" ?# J: I6 y
            Node removeNode;
    " M& t6 j5 k+ I) K8 {  j0 N        if (index == 0) {; }4 s  a: O- b( `! d- s
                if (size == 0) {; r7 x% u: T5 n
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");
    * ^6 ?' r! ^; S* I) q4 S            }. |) r, q* S8 v* Q
                //删除头节点
    8 C, j: O7 `" m' T6 B            removeNode = head;2 K, ?! {4 w$ u
                head = head.next;
    + z! k* k: L4 z: `7 C1 V9 ~        } else if (index == size - 1) {8 A2 }9 Q  [) e2 H
                //删除尾节点0 v$ o" ~8 \: |; N  f+ E
                Node preNode = get(index - 1);. @; B2 ^5 h# O- i7 ~' M. B
                removeNode = preNode.next;3 A. n6 |* L# a9 @; C- \
                preNode.next = null;
    * |! d) {+ X  G7 o" O/ C            last = preNode;4 i8 `' P2 g3 l5 C9 g) i1 [. R4 b
            } else {
    2 X. t( M0 d7 d1 [0 j            //删除中间节点5 G/ O2 x1 F1 v4 e* C$ l
                Node prevNode = get(index - 1);
    2 x8 w; Q1 f2 {+ @            removeNode = prevNode.next;8 @* {1 `5 y" A8 U3 |* A
                prevNode.next = prevNode.next.next;4 X5 I( D0 D- `) t) E) W  o
            }
    ( n: |8 A3 ]8 l! x( A+ r        size--;
    , c& _* o5 b; p( ~1 ?* Q* `9 S        return removeNode;* i' U: W  N( |
        }
    % M' ]* A0 r! b+ M4 W* a$ yJava实现链表的完整代码package chapter2.part2;
    3 q  E1 Y( M% T* Y0 o4 V  e5 {& P- e$ G! Y2 N/ b* g4 h, O
    /**. K6 y0 h8 R4 J- I3 P% _
    * Created by IntelliJ IDEA./ I2 L# Z  }" \1 U5 U
    *
    . J  U+ G( ~3 `8 `. l * @Author: 张志浩  Zhang Zhihao
    - Z3 P( b% g, q- g: U; W$ E  N# T- G * @Email: 3382885270@qq.com2 g4 A" k4 x$ V
    * @Date: 2020/5/3
    / g! _3 U2 p& U- n* u+ K * @Time: 13:39
    & U6 ]4 T' z4 _% K * @Version: 1.0
    : ^/ v! g) H" v5 P3 W/ k: }0 ^0 ]. V1 } */4 \6 h0 U2 P  X% H
    public class MyLinkedList2 {
    : A5 b3 a' E5 a$ W    private Node head; //头节点
    6 M0 p$ ^) g7 M. L    private Node last; //尾节点
    1 N1 [% U- D9 J# o    private int size; //链表实际长度7 I6 G! X4 W2 J' i  h; @

    , F, B- m6 b6 `% l- O, H: ^0 x    public static void main(String[] args) {
    0 j, Z9 k7 w7 U0 V2 r# t        MyLinkedList2 myLinkedList = new MyLinkedList2();& p5 o( H/ v( D/ d, s- f
    //        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    ; j% `4 J0 s# {( t3 B! j# \//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
    + n" l, w! }0 z+ ?$ v- D8 A5 W        myLinkedList.insert(0, 3);
    9 U9 u% t5 E+ N9 g& j# `! a/ b9 q# m        myLinkedList.insert(1, 7);
    $ k) J6 |) E4 j! P2 y        myLinkedList.insert(2, 9);2 w% U) Q( b6 v
            myLinkedList.insert(3, 5);
    $ q; c6 X+ m% R7 [" P3 u+ V1 U" t        myLinkedList.insert(1, 6);
    5 t, w0 }7 w9 x& Y0 G. N        myLinkedList.remove(0);$ [( A+ @3 V1 L) F1 ~! n8 p
            myLinkedList.set(0, 23);
    9 K5 c" F2 Y3 A; W$ R2 w- p        myLinkedList.output();
    4 Z9 B% |2 S% e6 Y$ i8 G    }; p( g0 [! {3 @% n0 N

    - \4 o$ U8 G. D6 j5 I    /**; a/ z: ]8 V( I3 m& D/ l  V
         * 链表插入元素
    . D4 F, I  `6 D     *
    6 \5 l6 m% W. m* _( `3 o" A     * @param index 插入位置$ H; i! [7 b; g% F/ n' D
         * @param data  插入元素 被插入的链表节点的数据
    3 M4 S' R& B* E& y     */
      ^4 ~# T; d: C- T0 s- V    public void insert(int index, int data) {
    3 M1 j0 e% p  R/ n2 U. X5 w$ A/ U        if (index < 0 || index > size) {3 l4 \) q, t8 d
                throw new IndexOutOfBoundsException("超出链表节点范围!");4 D- {& X" U% h* g# F
            }
    / t* C" [* D* Z: A. b        Node insertedNode = new Node(data);: C. r! {, b2 C3 P; D3 H
            if (size == 0) {0 a0 b; a: X4 X3 I* P. s
                //空链表* _& G) B0 E0 L2 H5 ]
                head = insertedNode;* |/ M2 d4 q; d  G" Y8 v
                last = insertedNode;4 b! _4 r9 k5 u2 U; E
            } else if (index == 0) {
    0 E& k5 g9 G6 |            //插入头部
    , \( \2 g% M; e$ U# ]            insertedNode.next = head;) b" \0 f. A; a/ f/ M' n/ z- R
                head = insertedNode;
    + X3 w( b. b9 {& E9 {        } else if (size == index) {
    $ C( f3 M/ I1 A( b4 q, r/ B, P            //插入尾部, z; B. p1 \) Z+ C  j: w
                last.next = insertedNode;
    " a) H) j. \1 g2 H            last = insertedNode;7 y( s" q  Z% D6 I6 C
            } else {
    . v0 w, U- v; Z) ~* F5 g& x            //插入中间; `5 Q0 h( @0 h/ Q
                Node prvNode = get(index - 1);
    - t# d. A, A& {, n/ Q! i+ _            insertedNode.next = prvNode.next;; |! g  E0 h# b
                prvNode.next = insertedNode;9 B+ V" m" t! [+ d' P
            }( u) _4 @) @+ R! b( }
            size++;
    $ c! C; l9 F: m6 E    }% D8 y4 G2 I5 z$ z' L

    & B* ]- B2 ]' ~7 V) [* L1 m1 V* W    /**+ \7 ~& e/ ]( e% G- ]
         * 链表删除元素
    & K8 C8 O) s/ E' G1 M2 @     *
    - U4 ~8 z2 q8 M! ]2 J) J     * @param index 删除的位置
    # o, ~% B% G2 S, Y0 {$ q( {- ~     * @return 被删除的节点! {4 K8 T9 O: q4 f
         */
    + X' K8 ~( Q( u, j( {5 q" j    public Node remove(int index) {: q: q8 S  c& _- L6 j& n
            if (index < 0 || index > size) {8 M+ ]9 {( l1 i( ]6 ?& L2 J
                throw new IndexOutOfBoundsException("超出链表节点范围");, Q; K% r+ C& D  }' z5 p$ ^8 u
            }
    % H! c- y4 ~) \8 k* O! s        Node removeNode;* p& ?5 `1 U3 Y& a
            if (index == 0) {
    5 J  x# v' x: R4 s0 S$ |            if (size == 0) {
    + {  ^) K# b+ p& N6 S- ~2 k                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    6 a( ~' N( a, }9 Z) Z9 ~            }
    9 n4 i. _5 N7 A; ^3 p) O            //删除头节点
    ! L+ q9 l# R' b% A            removeNode = head;/ c; b, H0 F, l" I& X
                head = head.next;& Q$ @8 ~0 d, y- F9 }) O1 M
            } else if (index == size - 1) {
    5 q5 W  c6 g. d% Q            //删除尾节点6 B' g/ V8 U9 a4 q3 L$ {) |
                Node preNode = get(index - 1);, E7 p5 y9 c" c; C# Q1 M3 i* m' O: }
                removeNode = preNode.next;9 \) T3 R; Z- _2 {
                preNode.next = null;
    - X, A+ N  n( g( E3 E6 W# B            last = preNode;2 {6 H1 }+ o, S/ Q' ?% z! ^
            } else {
    : B  E1 o- n' B( m            //删除中间节点) K7 R& i6 {9 ]8 Q2 u
                Node prevNode = get(index - 1);
    5 ?/ K# F: B# h8 Z* |; k7 |! z  G/ m8 q            removeNode = prevNode.next;. ^. Z- ]$ ^7 u, w5 j+ J
                prevNode.next = prevNode.next.next;. w0 y; i8 d0 |
            }
    $ f& b) H. m  W) T- N2 C' {        size--;4 T# _5 W4 R6 F  t, s2 n
            return removeNode;
    : l% m/ @8 p! l    }
    ( S! \/ K* n; J3 D- Y( s' x
    $ i* g/ @0 J+ T) U0 p7 Y7 _    /**
    % O. H6 k- q/ y7 A$ d     * 更新节点 将列表中指定位置的节点的data替换为指定的data。( W$ H! g+ M. ^+ K- n
         *
    $ M3 o+ l6 B5 z5 N     * @param index 需要更新的节点的位置
    / Z9 d6 w( G9 P" F" y     * @param data  新data/ Q: ?& O6 V+ @2 @! G5 e" D2 I  i
         * @return 旧data0 q8 ^4 S# b$ X8 X% |5 N  O
         */
    ! v& ^0 h% A1 `$ P$ E0 `    public int set(int index, int data) {# a9 v5 j/ M. E$ t8 h2 U6 f7 T
            Node x = get(index);; u8 N% `. r7 L$ X
            int oldVal = x.data;7 p6 m( T4 b2 A/ \
            x.data = data;
    ' B3 k9 B& |( b  ?        return oldVal;6 t8 \9 `: v' _9 Z) J/ o9 N
        }
    / \  d3 o& a3 H2 W9 M6 N
    2 R, u" i$ P4 M4 f! W; y9 i1 p    /**
    & P" z" {" L4 \* H" Y3 r. X     * 链表查找元素- x7 s1 Z- D4 N3 u+ g2 ~6 F6 q
         *
    " G8 A9 @' @5 x, z% J! N  `     * @param index 查找的位置, _: L2 ]% B2 M  ?; T
         * @return index位置的Node对象) z2 [6 m: S; p& h, o* J
         */
    ) N6 a; d. C0 h! g    public Node get(int index) {; i! d+ y0 X$ e5 V& X  ]" R
            if (index < 0 || index > size) {
    8 d2 U) F( x# b+ O6 D& d  B            throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    + _5 `7 H. V  j) ?) p3 c* K        }( ]% q# I7 K7 s$ j1 i/ W# o
            Node temp = head;
    . O7 M) n) A+ j: a) M2 d3 \        for (int i = 0; i < index; i++) {$ G* Z. @) B2 g! V' D
                temp = temp.next;, T* }) e; _0 }9 d
            }- ^# Z7 ?9 s. i) l
            return temp;
    & u8 \( ?/ Y7 s4 S* X    }5 [& U" i) M4 e. v1 Z

    $ O; V% g* ^2 {0 o3 Q! v    /**; c- Y; M. U% v9 _
         * 输出链表# N' r( k: x( Z1 X8 M; X
         */' W8 f, d2 i, j: ~
        public void output() {
    7 X3 O' D5 I# `- r+ W4 x        Node temp = head;
    1 F/ g8 N" B  S9 o        while (temp != null) {$ @/ d8 x+ g+ q/ o# F* i4 V
                System.out.print(temp.data + " ");2 R7 @) h/ E. J! n/ N  b
                temp = temp.next;1 j( Q' }3 `' r
            }
    # Y3 P* z1 r% w* _+ I1 F# A+ c7 D9 ]9 Z    }- J% D/ |! y2 P  G8 L0 ]( _" c

    + o8 p0 N. p  V) a6 o- l    /**
    , [% {$ Q# n( P- P! P( X3 O     * 链表节点
    " g4 X  l6 `  r     */+ ]$ \5 o  L4 l; Q6 {
        class Node {
    , I" g% I+ t0 p& ?* |, ^        int data;
    ; s. g+ j2 }- i/ V( W; ~        Node next;
    3 O! Y  f- t' S! |& C) g2 c" _& Z, Y+ x8 v
            Node(int data) {
    % J5 n; v* ^$ Y; w$ U            this.data = data;4 K& }0 W! x+ S+ ?) \
            }
    0 l+ W9 X) Z5 A+ j    }
    2 O7 u0 ]! J, X0 g8 Q9 y' N}
    . t$ A) \7 u0 U3 a, e+ s
    % w( a4 j: |5 ?! L$ l1 I6 O( R- f
    二、双向链表 12.png
    ! s- _# `% y. O双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。
    ( H& {" u1 w+ E- k& L5 e$ z, w" Y& F8 s, n

    6 W: u; u( `8 `: S; ^0 w5 y/ L) ?4 E% U
      h) h' A8 D; t* I. S8 k  F( y
    ————————————————
    ! y7 r6 ?' y3 t5 l1 A5 \; n版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    3 ^$ B% z; s2 T1 b9 T: n" J原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468& K: v# }# K$ ^0 Z7 Z0 n5 m
    5 ]3 t/ n* r* H+ p: s3 h+ m& C- C3 {

    - t5 W7 ~+ f% N

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

    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-1-8 18:18 , Processed in 0.427673 second(s), 53 queries .

    回顶部