QQ登录

只需要一步,快速开始

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

    " A* L, \6 l9 E. }, y【Java演示】什么是链表?数据结构
    # x" @9 C) U/ r  f2 O2 y* y" s$ [一、单向链表- _6 b/ _& i' {+ J

    . [8 t0 d0 \6 C 1.png * U# {& G2 r( r, u, w4 s: s8 P, z
    链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。7 K2 V: n9 K: M, m) J& g7 J$ B
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。$ G. i5 N0 b  f
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。
    6 v1 ?0 {; s4 @: [4 g- z$ d
    1 w7 g- S3 u  `6 a* d$ z什么叫随机存储呢?
    ) A" h% Z( u& m5 ^3 n: ?3 u# \* B& \* w: `
    如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
    / y' M& M9 ?7 S9 D' s( X" M上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。" k5 r; s" h: c" m1 i7 P
    3.png
    - Q/ A0 X  c7 B( \: N4 W- {
    8 B  q; J# }  L! q  G5 c

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

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

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

    4.png ; z& H+ @2 b! C$ }) x  h& w3 h$ D
    # d) ]$ z: n5 e1 G) d
    /**8 a. a% Y8 S4 l. H
         * 链表查找元素
    3 T4 T' I/ `% V: H6 y     *. D; A1 |# X2 |4 B- q; y. W' T
         * @param index 查找的位置7 G$ `  \" p4 {) `! r
         * @return index位置的Node对象
    8 o9 T1 k% c& [  H& I  N1 Z     */
    . l( \4 I: o( c    public Node get(int index) {
    2 q/ n# N% A( W7 ]        if (index < 0 || index > size) {1 [, S2 z$ T( k3 w. V5 v
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    - e+ ~4 h2 ?' M( k        }
    ; [' f0 u4 h  N- v, W2 }        Node temp = head;9 r/ N3 a0 f- {' G
            for (int i = 0; i < index; i++) {
    , p! q1 ~2 D7 ~* x3 r2 C. Z1 S7 n            temp = temp.next;
    & b" s9 }0 o  ~$ t        }2 h- q7 S7 W3 I
            return temp;
    , E& y0 n( I5 k7 H3 F1 h, e8 m0 t    }' {" i- E3 [; J& y* |, d8 u2 g
    + I/ X/ F0 I% p

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

    2. 更新节点 5.png - K2 `* F& _# X2 A9 F

    * p* k! {, M9 O: K如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
      x0 P3 P- C, i& c9 F0 h如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)
    : `, q  h4 [# g! V' p, L* w/**
    1 s% i# [2 @" Q6 M  E- A     * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    ' M% q: d/ g% I+ n2 s5 \     *
    # E+ E+ }! d& y- S     * @param index 需要更新的节点的位置$ v5 O8 W0 y- N/ `
         * @param data  新data8 n* t( r: q; q( @2 L
         * @return 旧data! B, z; U. c( M0 W2 R
         */* V6 o( O" z- F$ N
        public int set(int index, int data) {' J: @& o5 @! E4 @
            Node x = get(index);) Y! H/ [9 Q4 `6 @
            int oldVal = x.data;
    5 ~# x" d% H2 ?' k4 p        x.data = data;  @- R' V1 u6 ]4 ^  }1 _+ N- ]3 i
            return oldVal;' M  S5 \( Z( ~- B. m0 f
        }
    7 g3 v" g# S/ n. U
    9 E& u" l# s0 B$ M5 q3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入
      ( @4 T/ o. ?* r0 f( V
    3.1. 尾部插入

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


    * s" A' q% F4 R! A3 K; Q 6.png
    * \, G. C' `* p/ h5 t3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。
      2 N/ X# B* {: q3 z& Z
    7.png
    ( z1 t  Y. @+ S. b0 ^4 c
    . r9 ]0 F& Q& t% p8 E5 D% B3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。
        B5 |, c  x7 m3 I* I3 x
    8.png
    % }0 q$ c5 O* R- \% w3 S- |2 U8 j$ M7 B8 X' K2 n
    三钟情况的代码合到一起1 D) p" N' |$ Y5 T. Z
    6 D  P7 `+ Q& e! f, W$ W1 X
    /**
    4 _! ?5 W* r: c% I6 ]# A     * 链表插入元素8 h- O. g2 W8 M" M  z
         *
    0 p, W, t0 J1 ^     * @param index 插入位置- Q/ A7 t" @" T( \+ ?- G  [9 T
         * @param data  插入元素 被插入的链表节点的数据
    7 o7 t' i7 A6 {/ u/ F1 @3 f     */% r2 ^# `1 d5 U2 q; t5 @9 P9 F4 O4 G
        public void insert(int index, int data) {
    6 ^  u  g& X0 I( ~        if (index < 0 || index > size) {, W; E; Z1 n2 E# P+ p$ w% ^
                throw new IndexOutOfBoundsException("超出链表节点范围!");+ \* q- g( I' S& E" a
            }
    ) K8 m, H- `: h        Node insertedNode = new Node(data);
    0 q7 k8 y# s7 a& x        if (size == 0) {
    , q0 ^- l! }0 _3 j  @# |            //空链表7 s: l" `. i( O8 k/ t9 t3 `3 G: `
                head = insertedNode;
    # ~7 z6 u8 W: V& J            last = insertedNode;
    ; q$ \$ l& n2 `: t8 O        } else if (index == 0) {6 y% H4 ?! C# d1 ^) P
                //插入头部
    6 D4 D  |1 I$ ^5 s' p7 m1 }, h4 c6 G            insertedNode.next = head;- S+ @- |! a9 u$ O: i7 w  N! l
                head = insertedNode;  x$ R/ \) a. C& q
            } else if (size == index) {
    ' l$ D: E) r; H7 N            //插入尾部7 Z# j( |: Z7 G. Z* u. W* a
                last.next = insertedNode;& Y, l: i5 ?5 S  t
                last = insertedNode;
    7 L" g" R0 m2 |% c- u! d        } else {
    $ Y9 H$ j- X7 F9 q" c; E            //插入中间2 V4 s, d  z! ~
                Node prvNode = get(index - 1);
    ! W1 N( G& ]! o( _1 v1 l+ r            insertedNode.next = prvNode.next;
    ( j5 n' v2 U9 B) O, Q            prvNode.next = insertedNode;- C3 y; `5 J! r0 `3 B  Q3 u- @
            }
    ( Y# X4 i7 Y. [( g3 ~+ l        size++;$ A( F+ _3 Y. N3 T) _( G
        }
    $ |) ^7 x4 T. c" ]# H2 m/ {: Z1 \7 B* K' t5 L  S
    /**2 `- `) u& X. f9 u, P4 u9 N
         * 链表插入元素& N# @( @2 Y+ r% B' Y
         *
    9 q& G' x# y- s$ J' i" q     * @param index 插入位置( b" g) d$ m) P- e$ F
         * @param data  插入元素 被插入的链表节点的数据
    5 Q+ m1 y2 M$ L( c. R     */# ~9 |) V* a; I  n' p6 e
        public void insert(int index, int data) {
    ) N+ d/ x; t- I/ U8 \        if (index < 0 || index > size) {1 G! S3 Z5 e  k; L7 y; }2 Z
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    3 @) W0 ]! E. W; [0 P8 a- M        }4 G" S  R0 w. a* d6 W5 {4 p
            Node insertedNode = new Node(data);7 l  p: P0 t) F5 l4 m: `/ g
            if (size == 0) {
    . ?5 q9 v. V0 y* }            //空链表
    " b- x! V4 C6 t1 q            head = insertedNode;
    1 W' V( e. {% E3 Z7 k            last = insertedNode;
    8 Q8 ?1 F$ r6 W+ z        } else if (index == 0) {0 e/ N# a$ J$ N
                //插入头部
    : S' {* U5 b- @" z( u4 O  }            insertedNode.next = head;
    * R( z; h. m( [; X& F" G( d( L% Q            head = insertedNode;, K; [  M+ V: q
            } else if (size == index) {
    . {$ e# V! h; K" h" e2 _, e            //插入尾部
    0 b0 f) |, T: l3 |4 [# ^            last.next = insertedNode;
    : x! O$ k$ E- y- l            last = insertedNode;
    9 |4 n+ h9 g7 e( S" F. ]$ h: n        } else {
    - |. P$ ?! C: [. [. r0 Z            //插入中间
    " ?. w: [5 L6 W3 f( C" O( h/ D            Node prvNode = get(index - 1);
    : X2 a, S% }% V' i$ I7 ]/ b6 |            insertedNode.next = prvNode.next;
    ( J5 U- L& L. ?2 q            prvNode.next = insertedNode;
    1 T1 B$ n  u# U, ~        }
    ' F- |$ w6 s) h        size++;
    3 @. [: G- i) R( s$ e' c  l    }1 K% q5 w. @. C: z, ?4 }6 m% F! j
    4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除9 Y  t: R6 r# a& a
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即3 ^3 O0 z3 `7 F& i( W- Y/ A. M9 ]( ~
    可。

    9.png & w, i% V4 Q" x) i
    0 ?+ R/ W. R4 N  Y% R! A" I. I1 H
    4.1. 头部删除

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

    10.png " c- T. {8 N% F1 T9 |5 ?* ?" l% s

    4 N& E1 D. M( `. P! u0 N3 V4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要
    1 `, Z( B- l6 J1 c: r9 g1 v8 E% \' k5 @删除元素的下一个节点即可。

    11.png ) u2 {, r1 p- s  Y! \

    4 Q4 @5 a& v, Y; a& p# ]5 d& L6 D; Q6 T) r7 x; F, S
    这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
    7 L5 b$ i% L$ R5 n& T. M5 t& Z如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)& O. _# h6 m; j3 U% \
    /**: u. l9 b9 E! O& Q  j
         * 链表删除元素3 }% V# u5 A5 d4 f
         *
    2 l' B- u: s: `* ~     * @param index 删除的位置
    ' D4 ~  x8 |9 u2 R     * @return 被删除的节点
    6 h6 F8 t( d* T) X. ~2 l# _     */
    ) d4 L& q; c" I$ \    public Node remove(int index) {1 N$ `; U  F) W8 V( A* b3 u
            if (index < 0 || index > size) {* B8 U8 Y" a, {) E3 {
                throw new IndexOutOfBoundsException("超出链表节点范围");
    1 T1 }9 F5 V  V8 x; d        }- y) {) Z) w7 y4 S) r
            Node removeNode;; |# y0 g+ {9 G( D* {, g# Y4 {) _
            if (index == 0) {& y1 N3 O; _5 t! S8 s, p) S
                if (size == 0) {
    % Z) B) }" p$ Q& t# W, _                throw new NullPointerException("当前链表为空,不可以进行删除操作");5 G$ p: A3 c% M; K& C
                }2 ]6 R$ N! ^/ @; X& N9 F$ y- L6 }5 A
                //删除头节点
    + L% o' c. P  t. [            removeNode = head;
    1 q4 U8 s9 |% n, F0 C. J            head = head.next;
    * V/ G9 h" a% ?$ l& G        } else if (index == size - 1) {
    ; K9 a# b$ L, b. |7 \: U            //删除尾节点
    5 F6 n9 w  _, ^. d8 C' w9 x% _            Node preNode = get(index - 1);
      `# _$ j( @5 h7 X            removeNode = preNode.next;
    * x( G8 {' ?4 j            preNode.next = null;
    4 S) ^. @) F$ |  Q/ {            last = preNode;4 l0 n5 a" [& _7 U6 V
            } else {4 m% }5 B) t# f& a) i; X
                //删除中间节点# D# L# Z* H; Z; t0 k7 F
                Node prevNode = get(index - 1);
      j0 b# a' b( u, @6 S            removeNode = prevNode.next;1 K, m  g8 b! h
                prevNode.next = prevNode.next.next;- U, p/ Q/ A! ]7 |6 q; q
            }
    9 ?4 o1 G( w. O( u        size--;$ Y" R+ R! q' I
            return removeNode;# _* e7 ~; L7 |  J$ \
        }  D6 g% |4 S# ]: C2 U& R- R5 I
    Java实现链表的完整代码package chapter2.part2;
    0 W5 `: J; w% p0 q2 x8 `3 ]
    4 W$ L( c% E' \( B' X" ^/**) R* e; v9 ^; @7 l$ [
    * Created by IntelliJ IDEA.
    ; y' c" b9 c: k3 t *
    ( h- @2 e3 s" V- P$ Y) N * @Author: 张志浩  Zhang Zhihao
    3 F4 f! i( V3 u) ?: c- l4 e7 k * @Email: 3382885270@qq.com
    * u9 n+ E8 C) Z8 f6 u * @Date: 2020/5/3; y0 o4 a+ A  b/ J
    * @Time: 13:39
    ! K( Q$ |7 [) h- v$ {+ w, v7 e5 M * @Version: 1.0
    3 L. V/ f" W5 h3 y2 N */
    ; R* X  \( f4 f8 m$ Q. u( Bpublic class MyLinkedList2 {
    9 d8 g0 j. E% A1 W4 h/ [    private Node head; //头节点
    ( [& ~# }- ?$ R4 C    private Node last; //尾节点
    7 e( C6 [7 n8 y. v4 f    private int size; //链表实际长度
    3 i  ^! a* r# w
    - k8 h7 J3 C0 K( p    public static void main(String[] args) {
    & b2 V) `9 @. N1 o1 Q        MyLinkedList2 myLinkedList = new MyLinkedList2();8 _% ~% p7 D4 y$ @$ K, w! I* [( p3 z
    //        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作- P( b% ?" R- e; c# n" |! O4 z4 O
    //        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围/ q0 e& r* v# {# `
            myLinkedList.insert(0, 3);% k: e  u: t) ^, D
            myLinkedList.insert(1, 7);) d  F; K3 c2 i9 r* P
            myLinkedList.insert(2, 9);2 x2 N3 _7 ~; ~) I; q* f
            myLinkedList.insert(3, 5);
    3 c" g5 c4 E8 \  s% @! u        myLinkedList.insert(1, 6);
    * s9 v5 t5 c7 n) b        myLinkedList.remove(0);: B  R7 n3 E! r$ z& A
            myLinkedList.set(0, 23);
    " }) S, r% F" s; |% J9 w        myLinkedList.output();1 V6 Z) i! w' O* [
        }
    9 B% A3 D% S, O% u% e* |( b* s
    9 @) \5 p9 Z* ~0 B+ V" v2 P    /**1 ~9 t# S- t& N! }5 \
         * 链表插入元素0 F7 ~6 H$ r+ l- w" e
         *; m0 q9 B; p- a& z& G
         * @param index 插入位置
      X( m4 ?: B+ J* f     * @param data  插入元素 被插入的链表节点的数据$ p+ q$ z+ L, B0 I. u  b
         */; {, A6 Y+ m! a# d6 ?& H
        public void insert(int index, int data) {
      n1 v6 L/ _# d5 H" |        if (index < 0 || index > size) {
    / ]9 S6 }& B4 D+ Q, b5 p) R  P3 `( L            throw new IndexOutOfBoundsException("超出链表节点范围!");, M/ c3 ]+ W: x. h$ P
            }
    / o/ I6 ~% k' G! c        Node insertedNode = new Node(data);
    % J% p/ C; H: W0 D, k) K        if (size == 0) {5 @2 j) H- ^1 c( i
                //空链表- d6 O3 t$ Z/ n0 a; n9 K
                head = insertedNode;: m# J* ^  a: p1 K( w
                last = insertedNode;
    # x6 g6 I6 G: Y9 T        } else if (index == 0) {0 [! E+ @9 k$ @: c) S+ C2 n7 J1 |6 m
                //插入头部
    1 ]8 i4 c# }* R6 j            insertedNode.next = head;
    - ]: u, x' P  [6 J) z/ M$ T            head = insertedNode;
    2 Q4 c7 I/ X5 i7 ]# o% J        } else if (size == index) {
    7 h: Y3 K( X+ e( b/ u! e            //插入尾部# Y& ?; u* u, E2 U0 [1 @) j
                last.next = insertedNode;' J# t( O/ M8 ^' q- o- U# \( E
                last = insertedNode;, P! R) @) I  F; H- J: @; O& X
            } else {
    $ |3 I5 z- c/ G; c6 H2 \3 t            //插入中间% j. ?/ a* f, i$ s* X
                Node prvNode = get(index - 1);1 q- }- F3 S6 W$ _7 j0 {# `
                insertedNode.next = prvNode.next;
      n- @# c4 D! K; R            prvNode.next = insertedNode;
      K4 O0 x, U- _* {$ r. @$ A! v        }
    " C. k  ~6 x) M1 n        size++;
    : H# c0 f: D% _    }
      ]& D2 V3 a/ Y. t7 e+ |! ^# @  A8 L: D' m$ c( H9 ~7 P
        /**
    ( r# I% S0 d1 O% a3 O     * 链表删除元素/ W5 Q5 s/ Q" |
         *" y' I9 e- G; ^
         * @param index 删除的位置" S3 F' {( G. E: S7 G5 D
         * @return 被删除的节点
    3 [! N5 {1 Z5 d; j0 a, Y! c4 n" Z     */
    ( {) X7 B5 s4 f0 J" M8 o0 ^; G    public Node remove(int index) {
    ( s$ t: z' Z# V- b, G        if (index < 0 || index > size) {
    # [4 T- R% Y! R8 o7 h1 H$ O2 S7 O+ a1 S            throw new IndexOutOfBoundsException("超出链表节点范围");5 H+ K2 I& p" p) N# q
            }# L) M% h* H2 w
            Node removeNode;
    ! \. s& H1 f6 L& g# ]        if (index == 0) {
    3 G8 l9 l, D) I# n' I4 l* g7 `            if (size == 0) {
    & v5 R: P5 X9 f3 x* P  }                throw new NullPointerException("当前链表为空,不可以进行删除操作");, I2 r' @% O4 r( c( @. F4 f
                }
    8 u$ H4 i5 {! A, J2 V& [            //删除头节点; C! r& R+ t3 R8 E; |
                removeNode = head;
    + K3 O5 [7 S3 e6 t- m/ b. A3 C            head = head.next;
    8 B6 V$ K3 N. L. z6 p; J  M# |* f        } else if (index == size - 1) {. m' O: Z1 o& \( U' p  i; a
                //删除尾节点. O: z) J! a% E5 U" A
                Node preNode = get(index - 1);1 }" R7 Q9 F0 O
                removeNode = preNode.next;
    ) h  W$ j9 |6 i3 Z  ~: I            preNode.next = null;
    5 G) o, j; C3 e2 p/ I' n4 J  }; b            last = preNode;
      K! `8 x8 d, X2 r2 m2 z5 D        } else {1 a0 Y7 t( B1 S, M+ p& h- K
                //删除中间节点5 _: T: \+ q% S7 n5 W  `1 C3 `7 d
                Node prevNode = get(index - 1);
    5 s# M: T, O0 s( e9 D- Q; S1 q1 N' Y3 ~            removeNode = prevNode.next;
    : L8 {! ^: z+ x1 q# F/ U2 ^            prevNode.next = prevNode.next.next;
    3 l3 O- w! _- w' X) y- ?/ x3 q; e, ]        }
    % O8 ]' W+ i5 W        size--;4 q- T* A: M- U1 W: e
            return removeNode;
    - X. O0 R$ l; r' _$ I8 W- P    }
    * @6 c  N) K* ]7 R8 a6 ^9 T
    ; ~' @* N5 K( ^: S" [: a$ g0 O    /**+ C( A5 [; i5 y7 W/ d+ F  k) h
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。3 n5 E! x- K- \+ m
         *! S& Q1 T3 J- X+ `! Q
         * @param index 需要更新的节点的位置; j3 Z4 i# ^4 K* y1 I4 V
         * @param data  新data
    3 I# _, O3 `" @; h! \     * @return 旧data2 W8 v4 {% K, |$ J$ T3 b* ?: v* ~
         */
    / l/ i8 \. Y0 M2 D4 W- j7 s2 S    public int set(int index, int data) {6 y/ Z4 N* D) r- Y. J: S( ^! I
            Node x = get(index);
    ) ~& ?1 x5 Q: g        int oldVal = x.data;: z: m$ |4 g* }# v
            x.data = data;
    & H7 q4 a9 \! a  J4 J2 D        return oldVal;4 Q7 d' j' b4 {0 Q# a/ e% y% |
        }
    - B9 C; Q9 L' a1 O' E5 l6 }; ?& \, t8 `$ M+ ?2 Q# T- Y
        /**9 G* [. c, l5 t, _/ `
         * 链表查找元素6 H2 J4 b3 C, M7 A5 V
         *8 y' L% j. Y+ \, k" c
         * @param index 查找的位置: P: ^9 A3 t) e; d/ f% m
         * @return index位置的Node对象& j+ R0 P9 E, H3 J0 w. k
         */# j) F5 @; b) S- \9 n' c
        public Node get(int index) {+ b/ F4 m. X$ k
            if (index < 0 || index > size) {
    . F0 u. B7 r2 Y5 `            throw new IndexOutOfBoundsException("超出链表的节点的范围!");- _% j  O- E7 {' {, C# {9 d
            }
    0 H4 @3 F+ M3 M  u! `! y/ V        Node temp = head;
    / B5 d# F3 c  V$ Y) o0 w3 ]        for (int i = 0; i < index; i++) {
    ( C$ u4 j$ e$ ~) A            temp = temp.next;' Q5 H' O1 [# ?0 w4 z
            }5 \7 L/ q2 Y5 E
            return temp;
    9 Z& O& V# x" r5 R% U7 x" u6 m    }
    $ q4 g6 K) g0 N2 x4 t3 @- R. z! m) ]9 h
        /**9 }+ ]$ w: o8 `# j5 K$ R
         * 输出链表% i- N5 V# E1 u9 ^" C( r- y7 M
         */+ P7 |- h) U4 n
        public void output() {
    $ Q3 f& r$ m; y" P; E7 R# f7 j. n        Node temp = head;
    ) k) O* v+ U, x! }- ], m$ P; y5 M' f        while (temp != null) {
      {4 i7 w- L: P  b9 P' g: Z5 v5 {/ K            System.out.print(temp.data + " ");8 q) w$ P  W3 Q5 q, v% H/ e
                temp = temp.next;* O; y7 {" W* P' T  l
            }4 A  L( Q& z. ~% {5 y
        }
    , w! ~9 X3 A! M5 Q$ x. T  q& n# U7 f# T2 O" t+ \) {
        /**
      [8 p# F6 e6 ]) E$ J     * 链表节点
    / E$ \& g8 j8 C7 H/ ?     */
    4 `, |0 ?  v4 [- J! M- r9 B    class Node {* t% L3 j" G7 Z: e5 L2 s# Z) T
            int data;
    4 J# L3 z: n6 {. }9 w: r        Node next;" z) ^  Q. V5 o2 T. k8 i0 y- D

    - b+ `0 z8 k. ?$ w/ _        Node(int data) {4 l/ T2 x1 q/ p; O( b" E) k* i: H
                this.data = data;0 H0 c( a( ?5 n
            }
    ) _* e! f5 S% b. U% X    }" m5 B8 @. J' w
    }
    $ W6 a" u- [; @# R/ I- O9 g7 G
    ' E$ ^- G3 u$ q" b. A7 _  ]9 h& p* }( w7 k* d
    二、双向链表 12.png
    2 m! a; i. E9 D2 u2 C& i7 i  M双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。3 S/ K- L; p( D, o: x
    , g6 V9 n* k" _

    4 n6 u5 j7 J0 f* Y1 k* \6 }8 l6 ^6 P# K& r- Q2 q

    . b$ {. ]* G" y# z* z————————————————7 n; }: n8 W1 D5 c( y
    版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    : F) @; m% s0 d$ j4 b* C原文链接:https://blog.csdn.net/weixin_43124279/article/details/1059044686 X$ P9 J2 A3 B

    1 I' b! U. Z6 l$ X! D# ]
    - f5 `7 V1 R0 d8 Z' r% ~! j/ y# X$ u

    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-21 13:17 , Processed in 0.399492 second(s), 54 queries .

    回顶部