QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5183|回复: 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
    1 x' A, }/ [9 w9 t' j; c1 [
    【Java演示】什么是链表?数据结构
    2 P7 Q0 Y& e+ ]9 ~& M  |一、单向链表3 {* k) W' r8 f) Y  Q+ z7 j; B

    ; a  Y+ d. c/ A; s4 Z9 Z+ z7 `8 { 1.png & Z, z7 `% ?- i' J  z; L2 T& p
    链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。
    0 Y3 F5 \  T9 {1 J8 Q  L( A. z1 l单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。4 @) |- R6 j% }2 W. R! w# i* s6 |
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。
    # ?/ Q/ y* B: Y/ O: L) c: Q8 N8 y9 v' x" w% D- c
    什么叫随机存储呢?  K" r; F) L9 R) e5 V: L4 X/ {
    3 u  H) V# e0 h6 ], p2 G
    如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
    & z3 [1 D, E' r$ V+ A上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    ' t3 S1 _0 ]  |$ l6 ^$ n9 w: m 3.png
    3 m3 _- _, h: f3 W+ F) \9 S/ _5 U2 L8 d! c9 m/ d5 f8 y( X3 T& _; \+ B; s8 \& \

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

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

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

    4.png
    # ]* h& I8 J) E
    ' s! ]: ~7 e* @/ h/**4 i9 Q+ Q9 v) A, ~7 t
         * 链表查找元素
    " G) m0 _2 N# h4 u3 d. U     *
    , m2 g  M  U6 {     * @param index 查找的位置7 ]/ T3 m$ e7 v- `- D1 U
         * @return index位置的Node对象
    0 ]- @7 W% H; Z9 T+ i! h3 X, w3 o% k     */# n; ]5 R, a1 {) `! E- |( `3 F
        public Node get(int index) {
    * G' _# v, l: u- \+ U" ]  Y9 X- }9 z5 L        if (index < 0 || index > size) {* F8 D3 Y/ Y& D
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");6 |1 ]+ `# s! e' e! B5 _
            }- s5 V) p( J* @
            Node temp = head;6 F9 t7 g3 g* Q" \) [+ j
            for (int i = 0; i < index; i++) {; I8 F8 g' n) F! _6 e+ ]$ j0 k
                temp = temp.next;
    ; S, F, y/ o4 b* D) O* m2 Y        }1 @  v% e& |$ W  F
            return temp;4 w* D, e! X. u4 g
        }
      F5 M  r6 z7 E3 {' ~
    ) {, B5 @2 h% m% ~, F& v

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

    2. 更新节点 5.png ; t" q# v# n8 u0 N% X2 q3 F
    3 W; E+ G* P, K% [* d4 s2 _
    如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    / @. i& R8 K. \0 F如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)2 t( B9 R+ E, G5 b: I8 q# r+ o
    /**
    ( @+ |) X9 i2 }3 H8 r" k) }     * 更新节点 将列表中指定位置的节点的data替换为指定的data。/ L$ Z) c  G( S
         *# \+ Y2 [" m' Y  s; \5 n
         * @param index 需要更新的节点的位置) s1 m% e2 t5 A+ q+ Z7 m( d0 m
         * @param data  新data
    ' K: D  t& Z4 z, ^  a     * @return 旧data
    5 z. g( ~3 q$ |$ y$ y     */
    ( m+ Q+ s7 `" |( G    public int set(int index, int data) {: j. A" `; O' d% \, z# i3 ?# e. w
            Node x = get(index);
    ; h5 `8 c, V: z4 o        int oldVal = x.data;
    ; O# M) ]+ ]5 b+ h% S8 P& A0 e7 V' D        x.data = data;/ Q- H! b/ R) I' j' V; C
            return oldVal;
    0 k. e: p5 t9 X" E- S3 G- N    }& L1 D% y4 f8 y( X/ U

    5 L5 v' B: r: L% M; W' U# |3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入
      / G) e& ^0 H9 e% R" a+ N
    3.1. 尾部插入

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

    - \4 F+ g: i- V  k- f  L4 _
    6.png
    . i9 f4 v4 h1 [+ {2 Q! C) J3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。
        J( Z1 @% C  u" L- d
    7.png 3 Q( q  f8 I: A3 {4 T1 t

    6 R" s0 q$ ~/ t1 j! Q' n3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。
      2 G9 y( l& L5 v: U! P0 Z
    8.png
    - ]# R4 W7 |/ g$ k
    2 ?! w# X& |+ s1 w) @$ I8 q) n三钟情况的代码合到一起
    7 p% H3 G1 p$ Y4 {0 \" S1 S% h* g4 d2 w8 ]; Q2 E8 @
    /**; X9 t) d, T* S
         * 链表插入元素( }! ^' S5 F% i& A3 `. j( r' J* k1 S
         *
    ! r4 t8 ~2 D0 L3 X& x     * @param index 插入位置0 Y" M2 q# B6 H+ ^6 P
         * @param data  插入元素 被插入的链表节点的数据2 e$ f% y9 l3 F' N# o1 n- B
         */
    % G: A5 g' E% U- _  [0 @5 E/ ]: b    public void insert(int index, int data) {2 i$ W; H6 U0 B0 }$ y( v
            if (index < 0 || index > size) {
    ! Q) f( f: x# L( T            throw new IndexOutOfBoundsException("超出链表节点范围!");/ D; ]; g6 G5 g0 `1 g( J9 t" @0 Q0 C
            }! a. t. ?) ^' [: e8 m: h. H# k
            Node insertedNode = new Node(data);
    7 a5 Z, z; F2 t4 B# H9 ^        if (size == 0) {
    ( Z$ G+ t* K/ i# y            //空链表
    6 ~, }) V# H; K# g- K            head = insertedNode;3 C9 Z& V+ n" p& ^$ ~
                last = insertedNode;6 T+ @9 k8 j7 ^5 G* O; ~
            } else if (index == 0) {
    ' g% t. u8 X* L            //插入头部
    3 k) o. x, t! u$ X& p! \3 T            insertedNode.next = head;
    . z' h/ w6 B* T; a- t  O            head = insertedNode;
    9 p1 b+ |9 E7 l. j6 ~3 T        } else if (size == index) {
    : o$ q/ `. Z% A& V* s+ `            //插入尾部
    8 w7 L4 S  \; r: C% u  n9 |: s            last.next = insertedNode;
    1 r; f+ a% X) U% v) r            last = insertedNode;
    0 V2 Z( b' y! U; W6 E9 [0 `  X* F        } else {
    0 [. E7 \- m8 A6 v            //插入中间
    ; ^& X" c# U$ H% I            Node prvNode = get(index - 1);' N+ E, h3 J9 N- {8 W
                insertedNode.next = prvNode.next;
    2 F2 d& T! J9 M" k/ B  H5 H            prvNode.next = insertedNode;# }7 _" A+ d0 {  X' n9 z
            }' ?) w2 T- A. O, Z8 [1 \( V
            size++;
    . s9 ?3 [( D# p, ^/ o& ~. m4 _    }$ d* F& d. f, ?. V9 A, n- L2 u
    6 N2 E) l' U! W# r6 t
    /**
    6 a2 K0 _  P" U. A0 H/ S  P8 Y! T6 s+ u     * 链表插入元素
    1 B0 Z2 L* P7 W7 Z; _+ |     *
    ; I4 j' B! O7 e7 f- U" Z# a     * @param index 插入位置/ F2 x3 C# `6 L; \1 a& K
         * @param data  插入元素 被插入的链表节点的数据  M% B+ c. g0 p9 ^
         */# K3 x( D0 j+ ?4 x$ A* C
        public void insert(int index, int data) {
    5 d/ }' w$ O' \& B# J        if (index < 0 || index > size) {; \5 L1 b) e& L9 E1 ~7 q
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    # P; Q8 {7 o7 ~' j) |% b- l/ j' m        }
      b5 a: n3 m; K$ ~        Node insertedNode = new Node(data);" ]& ?' }( J5 Y4 G3 i1 ?/ ]8 q- W
            if (size == 0) {
    2 {# Y3 s4 T! D            //空链表
    3 _) _% ^. T. A) ]' {7 T2 R            head = insertedNode;: ]1 Z7 W% w6 W7 x
                last = insertedNode;1 c8 v3 x1 r; T! p8 e
            } else if (index == 0) {- @6 I+ Y! h( z# b  M5 n
                //插入头部
    1 C% b! {- G4 [0 }5 Y            insertedNode.next = head;+ X/ v* D( v2 o* _3 q
                head = insertedNode;
    ) E5 P# w; Z1 \" g        } else if (size == index) {
    : H& N. J: Y2 G9 A1 E3 g            //插入尾部
    4 ], Z' l, x) [  y3 F            last.next = insertedNode;* P5 Z9 Q7 p: B. c2 \/ R& d8 B
                last = insertedNode;
    3 H4 y* i) }& Y( \- T1 g3 e        } else {
      w. z, f' Z& W            //插入中间1 W8 N) j$ e+ [
                Node prvNode = get(index - 1);% a4 K" Y( r& r4 e4 x: n# o
                insertedNode.next = prvNode.next;
    ( \) a+ T* g3 I8 f            prvNode.next = insertedNode;
    + w; [2 [# H! H. x- C% v/ D        }
    5 f& `6 O: [. ^1 l% k4 s1 o. W8 o        size++;
    * k4 K/ `9 p) c) O% i1 V    }  }4 n8 w; u) x8 i' x6 b+ X8 h
    4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除( e" d5 |5 E! A! S& n
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即8 Q7 I: P( v. `
    可。

    9.png ( E# E! Y7 N. P1 [

    / W/ c% v2 e5 `- p. n- D* H0 W( ?4.1. 头部删除

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

    10.png
    * {. X! `6 J2 Y
    / L* S3 ?2 O3 R- d, A* n8 ^4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要" Y" [+ H) V. P5 y
    删除元素的下一个节点即可。

    11.png 5 c! \' J7 p- W: \9 B' n+ Q
    2 i/ A; D" Z+ y5 M, {, s
    2 B) K% |. ^5 E9 H2 M
    这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。4 {& B( U, F3 L+ W6 B
    如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)8 ?# j" x" q, D# i$ q7 k
    /**- s9 H/ N3 n, h( }5 x7 h& t+ F; e
         * 链表删除元素
    ' G* x- k7 X# v$ |8 w( l/ {     *
    ! B$ f4 K' j7 D" G  l     * @param index 删除的位置
    # M# O9 \, `; X  P$ k4 r( H0 |$ q     * @return 被删除的节点
    ' C6 ]# u3 Q1 q. d     */
    ' I% u2 u; F% z1 @' }    public Node remove(int index) {
    4 M  a  t& n" x        if (index < 0 || index > size) {
    5 q9 |' w4 \& ~& m4 n            throw new IndexOutOfBoundsException("超出链表节点范围");) b- t" `* X3 K1 k) n
            }
    + {7 D* I) ~, g" h* n        Node removeNode;
    , R8 v& H! w/ e0 t% G4 a3 g        if (index == 0) {. F3 T' w6 ^4 ]- N8 o8 w
                if (size == 0) {
    9 i' C0 _, M% G+ s; x                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    6 k4 a9 p6 u8 k: \% C( P; U( C            }
    1 B- ]0 j$ P& L+ m6 @4 g            //删除头节点
    9 t1 X; Z: o' L* l            removeNode = head;
    ( @/ Q  g0 S: a: N" k: U. H' f            head = head.next;8 y) D8 Y' V, X7 p
            } else if (index == size - 1) {" k2 h4 Z8 V3 E' o
                //删除尾节点
    4 O- ?0 |& P8 c7 \/ u. Q  e) _            Node preNode = get(index - 1);
    7 T& R( p! Z8 a5 m# B            removeNode = preNode.next;2 I. b6 M9 W4 y1 p+ w; B
                preNode.next = null;; {0 _$ P2 K) g  `
                last = preNode;" S$ t* i* g9 y9 W$ K. F8 F& c( S$ C
            } else {, r# A2 C/ S- ]: N( T; u
                //删除中间节点
    ' {' }& v/ s- j  L            Node prevNode = get(index - 1);$ G) R: ~* l! T: U- E2 g
                removeNode = prevNode.next;) Q3 t8 d+ G. r
                prevNode.next = prevNode.next.next;: M) R- e- z; n% `1 d# H
            }3 S) N+ E8 `8 }  p
            size--;- P3 S/ i8 C/ _
            return removeNode;
    & R% W0 C0 S+ S$ W9 I6 K: q9 l    }
      e- I: U! q( h+ TJava实现链表的完整代码package chapter2.part2;0 V! R: u5 E% I9 ^' V5 k$ B6 G' D' W% V3 c
    ) N7 j+ R5 B9 m; L% p0 x) j
    /**
    ; a. `; q4 b- ]8 n6 v/ b * Created by IntelliJ IDEA.: h) }" Y' t, Y  |7 a
    *& W/ D" Q5 Z- L7 k
    * @Author: 张志浩  Zhang Zhihao! ]$ H9 ^& I" |( ^: E
    * @Email: 3382885270@qq.com9 w% h$ a* ]8 B2 a  c- E) g3 s- B
    * @Date: 2020/5/3/ |# {# u3 m* Q; ]+ V" L& {- r
    * @Time: 13:39
    * |- z2 o# K: C$ S2 c+ j * @Version: 1.0$ q- D4 y$ X. H* s1 r
    */: ]) r# m" D4 d. {" \( v" t& Y
    public class MyLinkedList2 {
    0 n! n% j1 X2 g+ q, @" v! ]    private Node head; //头节点
    $ i+ |8 w$ P# a- O& A    private Node last; //尾节点
    , s4 U: S+ W7 X    private int size; //链表实际长度
    + _9 {3 ]7 X2 w, R0 z8 V( i2 x
    ( `) L8 c: t: i) }$ x    public static void main(String[] args) {% L% n4 P- g( C+ C2 ?! F6 b
            MyLinkedList2 myLinkedList = new MyLinkedList2();
    * p0 t( M' R7 L; p//        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作; e  p& u  m8 `" t  Z
    //        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
    ; n8 s- r: e$ |; K9 E1 w        myLinkedList.insert(0, 3);  i. g7 Q5 F, f7 ?+ X8 q
            myLinkedList.insert(1, 7);
      e1 z$ ^1 |# u: a, Y  G        myLinkedList.insert(2, 9);# ]* A$ d$ h7 {( {
            myLinkedList.insert(3, 5);/ {( S6 j0 t8 i; u) ]$ H5 {
            myLinkedList.insert(1, 6);
    5 Y) J; r1 \& v' d7 ^        myLinkedList.remove(0);
    - U+ E" Q; T2 X        myLinkedList.set(0, 23);
    4 C, e: S% P9 u! p, y6 P        myLinkedList.output();
    % e; g) M3 H" f5 ?    }- w- r- L* o3 P  F

    3 s4 n) b. c& A    /**
    2 Q, L9 r5 L" \) }+ Q     * 链表插入元素+ S4 @6 i/ ~  j, C! k$ B% F( u. F
         *
    5 W* `: ]  P' s% m     * @param index 插入位置
    : X2 B* f2 p' Y* e- I& g$ M9 ?     * @param data  插入元素 被插入的链表节点的数据
    ; X' s- S/ d6 `& z* `     */
    8 N; u+ ^# B  x6 L    public void insert(int index, int data) {
    7 {' T' c2 Q: v' |3 i8 m        if (index < 0 || index > size) {* D: M9 a" ?& E$ _$ n/ P, w
                throw new IndexOutOfBoundsException("超出链表节点范围!");. }2 b$ x' j; _/ J0 d+ C( S, d, C
            }% ^! x0 L% U% a+ m' k+ \5 ]# {
            Node insertedNode = new Node(data);) g; d$ ?7 X6 P8 M: t/ ^
            if (size == 0) {0 k  Q" o& C& v; l0 ~- |( p# y- `
                //空链表
    8 z$ N5 K- J+ z5 {: g3 c2 @0 l            head = insertedNode;
    + f, i5 [6 m& V            last = insertedNode;( A3 L4 X1 P+ O/ h( D/ t9 C
            } else if (index == 0) {
    . p: T2 J/ G3 u5 K3 X, r            //插入头部. S9 g, V2 `/ |3 a6 J
                insertedNode.next = head;' b" Y/ `' V. O$ u" i4 M+ I
                head = insertedNode;, p# V9 i( g: D; W
            } else if (size == index) {1 L4 q/ L; j) d& M& g) y2 Y
                //插入尾部
    * c' S. w! ~8 u# ]0 Q            last.next = insertedNode;
    / Y/ S. j* p4 Y            last = insertedNode;4 t5 B$ J2 O+ u3 W" R3 E5 s
            } else {
    + o1 T& F1 z  o            //插入中间
    2 ?/ O5 M+ q, A            Node prvNode = get(index - 1);' e2 ~1 l7 k2 b7 {
                insertedNode.next = prvNode.next;
      _8 _8 O& N9 b3 m/ ?; S; d            prvNode.next = insertedNode;+ ^* g7 F& C' j5 m' Z) [8 m$ ?7 ^) @
            }
    # ^4 s2 L" O7 M- u2 @7 t' D        size++;
    / J3 Z5 w' t: |8 F/ R3 v6 R$ g    }
    " W8 B* |$ l1 |
    : h' g: x+ L4 ?/ T2 f; ^! ~    /**4 p! }& k/ ^1 ]7 U
         * 链表删除元素% L- L( q; C( S7 X0 N7 R% d
         *
    ; [6 y# T4 J. ~8 X4 B' q% U. J     * @param index 删除的位置
    . c, E, s7 f% z9 c: \     * @return 被删除的节点! ^* w! V7 l* P+ n# V
         */
    # Q9 ]9 z! c) @8 D- T  i9 B0 e    public Node remove(int index) {
    / [% W8 Y6 ~$ {2 f) e* }        if (index < 0 || index > size) {
    . U# y( g( A" Z7 X2 W  P            throw new IndexOutOfBoundsException("超出链表节点范围");# r& e- z  C% O' }
            }5 M* l# \1 E9 t* V; r2 d
            Node removeNode;
    " }' S2 [; F3 h' x5 \( D; [        if (index == 0) {) b! c9 V# c  O# N) k# g
                if (size == 0) {
    : M6 k; I9 J! n+ x/ M2 X& H% L                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    $ e' [. W) C6 E            }% z+ q' D3 Z$ Q' Y, L  W
                //删除头节点& E# d7 i# p$ {6 m: I* w% D* \
                removeNode = head;" S$ R* K* W9 p4 Y9 y% Z8 P1 ^
                head = head.next;
    ' I, t+ c$ Q0 T$ {+ F3 L$ s        } else if (index == size - 1) {
    * q) Z5 v2 [; D' Y* S; I! \            //删除尾节点) G$ ?2 M" c: }+ j
                Node preNode = get(index - 1);
    # L" M& P' n( O            removeNode = preNode.next;& }( l  t. {2 H( q. ~4 \/ V
                preNode.next = null;
    " v$ S2 @- l" k4 v& ?2 O$ r2 K            last = preNode;' y) r3 m/ w4 d9 r
            } else {
    $ A/ w5 [5 ]6 P5 Z9 t" ^            //删除中间节点- b9 t2 H7 g' e: N
                Node prevNode = get(index - 1);
    0 W) c% I& a9 |  ]% P# {            removeNode = prevNode.next;
    . }2 @# N$ p8 D7 B) f7 p2 E, p, }0 W            prevNode.next = prevNode.next.next;+ r4 d( f. \  J7 E
            }# ^( P% Z3 u" K: n
            size--;
    ! g/ ]% W) J' D' {        return removeNode;
    2 T' V0 p% z' ]( W) j% _    }
    / z+ Y' y8 Q% m; M9 E% b
    " j5 f/ t' _' p9 n. q% l    /**' t( {- u7 A" ^# F5 h2 S  J
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    - S  u9 s' }4 y, T     *6 O4 G+ m; l% H# P! c
         * @param index 需要更新的节点的位置
    + b) o: E2 S5 {6 A% T     * @param data  新data
    8 Y' d  `$ z/ x3 R* |     * @return 旧data
    9 R/ w; z+ @# F% l     */1 ^/ f* T& O  a% U8 F' T1 l7 Z
        public int set(int index, int data) {4 ~4 Z; k: _1 R3 V9 B
            Node x = get(index);4 N: H- m* }$ `+ |3 ~" X5 k: @
            int oldVal = x.data;
    5 z0 M& T9 ~4 F5 n/ B        x.data = data;
    3 m- e2 k0 R0 h# \2 v2 {        return oldVal;5 f9 @1 z6 b1 o1 a4 |4 J" ~  W5 p
        }
      z3 Z  F  C0 `. r% N, M. m5 `. P) h" t6 p/ U! ]6 r- k
        /**$ p' U0 a0 h& }" y2 M/ m
         * 链表查找元素" k8 d+ D5 X0 g+ ], D
         *2 x0 x8 B9 W) L( Q
         * @param index 查找的位置
    2 N. Y6 l" k, v2 ~$ T     * @return index位置的Node对象3 T/ ^  C& d9 |2 q
         */
    ( t, c4 `$ }( T4 x% _- }  k    public Node get(int index) {
    " P* Z4 O0 j! u+ c; J/ K" M1 `0 [        if (index < 0 || index > size) {: e' b0 a9 r: k% p8 @
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");7 l0 ]- c7 Q: `2 ]0 [
            }/ Z+ @; k# M4 s/ u
            Node temp = head;
    " }! I9 x7 I+ T" Q        for (int i = 0; i < index; i++) {
    ' p- f  K% v3 T9 v0 w0 O            temp = temp.next;
    9 E- ^) y* X+ ?( W! {        }4 m% g% ?. Z( e9 t5 R3 x  ]
            return temp;
    * X4 w" ~: r9 j% M5 x2 d    }
    : A/ h% j+ \: X0 E4 |
    $ m( s+ i2 L: ^, @3 J5 T: e    /**
    ; R3 e2 M" `. @. w* h! C* k     * 输出链表
    9 E- C* I, ]2 ?* m  F     */
    8 Q9 e7 ~  ?# i: C    public void output() {0 s  L- b. d. o& j( \
            Node temp = head;6 B7 o+ g- t' m9 ~  |% f3 W" J- c% i: @
            while (temp != null) {
    : D! G6 K- s; W            System.out.print(temp.data + " ");
    - ]& K$ [: E3 a6 Y            temp = temp.next;1 k9 L" o1 {% D" L
            }# O1 G( y) t; b1 S8 R5 ]
        }
    2 T) `' N9 a0 W/ ~; i, v+ e( X* X. ]
        /**0 ]' X8 G; |! [6 L9 o
         * 链表节点
    1 d- o5 c7 u" `- b     */
    9 H7 T; P0 k3 B9 Y8 z    class Node {5 A, E& {4 F0 w+ y0 F7 O( j5 U
            int data;5 d" u- Y" o# A& L' M
            Node next;4 E: N% g$ |. m) U0 {

    6 S2 t0 U: @6 k# W+ _, E0 Z        Node(int data) {
    2 o4 \# W/ `- L+ g: a  Q            this.data = data;! }/ q4 ~& I2 [
            }0 a  v3 y; @. w" [5 I8 c6 v) T* w
        }
    $ x* E7 v+ F: K" C5 j+ b. k& Z}) V) ?5 F5 d& b
    : Q% M9 o4 f6 f* W6 ]8 ~
    , Y% N8 o. D( y3 M- a2 ?
    二、双向链表 12.png ! E6 }( C( T5 S: X2 Z' @
    双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。. ^5 I6 e: G1 y* G
    : c* p3 W: ?% R: u0 D& V' q

    # L$ }. x& W2 Q  W% g- |7 D$ c
    8 b5 @' Q! u2 m  E9 h5 d1 ^; L  A8 p. Z( ?0 f, B+ z
    ————————————————5 ^6 d3 T$ A4 i  j
    版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    & f7 N9 B3 @% Y# k* d' |1 Y原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468
    # b" J# h1 X, O
    : V1 c  O3 P: h. v
    9 z% T: s( X- j

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

    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-6-12 00:10 , Processed in 0.454140 second(s), 54 queries .

    回顶部