QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5334|回复: 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/ F" B0 T  i2 f" w$ D
    【Java演示】什么是链表?数据结构' C3 r, o3 ~# @1 E) [  p. N
    一、单向链表, A7 K6 ?3 N7 ^' Q; c

    - @' S$ Y/ `7 k, L* A+ j 1.png
    1 ^1 }& v0 h! F% r5 c链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。
    3 i6 s* Z( ^1 p( V& `. r单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。
    & v8 ?  W9 M8 _( a5 q! s链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。6 `+ i# z# b9 F$ f" j! _
    0 [% m! V8 ?0 D# E$ E# m
    什么叫随机存储呢?  Z# J, W+ B, G) {: y1 g' \
    ( [* d# r( e6 ]) r0 h& ^( a
    如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
    + [% C6 _8 `, X- a上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    / z6 d3 q: @) @! N9 G( I5 r; N 3.png
    " f* h$ h3 M; u/ F& t; Q3 ]* N" F, q  j' [, l

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

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

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

    4.png 5 {5 T& j9 @0 h" a1 ]; u

    3 }+ }& G0 E* |+ w/ W0 i5 `( t4 x( n/**
    7 t8 h1 M0 p- l2 _     * 链表查找元素- D5 h9 F% `. @1 L* N' W% ?
         *2 W( M  X$ g- Y/ z/ H
         * @param index 查找的位置. l- s  T1 P7 P0 O% K
         * @return index位置的Node对象
    8 b: H. R" q, Y- |. {" o     */  t# d- ~9 s9 H9 A9 b1 f4 V
        public Node get(int index) {
    9 ^6 i  {+ W& N, G        if (index < 0 || index > size) {
    ) X2 v9 z- Y1 c% w8 p8 g            throw new IndexOutOfBoundsException("超出链表的节点的范围!");2 r. H2 Q* z. u8 e. v
            }
    * X& U3 \2 m# ]$ N        Node temp = head;% h  [2 `2 D) y  S0 z9 `
            for (int i = 0; i < index; i++) {' p! @; @8 L7 x$ d9 u7 t
                temp = temp.next;( x0 ?* H0 l0 K+ D$ m+ _5 n$ r
            }9 {- [1 a4 o- Y# A
            return temp;
    $ B# }5 }$ {; m1 U! }! ~    }
    - Y* B- ]6 x% L# c; |" H8 r' ~
    ; H# l- V) E( G( `9 v

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

    2. 更新节点 5.png
    2 ^7 d- n+ j5 b# q& {* S3 f5 q# r) [5 ~4 s/ v: I9 y
    如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。& {: I' L  U& k3 z
    如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)
      [9 M" D$ b1 o* w$ @0 `" X& ^  `/**1 D  ^$ w" y% K. }
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。7 V* S* I6 G  I/ k8 E6 V
         *
    : k' `) M4 z! v     * @param index 需要更新的节点的位置
    % e( ]% w- F9 Q' z% f+ f( M( s2 h: X9 `     * @param data  新data( _6 L4 b" M1 I" j6 c& _
         * @return 旧data: Z7 h$ R- z! Y! }: `
         */! j$ J4 e4 o( H0 F& p+ F* B# x
        public int set(int index, int data) {
    0 B4 }' {) v4 s+ ~0 R5 P2 A5 `        Node x = get(index);
    2 v. D) e; Q4 X1 O8 @- e) N5 u3 A        int oldVal = x.data;
    . t$ a) \9 @% {1 f0 k1 D, p        x.data = data;
    8 U0 F/ r% Y: I4 G        return oldVal;
    " x8 N" F3 {7 H4 e4 m4 r0 d    }
    3 A9 P0 g( {+ m7 ?
    , K0 g0 U" R) C- z0 O2 z) D. N3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入
      # [$ m- ?! |" R; }# S- g2 r! t! }
    3.1. 尾部插入

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

    4 r& @0 Z6 o, v
    6.png # t$ F. x" T" a4 o$ f+ T% z
    3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。
        c" G) y4 T; S' a
    7.png ) X9 _5 ?. a* i# `/ M- O

    ) [8 }) N1 n& [5 k8 @. M- T3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。
      . ]: y& E, r2 C
    8.png ! n! t* M4 m) r

    6 ]7 p$ w- O# e0 B7 `5 C- v三钟情况的代码合到一起
    , n  u1 a8 F3 d% g& m' }% C7 F4 ^7 k8 S- y( U
    /**0 w& Z* I% O* n6 p
         * 链表插入元素8 q  k. L8 r: H, L9 X
         *" e. v3 Z0 x+ b; T# o% g
         * @param index 插入位置
    7 h. m9 {* a9 Y+ [( M     * @param data  插入元素 被插入的链表节点的数据" B# ~9 t% k  i9 M  `+ T1 H
         */9 }* ?. @4 h8 n$ F4 x. ~# Z
        public void insert(int index, int data) {' y/ k- w4 O% `2 @9 z& X
            if (index < 0 || index > size) {
    % |. q5 B/ K6 \* M# l            throw new IndexOutOfBoundsException("超出链表节点范围!");. `; x( c& o5 w9 ~( c7 w
            }
    * h" O: K: `( \4 f9 Q( @1 M$ x) O9 F        Node insertedNode = new Node(data);
    , A$ p1 p. y0 h6 M4 w( n        if (size == 0) {9 j6 Z' q8 a0 ]) X4 c/ s; k9 B. l
                //空链表
    1 W) u$ d* k0 q6 r1 s9 w9 T. p            head = insertedNode;8 ?: O- R7 z! q6 d- Y
                last = insertedNode;
    ! x; G3 b4 X7 D) g& u* [  Z0 ^- k        } else if (index == 0) {
    * t- X- @3 Y! Z1 y            //插入头部
    , o. [! r' k8 p9 R) u3 P0 F2 ~4 g            insertedNode.next = head;
    3 n) s8 I( Z& Z2 ~; h& {" ~            head = insertedNode;( U4 E1 L- q' l7 N9 C
            } else if (size == index) {% S: b4 {6 {) r& r1 m  C8 v+ n
                //插入尾部
    % `5 J# F4 {- i* q& g$ ]/ @            last.next = insertedNode;
    * k; b& W1 E1 v: k! x" S- T            last = insertedNode;
    ( p* w4 ~$ ^& B( H" B' [8 H        } else {
      Y1 k3 u" B/ M3 K) }' Q+ R+ v            //插入中间/ Z6 c% h3 _& D3 e5 _
                Node prvNode = get(index - 1);
    8 u2 V* v$ ^  g% c3 I8 }* d            insertedNode.next = prvNode.next;) Q" p% H' _; @0 o
                prvNode.next = insertedNode;
    1 Y$ ?% o7 _9 w5 C        }
    3 U6 y* e2 K) ]. W1 T! B        size++;5 [# F/ `& h2 g4 h* @+ e# n
        }. f  n2 A4 {: o# N' Q9 O! E
    6 f# [; \- M% w( [
    /**: X0 O+ P* z7 I  O* ^. F5 U/ c! S% w
         * 链表插入元素
    1 t% R) G* u9 R  Z: |* E- p1 |     ** F- h! P: Y" T7 ]5 R- Z, V
         * @param index 插入位置
    1 T& Z: h- ~! f  g) {- ~2 l     * @param data  插入元素 被插入的链表节点的数据( g3 K2 j- X( S4 y
         */
    1 ?) u- c$ t/ g+ j' |  G    public void insert(int index, int data) {* a. o8 `0 Z+ }
            if (index < 0 || index > size) {
    7 ^8 {0 p/ y2 H, O# Q            throw new IndexOutOfBoundsException("超出链表节点范围!");4 F$ d3 K" [$ B& }# m. I
            }
    & o+ A# E; z, L+ C7 T$ e7 S9 s        Node insertedNode = new Node(data);9 U$ R2 ]7 k) m" \, [# L+ c0 T
            if (size == 0) {1 L# J9 W) C+ @2 W7 H' b3 D
                //空链表+ U6 g) J) T' O0 @. ~
                head = insertedNode;. U% l5 @6 D% _, [' @" U
                last = insertedNode;
    # B$ q" ?" B: q/ X% c8 c$ @1 ~        } else if (index == 0) {6 M" f/ y1 K; y8 w" P
                //插入头部
    ; B. E% l* Y3 q" c            insertedNode.next = head;4 t3 }7 q+ `2 Y" B! B3 r
                head = insertedNode;
    , Z! Y; s3 _- a' K0 T        } else if (size == index) {
    0 N$ C  G" M; H( k7 Z  }            //插入尾部
    5 r3 C7 X; s/ o) m, O" a3 l            last.next = insertedNode;: L; ?* Q2 c/ s. E
                last = insertedNode;; N8 [( W: a  I7 x
            } else {
    4 Y, R" S0 \: h, N7 b. k: o            //插入中间
    % x: j& s. x7 D' Q9 U0 a            Node prvNode = get(index - 1);
    $ B. G/ q- H& v  w) d: v            insertedNode.next = prvNode.next;/ T# n( J3 @7 [& p( a* _
                prvNode.next = insertedNode;
    , g, a: r+ m" `) ]  }9 s        }
    ! ]" e) l) I6 f9 s' E( s& E4 Y3 D7 c        size++;- Y  ?: J- H. T1 J6 x
        }# j) t( C- \4 f: P
    4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除+ M0 A* v9 Q. s  J
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即
    - I4 j0 j, y9 L$ L可。

    9.png 1 X. L1 i" O  O6 ]' x, z
    ) _, i6 [) c' @  T2 c+ {
    4.1. 头部删除

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

    10.png   s- X+ z, `. ~
    ; S' B1 s9 X: [, f4 S0 P
    4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要; Z, n- G' N. j/ M% J& {
    删除元素的下一个节点即可。

    11.png + C3 ~0 i% l; X" V2 W4 M# w7 z, f

    4 i; n) S  y0 h" W6 |9 M0 b: e3 o! S7 @: Q1 g
    这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
    ) ]1 r% h  w( w0 T如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)$ F. o6 @: C) m& A, }  Y' X; b0 k1 N
    /**- y3 z# {+ P; n, h2 r- b# D6 t
         * 链表删除元素2 I6 i. Q% t+ Q/ f, g
         *
    : c! F& @# d3 P5 M6 ~5 C     * @param index 删除的位置
    1 a6 R- }' D5 o: {* e     * @return 被删除的节点
    4 |- Q) q$ `' @* I     */
    9 @: j7 J- e8 i" j    public Node remove(int index) {6 j8 i6 r- E* b3 T
            if (index < 0 || index > size) {
    2 U( u0 T* g: z1 p- }            throw new IndexOutOfBoundsException("超出链表节点范围");8 s2 j3 G6 M$ N& l
            }: U9 G3 ]7 T# e
            Node removeNode;7 o7 `$ d) N- a( \* ^1 i: A! C  e: }
            if (index == 0) {
    - x; B: W! O" p& P4 i: I3 V            if (size == 0) {
    : U9 C% M! N/ F/ f& H                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    3 }3 E% N4 _6 e* a, i, E( B            }! U6 x, c! _& _2 j
                //删除头节点
    $ F. N2 f; ^* j& L            removeNode = head;
    6 M4 S( `: I( R1 s- v! J            head = head.next;# B) r8 K7 A$ `/ W% J
            } else if (index == size - 1) {
    # ?; h2 d2 o" F. ^( S# c$ w9 \            //删除尾节点/ s6 i- y5 `  l2 E$ R( Q; V1 A
                Node preNode = get(index - 1);" e% f, b4 `& Q5 c/ X& r
                removeNode = preNode.next;% y* P# Z7 A" H' s
                preNode.next = null;+ H9 {' D3 K4 q- [: t! U- E. S
                last = preNode;
    4 f! h, [+ y* l3 m( n$ a        } else {+ a7 }2 p2 F; D: L
                //删除中间节点
      |. \4 F0 l( i& [; K  L% n            Node prevNode = get(index - 1);, ^' F$ P- h. @. _
                removeNode = prevNode.next;( w& K  }+ ?: `4 G
                prevNode.next = prevNode.next.next;
    ; s% g+ S  z$ P1 Y' w        }
    ) z" O8 e5 [& O' ^; ?        size--;
    ' x! N' ]/ L" C) x9 e, T        return removeNode;& D7 r2 N6 z6 h* X" N
        }
    0 [9 x8 T+ @4 P% |8 @: v+ }! BJava实现链表的完整代码package chapter2.part2;
    + i  Y3 B1 u: @" b) r9 _9 a- h7 i" ?! n
    /**
    + B1 Z$ y" {1 e% p * Created by IntelliJ IDEA.
    " a4 {) y  m6 S. L9 P *
    9 O) E# C* t5 |5 S7 X  Z! P# \; h * @Author: 张志浩  Zhang Zhihao2 V  o0 @& Y8 q" Z
    * @Email: 3382885270@qq.com
    4 E  k; P1 j# I2 b: H6 L2 _; K * @Date: 2020/5/32 E7 \0 P8 b4 T+ K" x0 X
    * @Time: 13:39  j, \- N! x* G
    * @Version: 1.0
    3 J/ u" z0 _6 i) Q. U */2 ~/ X5 N. @0 {& B* ?
    public class MyLinkedList2 {
    ' w2 a( v+ a) H  \6 R    private Node head; //头节点
    % T+ f5 `( C1 _- D0 T; s* n, L    private Node last; //尾节点; L$ q6 T6 M  b% u( l
        private int size; //链表实际长度# U8 D4 y2 ^- P" c4 w# D8 J

    % Q+ W3 ?9 Y! k0 V0 o    public static void main(String[] args) {2 f# u; E; C2 H% t* @
            MyLinkedList2 myLinkedList = new MyLinkedList2();
    7 P/ U3 E! I! J//        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作  E& u& O# T# ?% f3 G9 u
    //        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
    ' V. `7 z' X7 Z9 q        myLinkedList.insert(0, 3);8 ]/ i1 G% C3 T& [2 S
            myLinkedList.insert(1, 7);& Z" Q, X4 X  r/ p
            myLinkedList.insert(2, 9);
    ; S6 I2 _) u: a# `9 \2 e        myLinkedList.insert(3, 5);- M7 S9 Y" w2 p
            myLinkedList.insert(1, 6);  `, F* X$ ]  V
            myLinkedList.remove(0);( ^9 h) @& T+ K3 b6 m7 n; q
            myLinkedList.set(0, 23);
    : k* Q9 W. k5 l9 J' D4 T        myLinkedList.output();
    0 S7 _0 p/ G2 ?) }% [/ w7 |    }
    5 Z1 S8 d% y8 }/ o& u, ]' \, t1 `) C. t) M1 m- B
        /**1 H( e, f0 l! B5 _) G1 J3 i$ J3 c! }
         * 链表插入元素" X' h; ^' O+ q
         ** s8 `& y6 Y+ U) O) y0 Q9 V$ k, g
         * @param index 插入位置% b1 n1 D5 M# W7 L) K/ l9 T
         * @param data  插入元素 被插入的链表节点的数据2 E0 ]2 R! d7 B0 j5 E
         */. b7 f( g: C9 G! C4 w$ {
        public void insert(int index, int data) {$ W- d8 s0 c2 N
            if (index < 0 || index > size) {
    4 E1 }9 l9 S7 C& [' w8 `            throw new IndexOutOfBoundsException("超出链表节点范围!");. k2 U% X+ \/ A& ?
            }! Q5 Q' S6 O6 ^% ~7 F$ P  ?- L
            Node insertedNode = new Node(data);7 b5 k3 W/ W8 E( v) f4 `
            if (size == 0) {
    ; e8 ~3 ]- Z9 G( W6 z/ n            //空链表8 a0 I$ _0 N  T8 O1 \" ^
                head = insertedNode;
    ! t1 {8 m: B. Q2 K; t; U  H            last = insertedNode;7 E4 x  H5 J/ o2 Z, R
            } else if (index == 0) {
    # b4 u2 P/ D: U8 k+ A1 i9 [            //插入头部) C9 K- {: b) @
                insertedNode.next = head;
    ; n; v: k8 {# W* {6 ?/ i# z            head = insertedNode;4 @1 A, u9 q, U5 A6 R
            } else if (size == index) {- V5 ^- {1 D% d& c4 J4 `
                //插入尾部
    & K6 {/ L5 X& c( Z: i8 z            last.next = insertedNode;  F" V: n/ H- g. h9 u* h* J
                last = insertedNode;
    * t2 Q4 Q/ d9 R8 y/ n* g/ f! s# Z( X" i        } else {
    " m! o% A/ \' Q5 g: }2 p            //插入中间/ L5 u. S0 M7 N! C, P0 H9 t3 l
                Node prvNode = get(index - 1);3 m' v9 a8 s2 K7 y  m' t5 |
                insertedNode.next = prvNode.next;/ M3 d- D5 I9 ]# x& {/ w' |) j
                prvNode.next = insertedNode;  ^1 R, C4 c$ L5 h. H' y; _
            }
    0 g* T% W7 Z- W! R3 @& S- Q        size++;
    6 E3 R8 ]) |; G) x5 T  @& ]    }
    5 ]6 v0 ]* X3 V$ o$ F) {4 _' l! t" f7 `8 x
        /**4 }0 y) U7 {) @$ i6 x
         * 链表删除元素+ R1 j1 @: I, e
         *; ]( B& o$ e$ b' _8 e& q# C
         * @param index 删除的位置% J2 V: _: D3 ~3 k
         * @return 被删除的节点
    1 C1 j7 _' x! p  \& R0 e" {' \     */0 [/ t4 |; @! H- j
        public Node remove(int index) {
    $ Q* S6 C: ?. X# q$ {4 p1 F  I1 i        if (index < 0 || index > size) {+ C) A9 T: x0 l. Z# O0 G& O& O6 z
                throw new IndexOutOfBoundsException("超出链表节点范围");5 K7 Y" O2 r& h1 L3 Z
            }
    + U. h. M9 X1 f" w; I6 o; ~% m        Node removeNode;' h& m# w) P  D' }8 K# c
            if (index == 0) {+ {' m' X/ O4 F/ Q; F
                if (size == 0) {( }0 c6 |9 q, N
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");  |2 e. Y  d- w8 b3 U& O
                }
    * d- J. m$ v$ D; ?- J: X            //删除头节点+ h- m7 V, M% U+ g) j3 ]2 K, \
                removeNode = head;
    6 R; U& N+ Y3 P" p! E. x            head = head.next;
    ; \( C$ o1 X8 f9 \6 V' G& `        } else if (index == size - 1) {
    1 T* p0 b1 m( W- v2 G* @6 R            //删除尾节点
      w% b, p  K8 K4 l: f5 k& q3 c+ R            Node preNode = get(index - 1);9 D7 I& g5 b( p8 x' U
                removeNode = preNode.next;
    + o0 {3 x, k# f2 R: ~9 @2 _            preNode.next = null;1 U4 ~0 b# v& Q3 k
                last = preNode;
    * r! ^, `3 N1 p1 ~7 u# G2 e        } else {, V  }5 ]6 e! `+ m- r
                //删除中间节点) Y/ f# [; T" w- F2 P
                Node prevNode = get(index - 1);5 A$ l/ ^/ G3 o" a; U
                removeNode = prevNode.next;
    5 P; [% }6 @2 P* Q4 ?, _: x            prevNode.next = prevNode.next.next;2 p/ [9 L) h; w4 K% ]% L
            }
    . h0 D) e$ x( c9 n; V5 [        size--;# h& R& E! S  @* b% B
            return removeNode;5 m8 E/ W5 h' p/ Z" l; L
        }
    - j; T' g' u) |
    + z8 u9 ~. B0 V/ H    /**- c0 N: B; z$ K7 s+ p5 `* \
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    . `% Q# U+ A' {" z! b     *% C# P7 ]* e/ a# O0 m
         * @param index 需要更新的节点的位置- |1 \6 }+ A) P4 Z+ r
         * @param data  新data
    3 v; S) A/ X5 T! X     * @return 旧data- M; g8 J; Q8 [, a' c
         */+ E( B! a: j4 n! Y8 v
        public int set(int index, int data) {! i7 U2 N% b9 i1 c- U* f
            Node x = get(index);! N3 m- L" _$ Q3 y9 E8 A, k4 B
            int oldVal = x.data;
    - Y; D: ^3 ?  b2 x1 `4 l        x.data = data;( W) H( h1 }, i
            return oldVal;
    % X8 [  j0 Q0 a1 N9 w    }0 q' Z1 S0 S. ~  I* {' F

    9 ^) E. e; D  ^    /**
    # P/ p% m( c& b, y     * 链表查找元素6 k' C- T' b+ l; f+ i2 c6 V! K
         *
    1 S' }/ s; H( y     * @param index 查找的位置. B5 ^2 F7 T( O  @' C: w' K" q
         * @return index位置的Node对象
    + A1 w& Z: O+ L/ J; r     */& X5 `3 A( \# h' L" S8 `( M
        public Node get(int index) {
    + |) @7 M' u8 l2 `4 h" c) e        if (index < 0 || index > size) {' Z, |. {! e# Q. J/ O, _, {
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    1 a; h' i% J& j: P        }
    - s4 \- I" F) J8 M3 }, e        Node temp = head;
    9 N5 H2 I1 d5 Y        for (int i = 0; i < index; i++) {
    - G+ B+ a( U2 m: a! C            temp = temp.next;
    " v8 O0 O4 k, a* l        }
    " X. B. t8 D/ Y        return temp;
    6 w8 F/ E- H, {    }$ C3 N3 ?* K0 y

    . R$ z% d9 K9 w9 |' P    /**+ M! `" m3 a) @+ ]9 R& |" W
         * 输出链表
    * _- _/ s, N/ y$ E/ E* r     */
    $ `8 r" I. M! P    public void output() {
    ' I" W: J9 M9 \& U: o        Node temp = head;
    ; I' X3 E! @+ _" z1 b% ]7 U5 j        while (temp != null) {. R; n9 k) Q9 n! X  @
                System.out.print(temp.data + " ");7 g9 N# D  m, J! U# m9 a* @  y+ |
                temp = temp.next;
    0 Y4 V/ @- Y0 m. `        }7 h) o2 [( D& ?8 E/ h
        }- \4 f2 A1 O! I$ W9 x; x
    # R8 G  |' Y, A3 C3 |% t! L
        /**
    ; v* H3 _6 L1 V, k- Z1 Q4 v# W9 u     * 链表节点8 l6 k7 U; O: e# Q. e
         */7 T: w! Q8 y9 l; M/ f
        class Node {1 \+ G6 B/ h' S( I( h7 h
            int data;. r4 S  h0 E' \; r) l6 A
            Node next;
    9 I+ M* c. f# O  ]+ T% @" L' Q2 x+ A& I+ m+ i: q
            Node(int data) {1 p: b+ K4 Y) ~$ F# L/ C4 U1 i
                this.data = data;
    ( v4 M1 D5 r% A4 a        }
    ) C7 G0 v6 x; P, \) P' g    }! V! W9 n% S6 k9 k
    }3 |3 `: p- J3 S( T2 r! m
    2 y. n$ t- s: [2 \
      I7 x6 H2 u# d  D' z; e& t
    二、双向链表 12.png
    : i8 i+ n* V8 o双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。, n+ V4 a7 u; \  C3 r5 G) G
    $ g% M  f/ ~, n. N# [3 C3 O3 F3 Z
    + _/ d4 p4 s) ~3 q7 E0 b

    7 v& g6 B5 C' K  m' S' Q. I& m
    7 ]. C9 S0 i  z7 z5 f————————————————5 F, E$ v6 G0 r3 i
    版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ( H0 ?2 g0 n! b% c4 z. ^2 E$ O. b原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468( r$ i6 z& T. p; Z, g' A2 |* o

    2 B! G2 ~4 T' y8 l% E8 D
      @8 Q8 G" _' r

    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 08:34 , Processed in 0.500762 second(s), 54 queries .

    回顶部