QQ登录

只需要一步,快速开始

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

    * Z0 x0 ~, P% y【Java演示】什么是链表?数据结构
    . ]) {- s6 Q$ V% f7 |0 N+ ~) y一、单向链表
    6 \1 |  m: w: O- ^8 X$ [
    ( H- Y8 Y5 c# E; q2 }1 s; z5 l0 Q 1.png ' I0 X0 v9 v, S. @& U
    链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。
    " z' x6 M( C: N$ t2 B' J; c' h8 H! s单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。+ D* M' @4 i, A* t$ b! _" A  |8 Z
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。
    9 t: t& |/ d6 b' \/ x$ {6 c+ Y) c  I' Q' u+ ^7 U5 t) G
    什么叫随机存储呢?
    / i: M/ w9 t0 [  w
    . A/ j  X0 f2 O) E  w如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
    $ D9 x4 a6 ]1 Q6 I5 s上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    9 q7 }0 C; t& r# r7 P 3.png ; C& o7 T0 t. U, o+ `

    8 y; |) {* {/ K/ l

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

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

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

    4.png
    9 i' v$ O* G: U3 [8 F! j
    ! E+ y) u' a4 D/**
    ; v5 y" _- j7 u+ p$ [1 O1 z     * 链表查找元素4 G& X7 a, u$ O$ A* W
         *( {. H6 s1 L7 a0 [4 }) C" S1 R
         * @param index 查找的位置8 Z8 y! d% Q5 o
         * @return index位置的Node对象& h/ [1 A) R* U1 u( x2 Y( p
         */
    % j7 n" H  K1 V    public Node get(int index) {
    ( J6 |- p; a7 x# e, k* H3 o0 l, L        if (index < 0 || index > size) {& r) n, X4 K; _' D) X
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    , Z$ A, g; k  b& L: y        }5 t4 X' Q  f, n- O' a/ m
            Node temp = head;
    - P- g: A3 W/ O: U; t! q6 k$ }$ x        for (int i = 0; i < index; i++) {
    * q4 ^* M7 X- z  D( c            temp = temp.next;
    $ m) ~9 [  x2 z, W! S  X        }) m+ ]* W! G7 _4 ?) _
            return temp;
    + L  z! t  o3 g# ?5 u& J+ e    }$ ]" g' y/ K: Z9 E$ S5 V
    2 z3 p+ H* @& c1 o+ R

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

    2. 更新节点 5.png
    2 ~! ?4 i) ^" T1 i! H
    9 E1 a* p3 l6 W/ Y. t如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    9 Y7 m7 ?; E3 z如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)) B5 m% G: |& O
    /**2 S0 ^  f: g- H- w* f
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    - m7 Q8 \; O" X1 t) x$ W' ]; k     *+ L2 `- Q0 H1 m$ l9 ~/ a, Q
         * @param index 需要更新的节点的位置
      u4 f* {9 ]  q( _& t( h     * @param data  新data
    1 U- h+ H* I/ u0 l3 t  c( b     * @return 旧data- n% z4 o6 A2 J3 Q0 F  ]
         */) p0 ^& ~7 j5 E2 Y# Q$ g
        public int set(int index, int data) {
    3 T* |$ v$ X0 w; y% N3 G5 X' T        Node x = get(index);) g/ S4 a4 \- J7 r7 [
            int oldVal = x.data;) m/ a4 B2 }5 @$ T9 O' j4 ]
            x.data = data;
    $ S- y9 f# |+ C+ L  @" g7 D        return oldVal;
    . w! P4 G* v3 g. Z    }
    % c3 d  F  a, x8 \. h" \
    9 \9 e7 U0 i4 {" ~3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入
      + i/ S, U6 a/ M' f% a
    3.1. 尾部插入

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

    $ {$ ?9 n% `) X
    6.png
    , W0 }# V2 f& s3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。
      $ }/ J" v- r' X# C
    7.png / T, g8 T+ P7 B! _6 O* K3 {7 j

    2 y; W! Z) O( |5 R" M/ K3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。# T; j, M  o) o) f$ A% a# I: Z4 J
    8.png / i6 d0 Z" P; O, _/ X( i
      Y# Q0 ?" t& |/ y! i7 A6 p) \8 I
    三钟情况的代码合到一起
    2 R, o% B2 t. c5 B, ]$ f8 @& i, d4 u+ B# _+ h$ W( E! W. u% W% p. \
    /**  x$ G) k" C7 y1 ~% w
         * 链表插入元素
    & L2 c  d0 O0 A" ^5 o) v  z     ** X( w+ G# _& X. p7 f
         * @param index 插入位置4 v/ d( x2 D1 ^5 a0 s1 q
         * @param data  插入元素 被插入的链表节点的数据% v; S- R& B* B$ o  v8 @: S
         */
    # h/ v. P1 K, r9 d% E9 @! u    public void insert(int index, int data) {1 ?& Q0 X$ u6 Z. n$ w/ R' l% O- n& Y
            if (index < 0 || index > size) {" A: j- W, z0 v& k$ T* q
                throw new IndexOutOfBoundsException("超出链表节点范围!");
      O* Q& J4 j+ E4 o; s; v        }( v8 g9 w, Q( [' }1 y
            Node insertedNode = new Node(data);
    " T' D6 Y0 o2 ~/ q8 A/ Q! t0 s) W9 l        if (size == 0) {
    + [% P& X! T' d- m1 V6 t6 N  d% b& E            //空链表
    # P( v2 `# Z0 T: f! j            head = insertedNode;+ y$ K$ }: ]: b8 O# d
                last = insertedNode;
    ; o, U, u4 u4 b0 ]1 C9 b        } else if (index == 0) {  e" g! T% d9 @, H- W' ^3 p
                //插入头部
    2 |' ^. k" F5 F+ l            insertedNode.next = head;
    $ ]1 |6 @) e* F6 _8 A. p1 ]; \6 G            head = insertedNode;8 K" t: M7 ]. N; R; Y8 H7 P
            } else if (size == index) {& _0 c; G" Z" v1 ~& {( I/ _
                //插入尾部* K$ G+ `$ y7 W& u
                last.next = insertedNode;
    7 ?6 m+ S# Q9 O. F  w/ i) S            last = insertedNode;3 I7 s" v. d1 _, ^( m3 @( ^
            } else {
    9 }# A- m5 a9 u2 S9 h            //插入中间0 G* N# [0 N  B/ T2 y& c+ C
                Node prvNode = get(index - 1);) L' d0 g, N' X( T) i4 X
                insertedNode.next = prvNode.next;0 E( B: v( P! j- M
                prvNode.next = insertedNode;
    & ?# m7 y! E" t! d        }; ~7 k3 I) [. _5 t0 P3 C1 ]% t
            size++;7 Z4 k/ ^+ \6 a' P/ `, n1 U; S8 X
        }+ ]3 B6 m0 j; \/ r+ }* ]' `9 ~

    " r- A3 |! g7 M0 ?8 x( j) e/**
    1 T( U1 ~) i* j$ K' @9 d     * 链表插入元素( W  I7 ]; E6 x$ d* T( }
         *
    ; `1 H, [* {/ A6 F* J     * @param index 插入位置" _* [, [; T: a8 U# B2 n
         * @param data  插入元素 被插入的链表节点的数据2 t' P2 E+ t* e8 B% B
         */$ H, V) ]% ?2 v& L4 U
        public void insert(int index, int data) {4 }+ C" j4 y/ p$ F. N; ^. p
            if (index < 0 || index > size) {
    8 q5 E2 D& R0 P            throw new IndexOutOfBoundsException("超出链表节点范围!");/ c+ p. B! A2 b3 i7 u) T
            }& L; p* f) B7 \2 U( f
            Node insertedNode = new Node(data);% Z3 L$ g( t4 K- p9 b8 R2 J
            if (size == 0) {* p( o7 a7 J- f1 I, p$ g4 s
                //空链表
    ! g7 V1 y* _- W" A* v- i            head = insertedNode;1 t% F; S7 b# x% b
                last = insertedNode;
    8 P! Q/ G: W3 {& L( g        } else if (index == 0) {6 U+ H" q' w' q# f& `% u! r
                //插入头部
    $ {; X- Q9 E2 t; b, \' E1 K4 q            insertedNode.next = head;( b; n% r, O# v9 n/ f1 u
                head = insertedNode;) Z9 e- Y2 g9 a8 m+ F; |  x
            } else if (size == index) {
    ; y: w; r9 t9 K3 _3 b            //插入尾部" R' Z: ]% h1 |
                last.next = insertedNode;& ?. o1 ]5 z( o5 f  i5 B2 H6 e( C
                last = insertedNode;
    9 @2 u3 O6 {4 z$ M+ Z2 W# i  b        } else {
    1 e, v# z8 Q  c; ~            //插入中间
    ; E4 H+ ?0 \2 H% y: M+ J            Node prvNode = get(index - 1);( \; [; h; b+ c1 [1 ~
                insertedNode.next = prvNode.next;" K+ L2 B  c! ^
                prvNode.next = insertedNode;8 t8 _7 |0 s6 c
            }; Y# f4 ~! V" Q6 W- g
            size++;% R  B: x3 X0 A4 x8 {
        }% r* ]9 ~' T6 C. ]8 d4 k
    4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除
      / E3 A: i) Y! R7 I% w
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即
    ' x% p3 @% k/ U  j1 N可。

    9.png 2 ^# i* [) d3 |: p. |* N

    8 v# L$ y& ^# L4.1. 头部删除

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

    10.png + p4 V% y$ g9 _8 y& u

    ( a  R  u8 K, n. b: r4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要4 J/ l# P6 Y+ k  P
    删除元素的下一个节点即可。

    11.png 2 Q2 W8 |( E/ a% j0 C

    ! I0 D0 N. m9 ~
    ! g) s  {, [- `) B* N$ I1 {2 e" [这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
    + @' ^1 r" ^2 b% t; l& v1 o如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)/ S( F, I* j8 v+ Z$ s% O
    /**
    ' D& Q- `* K, I, V- i% {% H     * 链表删除元素* C6 s$ W' R3 N7 L' `$ X( _5 T) h
         *
    / P7 E' P# f( C6 @5 h5 l     * @param index 删除的位置: A4 q! J" O$ }; r: t. y5 h
         * @return 被删除的节点
    3 M/ j. f! ?# q% M: ~+ y& M+ z     *// c% P" S" h- r& }, R, ]9 k% L* V
        public Node remove(int index) {) z! }+ ]: T' I5 @' }
            if (index < 0 || index > size) {+ G1 ]$ [7 K' G% [
                throw new IndexOutOfBoundsException("超出链表节点范围");# j4 w! r( I0 K# V* |9 n1 L# \
            }7 d- e8 X6 N' t  t8 V
            Node removeNode;( D# x" ^. y, }9 ?* R, \/ Q
            if (index == 0) {
    & F* x" q7 X/ }            if (size == 0) {
    3 t9 j+ |- ~( y" Q$ F) d                throw new NullPointerException("当前链表为空,不可以进行删除操作");  g. S5 q" T" d; {8 J8 J
                }2 \* [+ l. p4 T4 u
                //删除头节点1 F7 U9 |3 Y$ G$ u6 k' ~
                removeNode = head;
    # A0 W' U; I) q  m            head = head.next;
    5 D( U6 K7 V' B        } else if (index == size - 1) {
    + T5 z: `# \1 m6 i! A            //删除尾节点) y& Q8 j; q' V
                Node preNode = get(index - 1);
    4 {: K6 L" S; \, F2 M) ]3 {5 V$ d            removeNode = preNode.next;
    / e, i  P5 I5 a( D" n' z            preNode.next = null;2 G+ p' [$ j2 e2 v" w, C9 f
                last = preNode;2 j0 p% }5 U9 W( o
            } else {3 R. v0 C4 {: T
                //删除中间节点
    $ F$ `2 D0 a4 b8 n2 v* x( o) X: \3 w4 C            Node prevNode = get(index - 1);" c' h3 a3 f+ K- W! B; I5 I
                removeNode = prevNode.next;
    . M6 r1 f$ x3 i% A7 g            prevNode.next = prevNode.next.next;. @/ v$ B9 l9 d, v0 [
            }
    ' e& S4 T% A9 M8 V5 A        size--;* i' F3 Y$ o" V( _2 }* i
            return removeNode;
    1 p, v% w: q) U% Z    }
    . p  e8 s; \; S) @" DJava实现链表的完整代码package chapter2.part2;
    7 }- d' c" ?3 i" _3 n9 ?2 O  \4 z, s2 O+ i; g3 f
    /**, o: \3 f5 }; @. q! r9 b
    * Created by IntelliJ IDEA.
    7 E8 x: b7 k1 T( ?+ Q# N *
    5 K4 g, D0 W7 n' A( k& K * @Author: 张志浩  Zhang Zhihao9 ~  d! e0 ~; \) k
    * @Email: 3382885270@qq.com+ A2 G' u. O" m* B6 }
    * @Date: 2020/5/3# K. f+ O1 u2 r. I" ~4 p
    * @Time: 13:39& T- Y6 D% x% x5 }$ @5 w. M* a
    * @Version: 1.0# V! E. X4 `; W7 A7 H* v
    */# p" Y; ?/ M3 m2 B1 u9 d
    public class MyLinkedList2 {! A6 t: A2 i- [1 S
        private Node head; //头节点# L6 K: J3 ^- ~# E( T
        private Node last; //尾节点
    7 c! i. r( O' P2 T. _. j8 |    private int size; //链表实际长度0 E) a# \4 L+ ]8 O' u- s. p- T0 D2 e
    4 ~1 K' f1 \9 `% W+ {
        public static void main(String[] args) {. j3 l! c2 ^4 q! B8 j+ T5 p" _
            MyLinkedList2 myLinkedList = new MyLinkedList2();
    ' y' Y5 b9 w9 c//        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作. }6 Z$ i- R+ N. A; O$ J* C
    //        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
    0 @/ z9 W9 S* h- K0 ^) e0 R$ t" h  M        myLinkedList.insert(0, 3);' R$ @8 M1 f* r. {
            myLinkedList.insert(1, 7);. M8 h9 I" j+ p; D
            myLinkedList.insert(2, 9);/ q  ~/ R8 s/ S6 ^( I( ?
            myLinkedList.insert(3, 5);
    $ [6 A: C/ ~- _# {, S        myLinkedList.insert(1, 6);
    3 U7 X, C/ Z* o  P        myLinkedList.remove(0);; Z: N5 T& r5 e
            myLinkedList.set(0, 23);
    + [6 W- r) |: @1 ?2 q. y- o( y( |$ l        myLinkedList.output();# |9 @0 ^/ s% i+ D( B' a
        }
    4 j5 D0 X5 l  ~# }9 X, t3 P& E, j1 i/ Q7 R$ I2 |0 o
        /**
    # M# \+ |' ^) {, [3 r     * 链表插入元素- `* U* z  A8 i* v- m
         *9 @+ _, ?5 q& A6 o: m
         * @param index 插入位置
    0 P! ?4 \- [# m2 {" i     * @param data  插入元素 被插入的链表节点的数据
    , D& f9 T- j0 h1 D( e     */
    * ~- [: d, S7 K% r- X. @! u& B    public void insert(int index, int data) {8 u/ z8 F/ V; @3 j& ~8 i
            if (index < 0 || index > size) {- O  ]# I6 \- ~# \( F: f9 j( q
                throw new IndexOutOfBoundsException("超出链表节点范围!");, O* b4 r; ~& m' k
            }# t# A) b6 G" Y: j7 m
            Node insertedNode = new Node(data);% [- W  E9 `5 g" V4 x
            if (size == 0) {
    % j$ @. C' k, F1 |6 x            //空链表& X2 d7 r0 C. C5 i/ n; b
                head = insertedNode;7 ^5 _- l- e( x% w+ Q
                last = insertedNode;
    , \& j  Y- ~) R" M. E* e& n        } else if (index == 0) {
    + z- Y( @; K0 {0 }) e) \$ [            //插入头部% }% m' l3 y4 m) {9 H
                insertedNode.next = head;9 [" n" [# s' ^
                head = insertedNode;
    6 c* C9 r& ~! L        } else if (size == index) {, `, A: K, U0 r' b; e) s$ n
                //插入尾部( V9 `0 `: r  t. J6 N5 I1 H
                last.next = insertedNode;
    + _5 L2 \# Q2 i! }& A$ ^            last = insertedNode;3 x9 h2 i, r. ~7 Q9 _5 Z
            } else {
    $ w3 f$ f, n; ]            //插入中间0 q5 L" x$ j9 Q* Y4 b3 K2 _
                Node prvNode = get(index - 1);
    3 l! @$ O' h* u1 M. E; N5 D& l            insertedNode.next = prvNode.next;2 R: v# C2 K' {* u( @& I. C' Z: f
                prvNode.next = insertedNode;8 F2 u# ?4 J) n: r
            }# A5 W; W' |0 }. }) T, o' P3 z" w( H
            size++;
    7 H, k3 s1 \+ L  n, ]- H    }2 s, F/ U  n: x+ }9 E2 @
    ! t  z' A8 A# M% s5 S# r
        /**( p) r: r9 ^3 X: Y( u, A
         * 链表删除元素1 T; s( L. q" D$ j4 t! A2 F
         *
    # j$ B6 x5 W9 N  v     * @param index 删除的位置
    - r, O' T( b. p5 }     * @return 被删除的节点
    0 K1 g/ l8 T& n8 c     */& W8 g* q7 M- E+ ]( B5 x( f7 y
        public Node remove(int index) {
    4 l7 g4 z" e- R, N/ C        if (index < 0 || index > size) {  r( A1 P$ Z  D# r# U3 s
                throw new IndexOutOfBoundsException("超出链表节点范围");2 k2 R4 U6 L9 u% B# E
            }* t* p$ M. ^" K( ~4 v, z2 z, w" M
            Node removeNode;- l+ b1 W, g4 Q& Q* @* e! I
            if (index == 0) {
    2 B& B: O" D- F; R            if (size == 0) {
    + u( U8 R8 Q( v  ^                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    2 @; R* w( Q/ r3 D" a            }& {8 S8 q! h2 y% P' b8 F
                //删除头节点) ~' y$ ^* S, s' {
                removeNode = head;( D3 v, w" _) F9 h0 ]0 M0 C' v
                head = head.next;6 e: ~  e1 P5 @, L8 P* }
            } else if (index == size - 1) {
      h  I7 {0 [7 P5 U" k% n& e            //删除尾节点
    3 Y% A0 z2 S4 t9 U( _3 v            Node preNode = get(index - 1);
    + G4 q/ o* G; p            removeNode = preNode.next;
      S# `6 B" A! J# g            preNode.next = null;' x5 P  ^( t0 c+ e- m1 T
                last = preNode;
    ; u- G: A; w( z2 D0 D( O* F        } else {
    2 x. V; e7 e1 x0 E; ?- c) y            //删除中间节点
    7 `' A! J* v% x/ `7 G2 F            Node prevNode = get(index - 1);. N0 k8 F& L3 T: D
                removeNode = prevNode.next;
    : ]6 _$ N- O- P, g6 m            prevNode.next = prevNode.next.next;
    4 @( K6 @/ ~  v$ \% E: E        }3 N4 U; W5 S1 o
            size--;
    - y. v3 u5 y. F( b6 R$ k3 f        return removeNode;, o: A3 Y" T* V8 R* [3 G' v
        }
    - D% i+ Y+ H0 `; t$ m& j  b" O" a# U9 s9 g1 ^
        /**
    - {# D, K5 p" {$ Y4 a     * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    " n! ~4 @: R# R5 e4 t' q     *
    5 w# _6 ~" ?& b0 e- l( |     * @param index 需要更新的节点的位置
    ( J" S; i; h$ D. ^$ E( i9 w- l     * @param data  新data
    + P5 y" t* `# ?1 ~7 v5 X; `7 B) K     * @return 旧data6 l/ o. f$ P2 @
         */
    6 }0 t& {  V/ I6 s; O7 T$ o    public int set(int index, int data) {
    % O7 R; o; Z6 E% S        Node x = get(index);( a# f) ~2 q- K* _
            int oldVal = x.data;
    . F. z3 ^, U5 L        x.data = data;
    # e; Y# l3 z. a3 p1 P3 H! J        return oldVal;! @8 X9 h. L8 K- c+ c
        }5 c( L7 x6 A9 b, A* v# L: _4 z8 I  L

    ! O) C" R0 C; h0 g: S! n) E- i    /**4 _2 O4 J6 ^+ Y$ j
         * 链表查找元素/ D  F- }, p  R4 e5 j5 R
         *! |0 x; g: z6 v* d8 O# E6 R; \6 f
         * @param index 查找的位置
    ) h4 o+ x; \* ~  Q7 x. Z# d     * @return index位置的Node对象% a' V8 H" R/ N* G
         */
    ( r6 W/ Y4 \$ u2 T" c* R# l    public Node get(int index) {
    - W/ T$ o. X: U, @+ e4 i' R        if (index < 0 || index > size) {
    8 V7 U: c* W$ z) B% _( ?            throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    ( n, v, v! v2 ?# _6 o/ s' R        }
    7 q. V1 F4 G6 }: U9 X3 e% F( S        Node temp = head;
    3 z& B% `- _+ T+ v9 a* ]        for (int i = 0; i < index; i++) {, T6 D2 d+ G# ]2 d$ N. q
                temp = temp.next;; s/ g' Q) `. w2 f& c! `
            }/ E/ ~6 D; S2 }
            return temp;
    . I. x, S: \, f* W2 r) w. T3 H    }
    ( C, E8 H) T# J* }- \% Z* S) q5 q! a9 Y2 M! S
        /**
    3 y. E" P2 `, M) T     * 输出链表
    $ g* B. l6 h# F6 f2 E0 e( k     */
    + r9 c: c# d5 c0 x3 N    public void output() {$ e* j9 X2 l9 s$ F- B) ^- R
            Node temp = head;% Q, x$ X* X& o( c% a# a
            while (temp != null) {5 h  `+ D) L: q5 b" A) w" g
                System.out.print(temp.data + " ");/ ^0 \; Z+ y/ f( R
                temp = temp.next;
    ( r  O- i& A* }, h& G% I  c) d        }% h1 J# k3 t$ H- I/ u
        }
    - {# [( r' h. e/ {$ h
    4 d8 Z5 \% [+ z9 Z9 U  t    /**& B) _# z$ [2 ~2 J2 x8 M2 T
         * 链表节点
    * o: Y" a* u6 E* ^5 U: r     *// S/ ]# n( Y0 e) C& H
        class Node {
    ! Q4 B3 z2 m" M) z& [3 U        int data;
    9 G$ S* R. m  t% W* i$ {+ H! C        Node next;9 s1 y3 i, y. p6 I" ]9 B

    ) ^; B4 S+ G6 N# {, O        Node(int data) {8 Z! O% Q* o, t" r& r
                this.data = data;
    ) M/ E1 m" h, e( B" U; W) @) g% |+ P        }4 Z, ^7 ^2 V  _2 I8 Y3 T2 t( [: v
        }3 w: l: d3 A# }* l' u
    }, W+ P! o% ?# X  U

    ) \5 M( Z- Q* w+ }5 p% g1 P0 N! d) l& y0 p+ E; v; c
    二、双向链表 12.png
    9 G0 L) N# }, W双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。$ a4 ?( X6 |/ L, p" W. K

    7 `3 ~: o; z' \+ F9 j/ ]5 t$ i2 D7 }* A5 V3 E4 d

    + V& T9 t9 i( k: p) e
    % _/ F4 \$ t$ `* M( ]( D————————————————
    1 j1 F/ q5 d! w+ w版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    1 j# }  z% x6 U) [* [原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468- j$ D5 J4 t* Z
    " L3 m7 \0 b5 r9 ?

    9 T1 Y. _) m! N6 `' i7 g

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

    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-1-11 08:48 , Processed in 0.342017 second(s), 53 queries .

    回顶部