QQ登录

只需要一步,快速开始

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

    % x  n0 [2 L  |1 D# M- }* ?【Java演示】什么是链表?数据结构
    6 F/ l: {% f7 _8 F, g/ N一、单向链表
    8 X# N  B) `0 @3 o* O$ t) D! l
    & `  N  p* ~! L% z8 o9 b 1.png ' \1 W; Q4 _9 c5 {
    链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。
    + q1 T( X2 B; ?3 X' W" h) t单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。: R4 }2 b" P+ K6 ]2 R! N, v# m
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。- y" u  ]/ c8 y6 f2 d4 l7 p5 ?
    $ G5 Z+ j$ A, X6 h
    什么叫随机存储呢?
    ; X: i! S6 B" r+ F6 J
    # \8 ]% z  F3 t5 C8 `7 P如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。" ?. _' e2 y7 ~7 s5 Q" I
    上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    ) L8 S! k. b) T7 }3 R, W+ N 3.png $ d2 W. T2 L, E4 H
    + I4 l% W8 M& u, N6 [

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

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

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

    4.png
    + n' b3 ?% d8 X  B, _, B4 P7 U1 _; ^- Z3 l% t& t) ~
    /**
    9 S7 {) a& k" o) k- @' G     * 链表查找元素6 A3 N! ^7 d( x( i6 w$ t( [: t6 F
         *
      K5 o( _* j8 {6 D6 v6 I% T     * @param index 查找的位置- K, ]! H2 u9 C8 e8 o" d
         * @return index位置的Node对象
    7 t. w: `$ _9 R0 F6 B1 f* |! `! Q     */
    ( e$ r- w& C2 q. p    public Node get(int index) {2 `% N# B0 x4 H0 E' g& Q* e
            if (index < 0 || index > size) {( j) t% {. j8 P7 t, \
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");
      k; E& `# ~3 \9 ]3 a: y. m        }7 ]/ \: ?6 F7 J! Q- t" {
            Node temp = head;& A4 n* h: j) m( Q
            for (int i = 0; i < index; i++) {
    4 z5 T' \: M2 B, J" E) A            temp = temp.next;
    5 W# |- r4 ]7 i1 y! \" ~5 j2 i        }. D6 f. H; R+ [% T, ]
            return temp;
    % J# @( `1 k" M% V& \' h    }
    ' Y+ d3 ~9 L7 z1 L2 V; T
    " h7 l4 v% p% H0 G# U

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

    2. 更新节点 5.png + Y3 p9 I% \  U( R) A

    + k& F; B; G( M/ o% X如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    . C- ]$ |% F# z& T  v如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1), d- u$ ~, a, q5 V4 `% U2 q0 C
    /**$ }# M' c% d6 S/ a" ]# r  b
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。  D. Q; l9 n& t% q: D, Q
         *2 W) [" G0 {+ j8 [) t) S7 s1 A
         * @param index 需要更新的节点的位置9 Z+ |( A) T1 n7 B& g. M2 @/ z" a
         * @param data  新data% f* w# w5 Z5 e* C+ w, ^7 g6 [) r
         * @return 旧data
    # n" R% ]" ~& T' q3 A8 i7 v3 G     */
    8 W3 W% p" I: {( g5 b1 |  Y( b    public int set(int index, int data) {$ H& E1 F; Z/ O/ Q$ ^1 i
            Node x = get(index);7 @0 {, D% L3 j" Y1 L7 N0 y
            int oldVal = x.data;
    ; R& X/ s, d4 Y" X3 t        x.data = data;4 o" G, X0 s: V/ m6 O- E
            return oldVal;& s/ y6 F* i8 `/ L. p" T
        }- R+ [# k, {! j, `" t

    ' k2 T7 [" I! w- G- S5 B3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入1 O; S2 L  \6 y, E  d
    3.1. 尾部插入

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


    ; e: y/ j( b: ?% [, W8 s& u. }& Q 6.png ) R6 Q6 m! D( X# d  N7 Z, {
    3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。
      2 g* \/ J3 Y; ^: p
    7.png & B6 I# v1 J) N- z# Z

    ; ^; {' h5 U2 h3 f3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。
      8 Q2 Q( r8 h# W* {1 I. L1 F
    8.png
    ' {# m* k- a, F2 X# H2 H7 Y3 F1 z( I8 X: @1 ?; `- ]. j% W2 h
    三钟情况的代码合到一起
    . E  D" k7 H# H2 t) m1 b
    1 T* A8 o( x& R- U/ i* [( J! ?: ^/**( Y/ X4 L. p, I/ j
         * 链表插入元素
    . ~& `. O+ c' b# {& w  s& C     *; F( Y3 z8 H# S4 b* ^1 E" p
         * @param index 插入位置
    & r7 V+ _4 Y# L% K3 S     * @param data  插入元素 被插入的链表节点的数据+ W1 u0 c$ N2 i
         */+ u9 v; [8 Y3 g* U" o" ?
        public void insert(int index, int data) {
    ' [; J1 B1 l; a* s. n! Z7 b        if (index < 0 || index > size) {- s/ M8 `" R( i
                throw new IndexOutOfBoundsException("超出链表节点范围!");
      Z& k+ x8 E" A9 C8 A( T        }! `, I0 G. c% h( Q( Z, F! `
            Node insertedNode = new Node(data);
    ) y% O) ]* l7 W3 `' @0 j        if (size == 0) {
    8 D& s; p3 e; ]8 a4 m1 ]            //空链表5 I& o' Y/ x3 Q: M- H9 Z
                head = insertedNode;2 X" K6 ^3 _+ F/ o
                last = insertedNode;' @- x* m% ~6 @/ G( D( \
            } else if (index == 0) {  j2 s: I8 f$ h  a" `$ |+ B
                //插入头部2 ~$ b* a# f* T8 l6 M9 M% ^
                insertedNode.next = head;
    ) x+ K. r3 R* t8 I            head = insertedNode;# p6 _* m6 |, t. \2 l: d
            } else if (size == index) {
    " g4 @: a$ P, `& j) Y/ F            //插入尾部
    2 B1 i2 e1 k8 Q/ u& W            last.next = insertedNode;
      Y9 O3 i8 o1 t. v            last = insertedNode;$ g# W2 {; Z! N( P7 c* T
            } else {+ `: P5 n: [& W; \6 p' i) G
                //插入中间- m9 m/ d+ J/ W$ ~0 k: M
                Node prvNode = get(index - 1);& {. Q7 L! O, U* Q
                insertedNode.next = prvNode.next;! b% p- h- K4 s8 \) E: y' _
                prvNode.next = insertedNode;
    3 v8 F# n& p1 h- {& k- K        }+ L! w. K) B" ]( o8 j2 V
            size++;! _: H" Q: I. I4 V6 `
        }+ Y+ |# W+ r. y/ }/ i
    # r. k0 {# K3 F0 [  w2 U& {
    /**, B9 _1 I+ {3 F5 r% d& c$ T2 M" H
         * 链表插入元素
    % C. y. [8 V; r. W( S" x9 _     *& i$ B! l. I. g+ i
         * @param index 插入位置- ~9 W" W& v) R; {; N' V
         * @param data  插入元素 被插入的链表节点的数据
    " S6 ]  s3 |& R% r     */
    4 v' G/ u- ^, C  ?. J    public void insert(int index, int data) {
    & p. ], B! ~3 x/ \& ~        if (index < 0 || index > size) {7 d+ r/ @( U" _6 r
                throw new IndexOutOfBoundsException("超出链表节点范围!");5 r' n0 M$ K6 L; W! `
            }( D8 W3 n( i" m( Q% @/ w+ M
            Node insertedNode = new Node(data);
    , F& w/ w5 b6 }: N8 `% G) F2 C+ |& n        if (size == 0) {
    $ g# i6 _; f( M4 o            //空链表
    ; S0 @7 C* [5 L8 Y. S            head = insertedNode;" @( a: O& h1 V( t4 g, l
                last = insertedNode;0 H1 ^$ L& T$ A( @
            } else if (index == 0) {( O0 J# W- C6 r0 ^  B
                //插入头部  b- o6 S8 n5 D$ L% d3 X3 i/ d2 g
                insertedNode.next = head;
    " L& N# t: y0 }4 a6 |" }/ T            head = insertedNode;
    1 C3 R- R. E. ?; _4 B        } else if (size == index) {0 g# N: d' g( f5 O6 K1 m+ Q5 y+ E
                //插入尾部' u$ u/ y, j4 w- g
                last.next = insertedNode;8 X! v& {. E! _+ s
                last = insertedNode;- {, X0 I8 R, U: }# ?7 ]: S6 M% M! _
            } else {# \' H8 \: I% a! k* s7 h2 x2 I
                //插入中间
    - n0 V7 G1 m; b. @0 a* ]4 a; C9 B8 l$ m            Node prvNode = get(index - 1);. `+ E. Y# x- n$ J" i
                insertedNode.next = prvNode.next;$ L  B/ G. o3 u0 N# i  w' `! \
                prvNode.next = insertedNode;. |3 s! d: u2 Y1 G
            }
    0 d" P# e# l  T  u        size++;
    / h2 x( v2 j0 V2 Z6 ], W    }
    3 U6 m0 G3 @# i7 Z4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除
      ) m; I$ Y" b; h4 R7 n% Z7 \
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即& |, a; j- M$ }$ x! X
    可。

    9.png
    . ~8 [) ^- I: a7 E
    8 H% @, W' {" z& E- C) _" {0 d4.1. 头部删除

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

    10.png 9 W# g" z! {  D! r; l& j4 c& o
    4 a/ e- F+ P7 }! @: ]2 J* \% v
    4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要+ I9 k9 R( \# }6 I
    删除元素的下一个节点即可。

    11.png
    * a/ F$ w" ~/ ]- w1 K# G/ c; E* p- ^9 o; H( l* s+ i4 \! Q1 S: y" L( E

    / S: T  {  Y3 q" Z$ C& b, M! q这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
    & C" D0 h& E0 i" z! h2 x如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)
    8 y$ _* O- A, g+ H; S/**( {( h3 E  W' ^( V- l
         * 链表删除元素
    + P) P9 Z) ~0 _4 M8 x9 N- @" V     *3 F9 E$ _, b. \, x6 p
         * @param index 删除的位置# c. T  {8 H3 w) f% @% ]: w" G
         * @return 被删除的节点7 T3 A  Q# d* s9 \& ]" I. d
         */
    $ A1 X0 N, G" q7 h    public Node remove(int index) {
    8 v! r5 H* r. ~; o  H  `        if (index < 0 || index > size) {# m; I  J# V1 A5 u  \+ S
                throw new IndexOutOfBoundsException("超出链表节点范围");
    9 ~1 B7 U5 K8 S  s        }
    ' ~; ~  g" Y4 l/ v# ]$ }        Node removeNode;- V4 V( Z# b3 O8 Z2 p4 ~/ Z+ O
            if (index == 0) {3 x$ {4 E2 r: a# H9 \8 J
                if (size == 0) {  T$ s1 [. T7 h+ J5 t4 m
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");
    1 V! T0 m9 W( q6 l) m$ w            }
    : Y$ k$ V( i; ^1 ^; i/ e4 {% Q            //删除头节点
    ( v# y: d/ S: e# w- y& Y7 |            removeNode = head;
    1 U  y2 C8 e4 F2 D: X2 y% r            head = head.next;$ d8 ]' V, s' f5 m$ V
            } else if (index == size - 1) {* w, M4 h- t' a6 {8 Z. U
                //删除尾节点
    " ]8 O  ~& E8 j) p4 f            Node preNode = get(index - 1);7 \* [& V# [/ b) o! ]* u. k0 C
                removeNode = preNode.next;
    : y* P. }4 |5 ]            preNode.next = null;
    0 I: N  w* _5 ~$ [            last = preNode;
      q  u6 f+ }7 q: g6 K% f        } else {/ w/ t/ _' l; \: S& u  a
                //删除中间节点! k6 x8 v8 }5 F/ v+ T# C/ X
                Node prevNode = get(index - 1);5 d8 P6 t2 b' H% i" z$ U
                removeNode = prevNode.next;: v6 H$ W4 \8 _* r# K
                prevNode.next = prevNode.next.next;
    : u" k) a. j* c  c, a8 h8 @$ c        }( d% e: A/ _5 @* T8 [; E
            size--;
    5 R: P, _  w+ p1 _% w1 d0 Q: `        return removeNode;' [/ m5 O  M; x- J
        }
    * d" [5 c* {; ~4 D9 ]9 X- @  s1 [Java实现链表的完整代码package chapter2.part2;
    ! l/ k& j# U- U( `2 r
    6 r- J$ P1 ]  g1 M+ J2 G' n/ l2 P- ~/**
    # v) c! D! g4 p/ A * Created by IntelliJ IDEA.4 P3 `! u1 Z+ D: D1 s' e
    *
    , y, }0 m  W7 _ * @Author: 张志浩  Zhang Zhihao
    6 \( j- v0 M6 z  r. r1 D3 n6 a0 m * @Email: 3382885270@qq.com
    , Y( L6 P4 b$ e4 o7 f4 S * @Date: 2020/5/3
    / _& Y  h4 S, j! N * @Time: 13:39$ S( _% E2 ~& Y) T" }
    * @Version: 1.04 I! i1 y  n% {2 V: P7 {
    */$ e* O% {) P+ b7 i4 J% b9 p
    public class MyLinkedList2 {
    3 {0 x* C4 S3 e, w0 ~5 q, i    private Node head; //头节点
    9 @$ D0 n7 {3 J. o  V  [    private Node last; //尾节点0 K, y: Z( A0 @3 \& s
        private int size; //链表实际长度9 W  ^# D- S$ I6 V, S

    3 m& E' Z+ l5 l" Q9 W    public static void main(String[] args) {
    * O: \0 C$ U4 S4 L+ C7 Y        MyLinkedList2 myLinkedList = new MyLinkedList2();
      J: d. W0 ?% w7 w! R//        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作5 U2 o/ i! K4 ]8 M- Y/ Y3 T
    //        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
    ) d" K2 L8 i6 o6 o        myLinkedList.insert(0, 3);: x! k  z( V1 L
            myLinkedList.insert(1, 7);
    3 Z7 Z7 h0 Z1 O$ s0 D% \8 x1 Q, L        myLinkedList.insert(2, 9);% A: {" X& p" |! ^/ L* j
            myLinkedList.insert(3, 5);
    . w0 H; K4 W& E# [. c3 j% z        myLinkedList.insert(1, 6);/ B; @% E2 e; f* l
            myLinkedList.remove(0);' X! r3 k' ?6 B! I3 W1 l' t7 S
            myLinkedList.set(0, 23);) |; E* J) B* z8 u5 H
            myLinkedList.output();
    ! V( ~! L) R5 g2 j' x5 h2 y$ _    }
    * D( f" y! d0 S  F: f9 _8 N
    2 \, b0 }  ]) p1 ?    /**
    4 D+ X# X9 h4 ], v* N     * 链表插入元素1 Y5 ~5 A# i4 f2 W% z+ s
         *& z, z" H" n' b, D3 V
         * @param index 插入位置( c- q7 \2 {5 Z% T% H* X
         * @param data  插入元素 被插入的链表节点的数据1 N4 ?; l3 p/ d0 g  q
         */6 `  J  T1 H* H' t! T# K
        public void insert(int index, int data) {
    + [' T$ P2 R5 l! s" q; ^' C3 [        if (index < 0 || index > size) {5 \0 h. S7 u5 B! c; B
                throw new IndexOutOfBoundsException("超出链表节点范围!");- U  g0 G* \/ J, l9 }
            }+ b9 T3 y* X4 X7 u+ C5 @" g1 @+ J
            Node insertedNode = new Node(data);! y# S4 [' N0 O1 N0 W* i# c
            if (size == 0) {! H9 F& P/ n9 d
                //空链表
    9 f4 w- Z& |, Z1 b! C% K            head = insertedNode;( R0 ]& D+ S2 r% ^+ t
                last = insertedNode;
    . O8 o% k9 O0 i0 {* |. O, R        } else if (index == 0) {
    2 b5 ]$ @" q" E4 Y# `, m  T9 ^) q            //插入头部
    # D3 U! w$ J% G4 u            insertedNode.next = head;* y7 A& C3 {! G7 D1 L' m
                head = insertedNode;) b. U# y+ v" x
            } else if (size == index) {
    5 o* G, V: s2 i8 Y4 E5 T( q. l' B0 `            //插入尾部/ j1 w  d: @- Z! {  R5 _
                last.next = insertedNode;
    9 T6 ~( I2 `' ]  I7 A" I' ]            last = insertedNode;
    ' ~: Q" \, u8 l6 w+ x        } else {
    " D' q, Z: F1 O  x5 q9 s% G            //插入中间
    1 j) v0 B( n# O' Z            Node prvNode = get(index - 1);
    3 W# F% Q8 C: r, K8 F& }5 N! K+ i            insertedNode.next = prvNode.next;# \" x% G7 w4 s" ?% Y. h
                prvNode.next = insertedNode;
    + }5 ^4 e: ?$ i# ?: I. d( o        }4 N6 b1 s; M/ C: u
            size++;
    3 [" m, w- r  r: U0 W- e3 L    }2 s! r' d6 C) s* }8 C  q) [
    ( e7 ?! I  C# l: N
        /**" U& o0 o) \* E' a7 E
         * 链表删除元素9 w* B0 c0 ^1 U$ n3 ~
         */ G+ m: W. |  b! f6 Z
         * @param index 删除的位置5 d3 b, n2 o# M/ H5 G
         * @return 被删除的节点
    2 k( p! K  S; j) L     */4 |% z- _& m# ^* m4 d/ h. N
        public Node remove(int index) {+ u4 i# B% G6 M4 r" S
            if (index < 0 || index > size) {
    ( M5 ]2 R5 T- p/ Q' {2 t            throw new IndexOutOfBoundsException("超出链表节点范围");  s) ]" B4 e2 C3 s; z. t- Y
            }
    3 S; O  I- j2 ^- F: }        Node removeNode;
    % Q+ l/ n# I  ~* r        if (index == 0) {7 j- N: v: F% y; j( ]* z
                if (size == 0) {' y  c1 z/ j# x5 f0 K7 n
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");& H& @4 l3 D7 ^9 ], q
                }
    , D& U7 m- Z) {  l: r) i0 [. e            //删除头节点6 c- B8 j# Z9 f2 @) ]2 \
                removeNode = head;& t: u7 o8 E3 r$ E( s: x2 k
                head = head.next;( Q, U8 |* {/ t( C) F
            } else if (index == size - 1) {- R$ Q" o8 @. d" ]/ \
                //删除尾节点
    7 b- K- V; Q: u& O4 P6 K) U            Node preNode = get(index - 1);
    # g  h- i& `& \3 F6 i) c% @            removeNode = preNode.next;
    6 m0 z4 F/ N, J2 j4 B# z1 E! m; o9 K            preNode.next = null;5 t7 x. H- C) m0 Q9 x/ @
                last = preNode;% ?& F: O! l- g% `0 T
            } else {1 i, g$ @9 |. l6 P, o) W
                //删除中间节点
    / n' }8 P( r% h# ?2 ?* e            Node prevNode = get(index - 1);: i& g* L2 ~  t3 P
                removeNode = prevNode.next;
    2 h8 u4 V6 w2 @. T+ ]            prevNode.next = prevNode.next.next;
    1 }$ F: {  k9 M! F8 ?4 l, r        }
    % W0 F* M  w0 O7 n5 n- i# U4 ?2 K        size--;: q+ W9 V$ C% z
            return removeNode;! w) E2 E: W% N
        }
    $ {8 O) Q8 ]2 s; M. u
    + m: J1 R& f' T* D  g4 J' l    /**
    " \% t0 B% U5 t6 B( U     * 更新节点 将列表中指定位置的节点的data替换为指定的data。9 z: ~9 \# H; C" W6 T, D
         *
    9 N2 t8 E2 j! y# ]9 J0 \     * @param index 需要更新的节点的位置
    ' D8 d. N0 b2 |/ Y     * @param data  新data/ o+ Z! A( m9 L
         * @return 旧data8 I! `  M, X$ u2 y$ W0 t
         */0 |9 l7 {2 K' [. l
        public int set(int index, int data) {
      |; D0 z5 U9 x# Z9 D! U        Node x = get(index);
    1 o4 R! S9 J8 M6 X  K% Y        int oldVal = x.data;
    ' B; Z. D7 C8 T0 z+ b* d        x.data = data;
    / w' w5 V/ k7 y        return oldVal;6 n6 y8 I- ?. i+ {
        }2 F0 |2 i- E5 R, a3 j
    : f" B- a; I! {4 q8 I3 e6 x' ?
        /**. w) _+ K8 a: N# W
         * 链表查找元素9 x8 f% `" i6 M
         *
    # s6 D7 h3 o+ [2 v3 m     * @param index 查找的位置
      P9 K8 O: \1 `6 T2 O4 r! V     * @return index位置的Node对象6 n: u9 O- M  N4 M, f( [+ Z
         */
    & c9 g: @$ c/ A    public Node get(int index) {9 n. A: p. H  O! ~
            if (index < 0 || index > size) {
    4 |- h8 e; Z0 q; w: u  ^" ]2 s            throw new IndexOutOfBoundsException("超出链表的节点的范围!");3 T/ ?; v. j0 D
            }
    7 X5 ~4 u/ R' \7 n( s: [: a& ~        Node temp = head;* O% A; V. f" U) S
            for (int i = 0; i < index; i++) {/ ^5 B: S, u5 s' e
                temp = temp.next;4 M+ @9 u7 S3 Y5 W
            }
      ]6 w& p6 Y! k  G# k        return temp;
    ( P1 @- n" H0 a! I& v    }
    $ y0 d- O4 |. m0 Q2 o  Y
    / b# ~$ ~, k4 e2 b4 D; q    /**
    5 b" X2 L* q# B5 w! B     * 输出链表, W( ?! ]6 `" s+ D1 n
         */
    $ G  Y! n$ T2 r6 a  ]    public void output() {
    # e( t/ c6 {3 f/ A. M. |        Node temp = head;9 j3 \$ n% o. u( f
            while (temp != null) {! f' \( w% w9 D9 V3 ]
                System.out.print(temp.data + " ");
    8 y# K' t5 @% r            temp = temp.next;
    1 c/ q/ h3 R6 T' O  u. d  [$ s# G+ ^        }" e. l4 Y3 K( n' @
        }8 L- x( P  a5 A

    6 |, C3 a7 y  _+ L! \0 p    /**
    9 t& t/ L" z3 e) n  m5 L" X3 E; o     * 链表节点
    / g1 [1 r( x2 O/ I7 ^2 d8 F     */
    ; S, [9 i$ [# ~$ k    class Node {
    , M- w1 J  n+ ~% s        int data;3 {) I, t& b9 j! m) P3 v
            Node next;# d3 _1 i% V' T/ B4 F2 x* g& A4 v

    & Y6 L# S9 w$ P3 y( k+ A        Node(int data) {
    & x3 e) E' u5 X. c$ k            this.data = data;
    ! t+ Q( F2 T. V- n        }" Q: ^  `* b, v# d4 h
        }
    / D7 w& ]' R$ Q# y' c9 s3 K( E}
    ! }5 Z( H! b5 w5 j! N8 v: `% Q1 k. E' V# D1 C8 M% f5 C2 [
    5 g$ t6 a: Y2 V6 _' h5 W) \
    二、双向链表 12.png
    4 s* H' Q6 K/ I双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。
    ) u/ Z% t' U* \+ N  f. S8 m- I" H
    $ ^4 J0 S! x0 u9 q9 R
    ; c( L, t3 e. M) C; N) W) w

    6 I: S5 i4 ^5 ~- p. A————————————————
    ) B7 f8 n2 L' D! c! p/ p版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。) g. P5 c0 W) |% C
    原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468
    + Z) A! x/ v) F- b0 e& K! m" {$ ~  l

    8 T0 d2 I1 Y: T

    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 20:46 , Processed in 0.559784 second(s), 54 queries .

    回顶部