QQ登录

只需要一步,快速开始

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

    " c% j/ y8 ?7 u$ L【Java演示】什么是链表?数据结构
    " |- ?6 n7 L7 e/ p; k一、单向链表
    * {) F+ Q) s& A5 b" J" w5 P+ k# n6 P7 x3 I
    1.png ; X- V8 O: }8 [- l" ~( c- E/ G" o
    链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。8 G- ~4 L7 x8 O4 k
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。6 G' ~" u  r7 c/ O: k
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。
    0 t$ l$ _5 \5 `% O# r; a7 y2 S- H1 D0 \8 f5 ^9 e7 G- P: b+ p
    什么叫随机存储呢?
    : o' n% G4 m$ ~3 [9 K) q! j8 w- Q/ x$ A1 x4 c% J' i& }
    如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
    3 V7 ~" G. q- g$ g1 ^+ a上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    ! z/ s+ P8 L" N8 t; h8 j6 n! V; t 3.png
    2 p9 s0 n/ r: k9 r- l! y- F" v1 [8 A* J( b% y5 E/ c: W2 f8 k' w

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

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

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

    4.png # {0 t3 ^* i! s1 y% q

    8 ]& u& h9 |1 X- J/**
    ; n( V5 Y: _; O3 ]* x& N6 b# {     * 链表查找元素
    / a/ H: O, `- g" @     *
    * _& U( o# {+ R( \, e9 s0 Q# P+ g     * @param index 查找的位置9 ]% Q) `, a# P1 D# f2 f# G
         * @return index位置的Node对象
    - T' m7 a5 I* W' t0 E     */3 ]. @) _2 b5 a: t! h5 G, ]
        public Node get(int index) {
    $ @2 I) i  l% s. r        if (index < 0 || index > size) {
    # ?0 d% ]2 u" H. d8 f8 T            throw new IndexOutOfBoundsException("超出链表的节点的范围!");' M4 h5 _4 j2 D6 {& ^, |
            }( _" o3 U* \; s
            Node temp = head;, J- ~# ?3 L: M8 N5 D% |, w( F
            for (int i = 0; i < index; i++) {
    * ]* T0 w9 k' `( W            temp = temp.next;
    3 D! c$ Q' C3 ?% t( P& B0 e! A: v" c# e        }
    9 K0 _2 w2 F7 ~5 J7 f) t        return temp;
    0 h9 l8 B5 G4 Q4 z" L    }4 K  w6 v# k+ g7 r, J% m1 N9 P7 W

    ( G9 ?+ K7 y$ ?# _9 v1 H: T! y

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

    2. 更新节点 5.png
    3 v5 [3 ]  m% f6 D0 a# I2 U' \' c/ s7 C+ k# x6 w( [& V. r- P
    如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    1 h+ @; W5 Q* V$ B; a% \: _5 Q. S如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)
    & c- k' S, ]; n% s, {/**+ \5 f8 _8 {/ [# y
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    % {6 |9 O( ^9 i: q     *
    ) Z! p( x) P- Z: O; K     * @param index 需要更新的节点的位置
      i4 K) N" [# M! r  Z1 G     * @param data  新data" l+ P" G$ s6 Z
         * @return 旧data: ^4 `* ^& A# t/ x- |
         */0 `# A7 s: o6 S8 U6 x9 D
        public int set(int index, int data) {0 m2 w( S5 I/ H) T
            Node x = get(index);
    % D7 @! R  b  A        int oldVal = x.data;+ h, d5 l) ?2 k  ]( {' I1 L8 Z
            x.data = data;
    % r+ Q; ?8 H9 p, K        return oldVal;
    7 [$ Y- k+ w# |    }
    # h9 z- D8 |, u; l; Y5 |, s& e+ I' h" }; g: p7 H/ I- i8 h
    3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入
      # Z; T4 q6 E& _$ a9 ?2 b
    3.1. 尾部插入

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


    $ F: W- u5 k6 d/ y3 r 6.png   ^" y4 \. c0 X/ l, J! ^  g# |
    3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。
      4 h1 a5 [4 r& U+ {7 Y/ S: D
    7.png
    5 r4 S! Y4 n- V& J* ^' P5 d3 i
    ( W0 q# Z8 T8 K5 b- t! T5 i8 A. j+ x3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。. [4 \% k5 R6 o! u7 P
    8.png
    1 C2 D3 u( }4 Q) C
    5 x* L' s3 @9 C4 R2 y三钟情况的代码合到一起
    ( V1 \& H6 J7 N2 e1 j; K+ S/ b. b, j2 j
    /**
    - y6 {; f: q7 R( z     * 链表插入元素
    ! B0 _2 s( J7 N4 M* m     *, p/ i, b9 `2 E" w. Q
         * @param index 插入位置' s0 l1 O4 o. Y' T- O" j$ u
         * @param data  插入元素 被插入的链表节点的数据4 y$ y: b+ _: o$ u- l# Z
         */
    ( q1 @* _+ S& h+ f4 V0 u7 K    public void insert(int index, int data) {' R9 g; Y9 e& w; B$ @! l" a8 {
            if (index < 0 || index > size) {, I$ _+ r5 {( |* M: _% m
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    + a3 r" `9 p' Z. d        }
    . A- }* T" ]& E  W+ R        Node insertedNode = new Node(data);) j$ r3 ?+ i1 h  I7 @3 h
            if (size == 0) {, a" b: D8 t8 q% Q0 [7 e- f' a
                //空链表$ M2 E* {% f. M4 k& k) |
                head = insertedNode;
    9 T6 u3 u  Y. r  l1 `            last = insertedNode;
    ' _, H' F# {/ h& S        } else if (index == 0) {
    & K' P. d' q- b3 w- z" w            //插入头部
    6 Q& ?$ M3 P2 L$ t8 H1 ^0 a            insertedNode.next = head;$ A- G0 W4 M" G
                head = insertedNode;
    4 E( J" }* |5 }4 g% P; z% ~        } else if (size == index) {
    6 \  T! ^- \$ ]            //插入尾部) I3 ^* \( q5 y& M* V9 n* J
                last.next = insertedNode;
    + [6 W$ i3 k- m" X, p- A            last = insertedNode;
    6 G# l7 \- \) Z' m& g& f5 L        } else {
    5 a0 C! k$ c" J6 l! g4 D5 g( z            //插入中间3 |' X+ P# Z9 |; \5 c/ H' y* \" }
                Node prvNode = get(index - 1);
    ( X# y4 d3 N) k2 T( K# S9 h            insertedNode.next = prvNode.next;4 m  i  j# g- |
                prvNode.next = insertedNode;
    0 }& Q9 p( [1 y" ^3 m! X        }
    ( r4 W! p& ]2 z# m1 A0 a  K( I        size++;
    , z& J9 C" V' J    }( `% V3 V, [# X9 q$ W

    # @( i$ g: Q" l* U; c/**  [7 Q; _5 l- Z1 C4 Y+ n5 J
         * 链表插入元素
    5 h2 y0 k- l- z     *
    1 F) o, ~5 |$ V& A) D+ b     * @param index 插入位置
    3 }  u. {5 z) g" l     * @param data  插入元素 被插入的链表节点的数据
    ) j8 S% I2 ]2 W; ]& f0 x& K/ R     */" j( Q: |1 w5 c, C% K; A8 P
        public void insert(int index, int data) {/ I" S/ p0 C( {* R5 j) g& J
            if (index < 0 || index > size) {# W5 A& v4 ?' K
                throw new IndexOutOfBoundsException("超出链表节点范围!");# o& N! D8 i4 {- U% A: @/ h* z9 C
            }" L6 `: t& ]  S* g: L
            Node insertedNode = new Node(data);
    2 _/ N6 Q4 ~% ?1 }; Y8 m; Y3 J' n        if (size == 0) {
    ) l. ~+ E4 L# z            //空链表
    ) d* M! |, Z! h3 Z& l9 B            head = insertedNode;8 s/ R1 _8 f0 p
                last = insertedNode;; ~+ p! ?4 C! _, P. r$ f2 ?1 e
            } else if (index == 0) {3 ^% p8 S$ M( ~+ K4 l, p! E
                //插入头部
    + f1 Q2 A- s. C) t- b6 q; j( F$ J            insertedNode.next = head;
    $ q; u; L# g( m2 g! G- H7 {            head = insertedNode;
    " w# M7 |8 n6 ]7 o; q4 Z        } else if (size == index) {
    4 P; S( a/ F- I            //插入尾部& _( Z  a5 g1 A# Z) C( b! k
                last.next = insertedNode;8 b. N( L$ |0 y4 a' Y
                last = insertedNode;
    , K) p, _/ c/ j        } else {
    + G  \- R: K8 R+ w' w            //插入中间6 X& N3 Q" Z1 |$ v! o* O  U6 h/ H
                Node prvNode = get(index - 1);
    ! V0 F3 m! l, O. }" M            insertedNode.next = prvNode.next;% s5 z; W/ q8 ?3 N
                prvNode.next = insertedNode;
    ( a- \/ u" n7 D6 T        }4 a3 I- H6 ~: i
            size++;
    ; {; W; a) b8 Y" m4 A' N8 B    }2 ]1 r6 \2 h* X) u
    4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除) D& f; h0 Z8 {
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即
    % m# j' W$ U1 ~. l8 b+ S% S% A可。

    9.png
    ; X' S$ M6 v4 V) U. V( ?3 E* ]
    ) A& N$ s7 K+ W2 l: {, J- _% A, O4.1. 头部删除

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

    10.png / v6 U/ `8 ]0 e% y8 |$ \

    0 y$ T% g- U$ @( j4 s4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要
    # V6 u1 Q9 w- h' O删除元素的下一个节点即可。

    11.png
    ! _1 P- {2 Y4 E# k( a7 P6 t) a# a2 L2 _  L: J' `) o2 e) O
      ^' p/ w% ], @. X- e1 E
    这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。* X+ o# G1 X4 c' b
    如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)
    ( \: s9 l- D6 `/**7 i( R6 C2 b. w: T6 b
         * 链表删除元素
    # ^# i2 A4 ?. p/ F     */ s9 p  r+ {% N, f  X1 @
         * @param index 删除的位置( `' \  a* x1 p& D* V
         * @return 被删除的节点2 d4 K' Q& L; c1 Q3 l  @0 ^) I
         */
    3 J: b6 p( K4 V1 E    public Node remove(int index) {9 t  A% Y; I; ?8 O
            if (index < 0 || index > size) {
    , d$ a9 D7 b# z            throw new IndexOutOfBoundsException("超出链表节点范围");
    ; B; Y% y8 \6 [$ b5 M        }
    : t7 y. @; I7 B$ _        Node removeNode;; h) e4 `+ q) p: w7 z
            if (index == 0) {
    : _/ P- h3 I5 |0 P9 u! t' s& K            if (size == 0) {
    # C2 i# i$ P% ], N) d8 ^$ a                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    7 k' b; V6 o0 G& e& Z            }3 T# b# a- p4 M5 K. v
                //删除头节点0 ~3 l; v/ L! j4 S; [% D" C0 h
                removeNode = head;6 R8 b3 f7 W9 Q. B% O' L
                head = head.next;# C* l3 O" d: y' Q
            } else if (index == size - 1) {$ |2 i; C: j. ~2 {& l8 z* _' p5 Y3 @
                //删除尾节点$ i6 f1 _/ T/ e% {( C! |$ w; U
                Node preNode = get(index - 1);1 @6 B5 C8 @$ t' t0 l1 r, n
                removeNode = preNode.next;
    ' {0 ^# s; Q0 }6 R) _8 I7 y7 ~            preNode.next = null;
    % \2 z! w  p6 B; `% E& ?: A! y+ Z            last = preNode;
    9 R$ O1 i; o/ t; V        } else {; w* l6 M) G2 s+ Y
                //删除中间节点
    3 j7 l* `. C* V) r            Node prevNode = get(index - 1);
    ! C) Q# O' @0 d' C7 S            removeNode = prevNode.next;* O4 h; p4 T! U" T! _3 b7 W" p
                prevNode.next = prevNode.next.next;' X1 @/ J- C7 q; a
            }3 }3 v* g& h5 y4 d) Y9 m
            size--;) x% w+ L! D: [& L# t8 J
            return removeNode;
    0 B5 j" b/ g/ i/ w6 G0 i    }. ~! R( Q- N, ]
    Java实现链表的完整代码package chapter2.part2;
    ) M, s( H2 V7 c, W3 X1 @" i$ `, t  Z; j7 p
    /**, E$ Y4 x" g, _2 S8 R. j
    * Created by IntelliJ IDEA.& e6 D7 d; F0 N1 u2 y2 Y1 s4 p
    *
    . T+ @# u4 e+ q4 f% e * @Author: 张志浩  Zhang Zhihao" \: B" t1 [. z% q
    * @Email: 3382885270@qq.com
    - ]" ?% M/ @( F  Y  K * @Date: 2020/5/3* C, ]) {  u6 W
    * @Time: 13:39, _0 F. O" |7 u! F' ?( f
    * @Version: 1.0; N6 A2 _+ p5 w0 O
    */
    % o  n4 b9 c" l' X* Xpublic class MyLinkedList2 {
    ( O# M% t9 V, p+ k! V# b! H    private Node head; //头节点4 q% L- Q& P! [8 [. }3 Q, ^
        private Node last; //尾节点! p+ I; l$ i' L+ {& q7 }
        private int size; //链表实际长度9 {  O/ d: R0 h0 ~7 }. @: P# D
    . g  s2 b$ @' j9 ?+ r5 m5 r" n
        public static void main(String[] args) {/ P+ g# L0 A; {8 A( B9 o. F
            MyLinkedList2 myLinkedList = new MyLinkedList2();$ ~$ ]  @$ b( M+ D! R* [
    //        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    + }/ D$ f) w6 w- a3 @7 L0 Q; a//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
      G) W5 ~5 v! [: z0 L# C        myLinkedList.insert(0, 3);
    ! ?- W. B' e' i8 K        myLinkedList.insert(1, 7);
    : B! z0 B) o! r        myLinkedList.insert(2, 9);
    ! D5 X9 l  d1 t( o        myLinkedList.insert(3, 5);
    $ q% ~3 \6 D7 {+ _        myLinkedList.insert(1, 6);, r7 E* p# R6 [
            myLinkedList.remove(0);
    ' ]0 w  [1 _) y8 X        myLinkedList.set(0, 23);
    & z) N7 L6 m) b3 S! Q  P; D        myLinkedList.output();4 c2 R& M* F% _; _
        }$ f  b" A" v6 [: l# \5 \
    : e8 F( E) G! X0 C! K* K
        /**& G, o% n( T8 a; V2 z3 O
         * 链表插入元素
    ' {: a5 F' f3 _" ?/ h! q' N  B     *
    & T2 D1 I1 T1 e" A3 W" ~     * @param index 插入位置
    6 q) i' W, x2 f% k# Y     * @param data  插入元素 被插入的链表节点的数据
    5 O+ @. c" O4 [5 v7 p. Z  b/ X# p, B     */" K" l) E' v5 A+ S4 W1 J3 Q  j  F% O
        public void insert(int index, int data) {
    : i+ L. W6 l  Z5 W        if (index < 0 || index > size) {+ g* \& K; v7 a. l3 S% [- |! e) k
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    ) p1 g5 r% W, D: M# {9 r        }
    8 b+ R. U% N* Z  I7 Z  f( M        Node insertedNode = new Node(data);- G  r4 N' k: e; m) R7 M0 P
            if (size == 0) {
    * _# h" j& ^) s, R' X            //空链表) W, @# X( l& _
                head = insertedNode;
    - Y5 T' u/ |# Q( J+ {* \7 y0 L, T4 Y            last = insertedNode;' x5 v- T) u+ \+ e" S
            } else if (index == 0) {( f: f2 [5 ^8 N$ ]  s: Q
                //插入头部
    / T8 s; b! z- K3 M            insertedNode.next = head;
    3 ?$ r8 h* S# h7 {2 D/ K6 d9 J            head = insertedNode;7 h8 d6 n# x# }9 c2 F  I9 l3 X* t
            } else if (size == index) {
    - M- @2 V4 e9 }" [            //插入尾部
    , _  {' u) s4 ?: I2 J            last.next = insertedNode;
    . k! [! p9 u0 v1 x- o            last = insertedNode;
    2 g* T3 [% A: {) I9 U( ]        } else {
    3 x3 C5 ]! H. h" m            //插入中间. a- H( h- |- T: J4 V, B. K
                Node prvNode = get(index - 1);; T4 S# Q  N# d& s+ w* I  B
                insertedNode.next = prvNode.next;
    6 c( T4 \. K* [, s9 ]% D' c0 [            prvNode.next = insertedNode;5 ~3 |8 q) \* j
            }
    % V. d$ r8 H5 b5 K9 R        size++;
    ! [2 m1 l( o+ _) ]) m' N) I    }. |' u4 c4 A/ T
    9 }- {; y: V2 `
        /**# E' k4 A" c2 i6 b' ]2 f6 \
         * 链表删除元素
    ) M6 d3 o( G! g& g0 r     *- ~' l. h7 s1 e" |2 J+ d: n
         * @param index 删除的位置: A# O; k1 H8 u% ~3 h
         * @return 被删除的节点1 f) D# n! G- i
         */
    + ^6 z8 i; d: M$ `% l: V0 I$ n* e    public Node remove(int index) {
    0 n' r( e* _6 T; ~: M% a+ E* G) C        if (index < 0 || index > size) {2 Z( q2 f' m1 S! w0 V& P
                throw new IndexOutOfBoundsException("超出链表节点范围");6 E9 E) i. O/ O4 V; ^8 n
            }
    ! H* f* ~7 m( i. @        Node removeNode;/ ?% ]1 e, a# R+ ]
            if (index == 0) {
    2 ]% I' A: M% O! P            if (size == 0) {
    7 O3 k8 \$ J$ l% i# n" p8 l                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    0 T! B+ u9 {+ e/ D$ j            }4 H7 G( B# e0 K5 ^
                //删除头节点
    3 V5 |, @; H8 g( o            removeNode = head;3 ~$ O! ~+ Q( Z8 j# }# ^  z( \8 u  v
                head = head.next;
    ! }. S. s. p8 n5 R: w% q        } else if (index == size - 1) {
    7 z1 B- I. _# Q. i9 q, A) u0 o7 o            //删除尾节点- C! E1 `; S& |4 o) R
                Node preNode = get(index - 1);7 V# [% m: e0 M) J% G
                removeNode = preNode.next;
    1 O+ V) ]8 S5 W* m  r            preNode.next = null;0 Q3 P: a( \2 |7 J+ j
                last = preNode;
    ; B$ o- \' U5 y3 ?        } else {! U- r/ l' x3 q, |! |
                //删除中间节点5 S4 g1 s/ d1 I
                Node prevNode = get(index - 1);; g5 B6 z2 e1 u  N3 v5 G
                removeNode = prevNode.next;) ], d. y3 s0 k
                prevNode.next = prevNode.next.next;$ J, G- g! _" I0 @  K& q& B
            }  W. m  H6 t" E& a
            size--;
    2 ~2 Q$ T% Q2 P        return removeNode;
    ! X2 k0 V+ A# f* d. l  w# u4 P7 @    }+ W! [2 P1 w/ e. w8 q! a# @. \4 ?

    * u) s# g1 {0 ^1 P' B! l1 p% q    /**- n+ o) ~6 c; m) j7 F
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。% }+ E% j# e: z1 B+ Y! a
         *
    1 F' b% ?  k, H7 b     * @param index 需要更新的节点的位置
    ( k$ a% l; o/ j0 t; l( K     * @param data  新data
    * e. k( b! M; m' F$ A     * @return 旧data
    3 w: K. g  d) n2 A) N" H2 P8 t2 v     */1 c2 Q; h" L) C
        public int set(int index, int data) {
    7 x9 E5 Q7 p$ b+ j        Node x = get(index);
    % U" s( O' }& l0 c+ _  j        int oldVal = x.data;2 _2 O& X$ Q, C; p5 J
            x.data = data;: g5 J6 [, q( W+ T  y3 B- ]
            return oldVal;
    + N4 j5 m) {8 |% i! ^    }
    * m  j+ @9 P) C! g! v1 J5 H, L
    % ~# h1 {5 N/ L; |0 P- h    /**
    ) P( Y, B7 z6 v0 ?8 {' K( T     * 链表查找元素
    : K1 O$ J; r3 {0 i. ]# V* v7 A     *7 N& w  k7 C' \! N. o, B: {
         * @param index 查找的位置, K) H+ J) Y, F& A
         * @return index位置的Node对象
    6 `8 e2 ^+ x8 x! N) J5 m     */( T( t7 J5 b# j  X% I" e- X5 G
        public Node get(int index) {
    * K0 S- F' [1 C3 j        if (index < 0 || index > size) {
    7 _& ]+ z0 l  e% @  u' T            throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    2 Y0 L3 l' U6 h1 E& j        }- `$ e" M$ c! h/ j- J0 f
            Node temp = head;. Q; `4 o( e! h: E3 \. P
            for (int i = 0; i < index; i++) {
    ) J' C  G' R, L) Y            temp = temp.next;
    0 G, s6 E- g3 V4 M9 w8 \2 s# q        }
    + L' b' Z+ ?6 |  j        return temp;
    " k( ~: `. [% m, b2 ~  ]7 \! \% z    }
    & M6 J0 _- @1 W8 |) ?; u: m; L" p6 f4 g  |- y
        /**4 N$ M( a  L; {7 K  l
         * 输出链表5 t% n4 M; A) N/ {0 r
         */
    $ m& f/ r! [& G3 |5 A    public void output() {5 V6 k: w+ d) x/ ?* _4 R. x
            Node temp = head;
    + R+ x( I9 v. f& S. A( u# [        while (temp != null) {$ _& _9 T) x  O
                System.out.print(temp.data + " ");
    & k7 U4 s/ ^6 |. T6 _$ w6 {            temp = temp.next;
    - m( I# d0 A0 X9 M' Z8 I        }2 g( V' _) y1 ~, S  G( t2 _
        }' A) F& u) P5 n( R6 b; u
    8 H* \+ _. o8 e) T% C0 P
        /**& l9 F; x$ C+ ^- l" Q5 j4 f
         * 链表节点. R& L  X3 X/ i/ }, j* N) H9 v$ `
         */
    - K, O1 Q$ n& O) ], ^6 C) b/ u" _9 Q. X    class Node {3 o! E# s4 ]: e$ k$ |
            int data;
    7 ~% z" k. z* c* d        Node next;! c0 t5 n4 ]9 F1 }+ {

    - o8 j9 J5 n% w( i0 s$ W/ {: n( l        Node(int data) {
    ; q: b) K9 d5 t4 O- G, \! u* b            this.data = data;, C( P6 w5 }. P9 ?# B8 M
            }$ h: v6 h& [% G0 _/ m: U
        }
    - i2 N; D% ^/ I, _( j}
      s4 J3 i& b. c: Z9 l" {' S7 o
      X3 G  @$ O! D  i, _6 Q4 u4 X0 v6 g3 F+ e
    二、双向链表 12.png
    0 I3 c' w7 Q) \1 Y双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。
    6 M$ G1 h( Y6 U/ d( t- }) ?
    0 G4 d/ Y% l* W9 |0 A
    ( t  S3 l: g& W. i
    % b- b! l3 V8 t: D1 G, }
    / b7 s! I2 V5 ~) V7 I+ k————————————————5 E+ i, O; Q0 o3 V, D
    版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。; |9 g7 A3 o/ K' X( I, E
    原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468
    + ]7 o, C7 g$ t1 l7 V" N
    * S8 s/ `3 q5 m" w; }
    0 I+ C& J/ ]) v5 ?1 K1 }# t

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

    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-9-22 20:31 , Processed in 0.424520 second(s), 53 queries .

    回顶部