QQ登录

只需要一步,快速开始

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

    8 P$ @+ K& ]) r- l2 \0 a【Java演示】什么是链表?数据结构; W+ M9 \* |9 G
    一、单向链表
      ]  {( l; s8 L' R3 A8 I
    0 I- A% o) `& C, i/ b, y, h 1.png ; m! m: m) ?7 g$ M: @  T8 a% s
    链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。7 Y4 Z: t8 e- N7 c) o$ B; f+ u  S0 c
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。
    ' I- Q% T5 c9 x5 ]8 t3 w: C链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。% M, b% r! u0 w6 e4 m/ N
      B/ F9 Q: A( p; R+ t  Y' S
    什么叫随机存储呢?, {  F% B# H3 [. X! x
    0 n2 N) s# I, j% n0 c5 J
    如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
    1 ^; j. O. d, |3 T' v8 m5 F- U上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。+ y7 g# b  V& }& v  N% E4 \
    3.png 5 C. d9 z8 A% f9 ^" f( ~' _

    8 D$ Y- e( [. y9 I4 E6 Z$ w8 ~

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

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

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

    4.png
    , P6 T6 |* Y3 b7 y+ ], ]9 r) q' n2 ^" X4 S9 h1 A5 i
    /**, t& o1 Y" {* Y7 X. H, x: M7 |3 w# x
         * 链表查找元素* ]2 ^, K  |5 V
         *' N, o3 _: t( I( q
         * @param index 查找的位置( F( S: g1 p' s/ ~* k
         * @return index位置的Node对象
    ; t* C2 a7 w. r  b3 y  r0 w     */8 {) o; Q  ?& `/ g: b. F
        public Node get(int index) {- r3 y1 U; @# b  u, E( Q9 \8 g
            if (index < 0 || index > size) {( _( _/ \  n1 Q, Y7 J) \' }
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");2 E3 K5 X8 o% I
            }
    ) m; H( T1 J' w        Node temp = head;( L4 \# D1 j9 H1 x
            for (int i = 0; i < index; i++) {: }: W) r% a+ J- D2 o1 v
                temp = temp.next;* L* C& ]3 ~7 J) d! l" J+ p4 }, j
            }! p3 ?% k, d/ }' ^1 G# I
            return temp;
    8 E+ L6 }& M9 }. j    }
    ( V8 u  N+ K& l1 X4 h6 n9 u( U/ s8 c' ~  y

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

    2. 更新节点 5.png 3 i$ w7 ]  i" c& j" @% ?3 F5 u4 R
    9 v* @0 d. o" H& |8 v5 C6 Q0 z
    如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。! {7 M3 W2 s  d" y6 l( O: |
    如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)* I, U) t8 A$ A  k+ \+ S/ p  g
    /**
    . v7 a* g5 v2 `6 r  k. A5 f     * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    % _, J2 I& s9 \2 c+ K+ t6 f/ Z7 c     *
    / p' n& w0 y1 L2 J! P     * @param index 需要更新的节点的位置
    : S7 f  J$ |$ W2 C9 v+ t     * @param data  新data
    ! z: _: s# S: c8 S; _' z     * @return 旧data" e4 e2 v- w7 {& G: X; `0 m
         */, D$ e3 z% r9 e* K
        public int set(int index, int data) {
    4 \% Y9 G5 _5 |( }8 p' O8 d6 ?. x        Node x = get(index);
    5 f; c$ n0 w; z$ Z6 R% ^+ a$ R# Z& U        int oldVal = x.data;! n& s- G. o% n
            x.data = data;
    6 M( V" E  l8 _# V$ ]; e        return oldVal;6 K: @2 g7 u; c6 P/ D" h
        }
    6 S6 F( a- y3 [- }) p9 c1 Z# }
    * S7 u! R- ^  q8 {& K4 c7 A3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入
      . v* Z2 v9 v3 n9 M
    3.1. 尾部插入

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

    % }1 I! j7 z8 h% G' _2 ?4 e, G
    6.png $ S- h5 D( E, ]. T2 l/ R
    3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。
      5 N5 I6 x- m# N/ @1 W
    7.png 5 k: ^! `, D: v+ d1 M7 R3 @' G- ~) X

    0 O; _/ [6 U( c% G. p, Q, F3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。4 B5 [3 H$ u. U: W% c, {
    8.png
    0 V/ l) `$ p2 T* M3 w# z% @" ]$ j& _. n( }
    三钟情况的代码合到一起
    7 _6 P0 O( t0 u- F+ N9 `6 a( s
    $ s) T# \9 a" @- d4 k% C/**
    ! U' C. I/ x$ C3 ~% N, x     * 链表插入元素
    ) [& h2 f! {1 t4 _; U6 F     *2 f3 t# v& r* t* u; k7 ^
         * @param index 插入位置' O. ^& E% x- l( a' S! V/ M
         * @param data  插入元素 被插入的链表节点的数据# c' y: m" {, B
         */
    , m+ |) e' L% C% {6 l- M1 U) s0 U& L    public void insert(int index, int data) {$ G6 l2 W, l/ ~! ?3 q, [9 |! f
            if (index < 0 || index > size) {
    4 X* k6 t+ \* J3 T/ N* S& C8 T            throw new IndexOutOfBoundsException("超出链表节点范围!");5 o1 V/ n# `$ E
            }0 K; p" k# L8 s( t" Q
            Node insertedNode = new Node(data);
    5 b9 G9 _$ Y- ?! E' j+ f9 F        if (size == 0) {
    # y) }  K0 }8 u, t* ^            //空链表
    # Y0 S: E* r, U            head = insertedNode;
    ; z. U5 p+ B; k: W            last = insertedNode;/ k0 c4 V8 f) L
            } else if (index == 0) {
    9 o% P& W( Z# a) j  T3 L            //插入头部
    0 \) V1 t* r2 \) w            insertedNode.next = head;, s! e, b3 w, s# s" @" V5 r
                head = insertedNode;
    , M/ ~( h' D8 @        } else if (size == index) {
    7 c/ l' ?* E8 Z& O            //插入尾部$ V$ u+ w3 O7 U% t6 T. m5 d
                last.next = insertedNode;3 C$ ?  a2 w' P1 F& V, Q( _
                last = insertedNode;8 }1 M. N4 l) r
            } else {  N8 D+ q  h1 |1 Q5 f( k! s4 {9 z
                //插入中间
    5 M# q/ B4 x) n# m$ |            Node prvNode = get(index - 1);
    9 f% Y( z4 E' q0 {7 Z            insertedNode.next = prvNode.next;' v1 @) Y0 b4 E5 Q) ^# }! t
                prvNode.next = insertedNode;( Z, b: w1 m$ @. a  `: _
            }
    - j& _2 ]! q6 I3 `# D( [" D' Q- Y        size++;' q5 {+ b4 A- b# Q2 ?
        }: H6 Z0 f" F4 S2 j( d' h; w

    ! \& c2 A/ e$ O! ^( k7 G2 ]/**
    8 S7 A! \( ]+ p- ]     * 链表插入元素
    ) }! _4 v0 V( p, B- D     *) F$ @' e; @/ G9 @% W7 l
         * @param index 插入位置
    " |) x1 F4 e. T& i5 m     * @param data  插入元素 被插入的链表节点的数据
    ) m) x$ R( E, C' S6 G     */
    0 v8 C" T4 ]$ t8 J- X& f: `    public void insert(int index, int data) {. ?9 X" I2 o+ ]  A
            if (index < 0 || index > size) {3 d3 M! A2 r' q! Q; r9 N8 J( m
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    / Q5 I3 h8 I+ y- L, I, \        }3 L& m  w, s' p. u1 Z. v" _
            Node insertedNode = new Node(data);
    . u5 x$ V$ T& Q. v5 e8 y8 b        if (size == 0) {
    7 r' ~$ Y2 @( v            //空链表- `6 ^# u/ b2 t, m6 w, H
                head = insertedNode;7 E5 o" C: F. j% A5 V5 I
                last = insertedNode;: B" P% F# P2 r$ n/ D# b
            } else if (index == 0) {, p& B. v" D; a. q0 l/ ~
                //插入头部7 B* J3 i, I7 i9 [- F- [( X
                insertedNode.next = head;0 U# n( d4 K. U/ ?, p' m6 o
                head = insertedNode;7 l) }5 ]  x! o" \' x8 L; O
            } else if (size == index) {
    # ~5 E1 |" }1 `; b            //插入尾部8 F3 U- Y5 f) g7 c3 o
                last.next = insertedNode;9 ]' S4 c  o" y
                last = insertedNode;  c( s% w* t" i3 g, \, h
            } else {' a) O5 r$ f5 l) w" c
                //插入中间3 [+ u, p/ S- z2 s  q2 N! V  E1 ~7 v
                Node prvNode = get(index - 1);/ @' [& g9 M8 G5 m
                insertedNode.next = prvNode.next;
    / I. Z# d/ r5 }5 t1 N$ Q9 l9 e) f0 \            prvNode.next = insertedNode;
      ~% ~/ u2 R/ |# V        }. \! w. b+ a$ i9 P
            size++;
    3 N3 T. W. h  g$ W8 m( s% O4 l6 U    }) k/ d* }( S# R; n+ X% A8 P
    4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除
      : c( {- I! J- X2 H
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即: Y5 ]+ r% C7 H* w
    可。

    9.png
    & q/ z& O1 v  _3 D
    2 j0 ?, h: A. N5 Z! ^9 f6 g4.1. 头部删除

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

    10.png
    - u; q6 d( o5 L# N9 ~+ G2 B
    9 T6 {$ p" n" w" ?% z4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要
    ; |! G' j; B) T' Y8 t$ p7 e: e删除元素的下一个节点即可。

    11.png
    2 \- |" y1 x5 d8 C, ]2 |  d7 _* J- r$ I# z7 ]6 ?/ i' \+ ]
      z5 v3 z* f$ V) q3 i1 `( x" M& C
    这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。8 a  ]1 A6 u* F3 C, K5 a
    如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)- u( I3 W" J" r1 q5 \$ c
    /**
    * d9 h- E$ Z( K) p/ U     * 链表删除元素, ]0 O: x9 ~# X6 |2 Z
         *+ x  c( g8 t! g1 Z9 t, r0 _6 t! d
         * @param index 删除的位置
    0 e/ ~: d. N, {, k6 E7 S' d     * @return 被删除的节点
    , @" L2 H( J/ s- a: S. U     */, p  I% v% J/ n/ C- G! Z2 I$ p6 j
        public Node remove(int index) {
    3 V7 C. q2 l" f5 y; t$ p3 L- |( ~0 O        if (index < 0 || index > size) {
    4 ~% R0 H. e, G! c0 a( s/ n            throw new IndexOutOfBoundsException("超出链表节点范围");  J5 Q3 z4 M: A
            }
    * g4 r8 R; ^9 @% o* a        Node removeNode;
    8 j& D% _2 B( P+ A) B4 I& n        if (index == 0) {
      u) p; _  H" w5 B! R' q0 }            if (size == 0) {
    : }+ G2 D4 v1 d! q5 z$ ~                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    . I: w% l( L8 K& Y            }
    " e) a+ ~, N+ N" b            //删除头节点7 j  ~* ^+ M+ ~, u+ j& U
                removeNode = head;: c' u$ p+ Y0 s# N  ^. f
                head = head.next;
    1 |8 ?9 l2 S$ ?  m: R7 V% n1 z7 C7 r        } else if (index == size - 1) {. {$ l! e1 Q# [$ ?5 N
                //删除尾节点
    . V4 [( Z+ Y' q+ o6 V# c            Node preNode = get(index - 1);
    4 e. Q* A: ]/ m9 y' ?8 ~: R: Z4 b& x            removeNode = preNode.next;
    9 X6 a: F! o- m. G            preNode.next = null;0 {% Z# Y2 @% B# S
                last = preNode;" p+ V* m/ r0 R& Q5 X
            } else {
    9 _2 F. X: q. q1 K! s2 S            //删除中间节点
    $ W1 d; y' Z, X3 y; j# N            Node prevNode = get(index - 1);8 v# I/ D$ j+ v( \! y( K, D
                removeNode = prevNode.next;
    , S  M8 J" i5 |0 p! L& `" v; E) }1 S            prevNode.next = prevNode.next.next;
    3 A' [$ W% m  V( M2 f        }
    $ Q) z# S) J* S        size--;& k; Q% ]' Q! i- Y, I% i9 |% I
            return removeNode;% y  l4 I, i) i! B
        }
    - R& S. A- y5 y) A1 tJava实现链表的完整代码package chapter2.part2;9 J$ R5 z+ d+ R6 F( c& I

      f- s& ?1 U" W4 g, h+ G2 z. z/**
    9 t% w; X/ T' h; n9 n * Created by IntelliJ IDEA.
    9 z/ |) q6 q! a6 b *# _; ?; x" \4 [( h$ `
    * @Author: 张志浩  Zhang Zhihao
    2 j3 B% G  E3 N) X0 u* T: o% W * @Email: 3382885270@qq.com& W1 C6 F  |* |
    * @Date: 2020/5/3# I5 e) t! e+ N4 {6 [# a: n. H
    * @Time: 13:39
    & z, h6 v+ T) w: Y * @Version: 1.0  q8 U: U% G! x* x4 f
    */% e  W6 g8 j* R% A  o- v/ X$ w
    public class MyLinkedList2 {
    ) p! ]. I! L, A4 Z    private Node head; //头节点; [! c  J) i' y3 y# P* f& K5 I" c- K. ^
        private Node last; //尾节点) j9 o$ S* w% t4 [
        private int size; //链表实际长度. ~7 l7 X5 D/ R! V  [5 u4 l
    + }. d% ^) G' G
        public static void main(String[] args) {
    # b0 }5 R" ~2 s7 J2 B+ b0 |        MyLinkedList2 myLinkedList = new MyLinkedList2();0 i# K, C3 M. m$ Y5 C% i
    //        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作) f! u7 d9 m4 O
    //        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围: P; [& \; M$ k5 F/ T+ H' G
            myLinkedList.insert(0, 3);; }7 s3 O' N( W8 f* ^% \
            myLinkedList.insert(1, 7);/ n- B( n) u! J
            myLinkedList.insert(2, 9);
    & x" b7 N1 M- }, A; c. a4 j        myLinkedList.insert(3, 5);
    0 }9 K. M. W4 m2 H! ~        myLinkedList.insert(1, 6);
    - q6 A4 Z) ^( e2 C. f0 I( ~2 K        myLinkedList.remove(0);: `; k& ?& C  M# V5 k3 Q$ k
            myLinkedList.set(0, 23);
    ) k/ d! S0 K: E9 ^" ^( j/ U5 U6 n        myLinkedList.output();% y( A  _* h7 [4 @6 K
        }
    2 s8 d1 M% j+ Y/ m# y7 ~- E4 P7 A$ K- `% j- s
        /**
    1 \# R  X) u3 W" w" b# j     * 链表插入元素9 B; M! i, O# W2 G- p
         *
    % D- \% X  j5 B: ], {1 X     * @param index 插入位置
    " ~( i& C3 w0 [" K9 Y; F# J! L     * @param data  插入元素 被插入的链表节点的数据. q( R. V& U8 \# I) g
         */6 B* \  o  Z+ l) n- v
        public void insert(int index, int data) {" R5 J7 t8 ^( M9 D* E, e
            if (index < 0 || index > size) {
    - H7 w( W4 C% P4 |  \% ^* @            throw new IndexOutOfBoundsException("超出链表节点范围!");
      g' e& g0 G. Q1 Q( S: x! r8 @* p        }) _" l% Y9 F9 I8 @5 D! U
            Node insertedNode = new Node(data);6 F: H1 R; Q5 P# V4 N5 L9 o7 L' V
            if (size == 0) {
    7 d( k# `% m% _4 V" a            //空链表
    . E* ]- t7 V( V% k0 X. Y            head = insertedNode;
    & ^. @. r( f  k0 z2 \: ]0 a            last = insertedNode;8 \+ k% D) ]5 @: Q0 p+ X5 \0 O
            } else if (index == 0) {
    1 g& D% q$ K/ W* H            //插入头部
    . s4 @5 {1 Y# \8 k            insertedNode.next = head;1 L/ k4 e/ _* V2 w  d. C. N) o
                head = insertedNode;0 C: ~- J% }# z) Q) ]4 s9 d
            } else if (size == index) {
    $ J; l. l9 X' f: J            //插入尾部* Y; N) G0 u& f: L7 n! K
                last.next = insertedNode;
      h0 Z9 q2 o1 B# i: J1 ~            last = insertedNode;5 M/ M0 I. ?4 B" A3 i1 J
            } else {
    ) |$ }% @2 K' K% Z, I  k            //插入中间) z# ~" K( A2 L
                Node prvNode = get(index - 1);
    ; c2 l$ w- S+ H- z            insertedNode.next = prvNode.next;2 p' z) _& O- e7 h+ M
                prvNode.next = insertedNode;  L) t% O$ G, d
            }1 q* }  ~1 I0 Q2 @: Y
            size++;
    + |/ `* z0 W$ S# ?! a  R! b2 W    }0 K4 }. U% M3 D4 I+ O# I
    ' I% }2 x# y* e* [2 k7 s
        /**
      C. t8 z7 m% b% `3 o7 Q     * 链表删除元素# h+ d. B2 v5 M6 v
         *
    5 ]4 v8 N! g7 O5 r- D2 }     * @param index 删除的位置
    5 K9 \/ o1 o5 \% r7 @  d0 }     * @return 被删除的节点5 m+ t6 ?0 n4 l6 B6 ?( J7 N% t
         */
    5 ^; j! h# S  s6 F    public Node remove(int index) {" X& d+ O# [& I; B  x* E0 G
            if (index < 0 || index > size) {
    ; T6 x' I# T" A# i. S  u  \4 s            throw new IndexOutOfBoundsException("超出链表节点范围");
    * l7 O) F0 [: Q, j) |        }  f) a  Q: O+ A, R! A5 U
            Node removeNode;
    ( H1 n8 u- b/ W        if (index == 0) {) R" U4 L7 E# E# S- c; {
                if (size == 0) {, l2 S* i# y1 Q9 o' c
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");7 S* A9 p- U% X7 l1 B6 f! f( ]. K
                }
    + N/ X2 A' \% G3 ]; b            //删除头节点# V' N5 _0 w. I) V$ a. ^% [! X
                removeNode = head;
    4 p+ l' x8 W8 r# C0 ?# W            head = head.next;7 Z" B( c. c- z" O5 X  h
            } else if (index == size - 1) {
    ; S, J) s3 q8 K( f3 V            //删除尾节点( Y$ d$ K  C2 m0 S& ~. U
                Node preNode = get(index - 1);+ u, `/ V& j/ Y8 S
                removeNode = preNode.next;
    ! J) s: Z* V% ~- X8 Y0 Z. {            preNode.next = null;" R( G/ ^* b( u+ c5 k2 t
                last = preNode;# ]4 u7 g+ ~' S3 x: D2 I: Y
            } else {
    # m4 g/ g+ p' ?5 V. t2 L4 Y            //删除中间节点) m7 w+ H$ C+ `: n- b
                Node prevNode = get(index - 1);
      q. e  K" X6 u- F            removeNode = prevNode.next;
    1 W9 Z  m! t3 I6 ]+ _            prevNode.next = prevNode.next.next;  C, p/ i( K; L- H
            }' a4 A6 }4 Y+ d; G
            size--;
    * P4 O+ a: E( ]0 M6 G- w8 G% Q% g        return removeNode;1 U5 L: W0 E) K
        }
    $ [* ?& h1 g( O1 J8 P9 d. Y% K3 f/ E9 S, P
        /**
    5 B6 c: B, J( D- ]     * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    , S/ k+ H, h7 L$ _; l     *& f3 W% Q5 i* d2 q3 D
         * @param index 需要更新的节点的位置
    7 Y! p' ~/ |- ^* E4 o) e4 q     * @param data  新data
    0 {/ @3 @# V8 |+ I     * @return 旧data% T0 ^$ X  @2 n. {, s9 k2 V! K3 ?
         */, F5 T9 h( \" N' T4 a
        public int set(int index, int data) {
    - z$ {9 p8 M2 S% Z/ h        Node x = get(index);
    5 ]' z( g; Q% }- d; k* l7 U0 U# z4 s        int oldVal = x.data;
    2 M. k  ]& [9 L: @% t        x.data = data;( X3 g* G4 ^% }; u- e& `
            return oldVal;
    ' _1 d5 t& c: T9 h$ i    }& G% P/ G( h3 ^) c# Z  c7 \

    1 ^! S5 Z* |' w# @( Q% ]2 o    /**- Q! W9 i4 U% D# \
         * 链表查找元素
    / ?% R. \- t% F; p9 Q6 u% l     *% c/ i6 E  s% M, I+ {  u/ m9 x+ p4 M
         * @param index 查找的位置7 D; }8 H+ t5 I. F7 m2 F
         * @return index位置的Node对象
    5 y2 r5 z% k) C& d     */
    * v/ }# w, J* N) E* M: z2 k+ }    public Node get(int index) {* d, L7 |/ B- W+ D8 w, ~' E) E2 b6 Z
            if (index < 0 || index > size) {# H6 ?) a) q) V' ^0 U- s- I3 f7 M
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    $ D. |& T, N( h4 O3 Y( u        }
    . g7 X* H6 L4 m: o6 T        Node temp = head;
    / w1 z0 Q) _3 v1 y2 V! i+ W        for (int i = 0; i < index; i++) {
    # P) v3 c1 K' L5 {( `# G! P6 R0 \! p, v            temp = temp.next;
    # v# K+ h: {, r. k/ D: i        }& U1 ~( }" E0 {3 c6 {+ _4 U
            return temp;& S$ F7 }- G$ j2 |0 v
        }
    % B! v" L4 V) ~8 y* j. P6 A% _! r* j# R6 {6 I1 {& y
        /*** I9 W9 D* Q6 a- V# I
         * 输出链表
    2 U  w& @3 n$ L: \. I     */
    0 g' e2 Z4 ]) L2 c2 W; k4 W    public void output() {
    8 h& ~* R# d6 R! X' S        Node temp = head;
    ( _% d7 W$ C3 M  D) p        while (temp != null) {8 X3 w; y6 U5 u1 u& Z1 _3 Z
                System.out.print(temp.data + " ");, z' I% k! {, l# [' m
                temp = temp.next;
    9 Q  u- Q2 L6 m7 Y0 j        }
    " b+ c7 L4 Y  h& T1 Y$ J1 R' z' l    }( c' o1 a* `$ b9 ~; R* E* ~
    . @# w% d; R3 ~. A8 @: _$ _! H
        /**1 I$ l9 ?2 L* v% O
         * 链表节点# O- m, V& l- E% b2 \8 J5 F
         */) G& N$ X$ X7 b4 l5 H- V
        class Node {# C+ w9 K2 M1 D' J
            int data;
    7 X2 ^  w. l6 P/ J2 D        Node next;
    ! P$ X- h1 k7 L
    & m) W" X' _. I+ L% Y: F/ `5 q' p3 h        Node(int data) {- x! P# X+ b0 F* J
                this.data = data;& o, y4 [3 k2 W6 I* ^+ ~+ _  I
            }/ i2 C  x  n) Y5 {; @: h8 q
        }
    5 z, G7 q% Q& k  Z8 |}
    $ N8 p1 C: I9 D' F6 M  A: s. i- _! r$ Q9 F% \) n

    5 f2 Z9 j$ \8 ^7 u% t二、双向链表 12.png
    ) @: h0 J- H$ Y# Y  P双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。
    ( D  ?4 q2 f& P7 H' Q# u
    - M  _5 M% f4 \! l2 R
    6 w. P" t. `) C# T9 \
    3 Y+ N9 y0 H! G  R1 u5 t% m% V% s/ _: A
    ————————————————: f  ]7 l2 y% M
    版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。1 K8 }  u6 e, w+ \, w- F; v# a
    原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468, ]5 e) T8 c6 [+ b# {
    ( i+ U2 B* S7 e9 \) v0 R: a* F; H3 Q

    ; C& y0 C+ U1 e& ]- U( V$ T( o5 `7 {

    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-14 17:18 , Processed in 0.356861 second(s), 54 queries .

    回顶部