QQ登录

只需要一步,快速开始

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

    : W1 B  E# c8 H【Java演示】什么是链表?数据结构5 k. e+ Y4 L% K1 S& y, {  d* |, K
    一、单向链表
    9 W' u6 D; ]/ g/ z5 y8 f& N% q1 e/ C
    % b3 m3 p' z! G6 e 1.png
    9 d) V% Z1 E, ~) m8 _$ ?0 O* l链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。  l% j! ?' g9 K' j4 c7 R. m4 E
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。
    " l" b+ y8 m  O% [链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。; p) Y2 ~" b2 B' f# e! a3 F
    " ?0 [7 C+ R2 }: a+ G+ ?
    什么叫随机存储呢?. S* Y* e- G8 b
    ' C, T* c0 e4 D/ z* `& q& l% g8 L6 z, f
    如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
    0 E7 z/ K/ w/ F* y% ~2 J上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    2 E( B/ ?1 P1 G/ B2 b1 A+ q& l 3.png , J2 O3 d. v# n( G8 G+ X7 Y

    " h& ~% p: z" l8 w

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

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

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

    4.png
    1 O1 Z2 b2 A7 D: g8 z% R/ C
    2 B- f, b  X( P: N6 H5 t/**
    % @7 f- N* y: p+ D     * 链表查找元素* ]; Y* E. P5 p% g% D
         *
    ' q4 F( e5 K0 e  `  X     * @param index 查找的位置! e4 C3 e& r5 x9 t  p8 ]1 @/ q9 f7 V
         * @return index位置的Node对象
    0 R  `( v7 U5 ]8 C; I, u; X) d     *// W# D  z* l: N$ }; W3 V
        public Node get(int index) {" J9 |. q" z0 D0 }9 }' D! f  J. e# A( O
            if (index < 0 || index > size) {( s. q& L' P. p) E0 t4 ?
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");) R; x; O" n% k) T9 o8 O% n
            }
    ) d9 S& o% Y1 E        Node temp = head;' w6 D3 s7 A# G6 b$ |/ E- [9 `
            for (int i = 0; i < index; i++) {+ |: P/ f$ J# D' x" g
                temp = temp.next;
    & o9 _. B8 T, ]: s        }  m/ A0 @8 E' E  C+ I
            return temp;
    - a' o; N; \6 n. G2 T* F    }/ o" S' O9 m9 e

    7 _/ {+ p7 h6 w- _7 G

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

    2. 更新节点 5.png 4 D8 E' _! x, x& G6 R' z& e7 `
    8 W% r9 j* h, h: }0 {& ~! Z- V8 o
    如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
      }5 E- ]# @* y: z8 a* v7 p如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)
    ( i, l. _4 H( v/**
    + U4 N7 A+ |- u4 o* T# b6 W1 |( v     * 更新节点 将列表中指定位置的节点的data替换为指定的data。- v1 r( ?, q7 h) f+ T( |' N- f
         *7 Y- ?2 o4 ]" D: D+ r
         * @param index 需要更新的节点的位置
    3 ?- G% |: Q& a3 L     * @param data  新data
    ! E: T* z9 V) a/ r: Y/ P     * @return 旧data1 s$ d* L3 m. n% M
         */
      @9 p* |7 Y* m: ~    public int set(int index, int data) {
    . ?2 V" Z- P4 b# u8 G0 z        Node x = get(index);
    . E9 z( I8 |& X+ t& T        int oldVal = x.data;& v7 J4 D) x" M) P  w% C- U
            x.data = data;( b$ R8 q% ?( q1 Z
            return oldVal;& X& ]2 }& _1 C7 \3 _) y
        }
    , w9 n( g& x$ h$ c. r$ f
    7 H4 T- s- m# ?' t" d3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入
      9 f8 a5 M, i( P; ~& [0 R
    3.1. 尾部插入

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


    / o" y7 ^* F) v! t* u5 { 6.png   s! _1 B+ e5 h. [% R
    3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。
      8 X! p8 Q3 T+ b# x. }7 f5 v/ u* U
    7.png
    / i; [9 J( A8 u& }) h
    ( {+ J2 E2 ^; N: E. Y$ Y( Q3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。' L  `, i6 U+ U2 i' U& E. y
    8.png - m( M6 ^/ N, ?" r" b
    & l5 P! o" v1 x# \* }
    三钟情况的代码合到一起2 Q& ]2 f+ j3 f3 R0 y, ?. u( E
    * h0 K' r4 n% U5 e
    /**; z$ G* b2 L. d7 R
         * 链表插入元素, |1 f! q2 {; k  y
         *
    * ^$ ]9 J: N0 Z5 T* f2 G# a     * @param index 插入位置
    % d# {. c7 P) `2 B, B     * @param data  插入元素 被插入的链表节点的数据
    6 t$ L" ?1 c5 ^, L     */# C1 @  U: l5 s( @; c
        public void insert(int index, int data) {
    % ^& {/ l" L0 i9 p! Q        if (index < 0 || index > size) {
    5 [5 r- O8 n3 o/ d2 K( s            throw new IndexOutOfBoundsException("超出链表节点范围!");+ D1 ]" n& _& {3 @0 f4 @
            }
    - ^4 E: Z/ N+ D5 B" T" P% ^        Node insertedNode = new Node(data);
    : [, Q% h0 F4 J- e        if (size == 0) {" n. J' [8 A8 _
                //空链表
    0 ~2 s8 L  i9 y0 [& Y            head = insertedNode;" Y  K2 g1 ?# {' I% ^& X9 |6 G
                last = insertedNode;
    0 b, Q0 [3 a! Y  b        } else if (index == 0) {+ p1 B& T" K$ n
                //插入头部
    1 a& H3 u  q6 W            insertedNode.next = head;
    1 L0 e7 O1 S1 y            head = insertedNode;' f, m# f) t  R1 n& D
            } else if (size == index) {
      t9 p" G+ ^  f  f9 E+ M1 [            //插入尾部5 Q" ?# W5 Y. X, `
                last.next = insertedNode;
    ! v3 T9 E8 z, H, D            last = insertedNode;9 Y2 A" n/ H  [" D1 [! G5 X; a+ @
            } else {3 q0 B1 J! P& x* B! @( a  }2 y' J
                //插入中间9 O: Q" a* a) ^3 K5 V1 y
                Node prvNode = get(index - 1);
    + y% g  ]: S9 m% H0 K$ G            insertedNode.next = prvNode.next;  R" n( X0 z4 {; @
                prvNode.next = insertedNode;, F! q, @* Q: s" i0 S
            }
    " c% m8 X& o7 B; t( y- ^3 n/ g        size++;# T( Z0 f$ y. \+ }) p; r. w
        }
      @* F3 u6 F# J( w" b& @7 N6 F% f: H7 L  T& y
    /**: ^/ U. g6 h. R- O
         * 链表插入元素
    . o# ]+ v7 }" p- w; F     *
    6 m1 c6 V1 Y8 y$ l) D     * @param index 插入位置
    - U* u. G) F. k. R2 K: {     * @param data  插入元素 被插入的链表节点的数据
    ! ]/ @: H5 Q5 M+ q0 A- E. n     */" U) f% ~# P5 g# v/ M) E2 U; t
        public void insert(int index, int data) {  v% `1 u: b% F  t9 c7 S% f" `
            if (index < 0 || index > size) {( m% @5 Y( U* A+ @$ [# @6 f
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    : k( n" _& B5 u, s        }
    0 I) p* I2 k  h5 z8 q        Node insertedNode = new Node(data);6 ~0 J7 N) e/ P* y
            if (size == 0) {3 C& Q! F0 P# h
                //空链表# U3 }5 F- @. e1 L
                head = insertedNode;
    - \; L4 U5 o+ R! {5 h2 c4 t- V, @            last = insertedNode;
    % F# f0 I$ N0 S5 g        } else if (index == 0) {- F; I* Z7 \3 n0 y/ @
                //插入头部" m. k4 q; t* o; r: t8 W$ P
                insertedNode.next = head;
    : t1 d# t( M8 F1 Y8 L" K" i% M            head = insertedNode;
    1 h. P% L3 E) o: r3 m        } else if (size == index) {8 T3 J9 m5 x% W
                //插入尾部
    / |2 c; k2 d9 j7 z$ k2 v' O2 C            last.next = insertedNode;
    / ?; B+ u6 ]7 @; f1 ~" t/ k" ]! D            last = insertedNode;
    ( W( ^& y" \9 Y4 [# }3 U  o        } else {! J1 N2 \! k% ?7 k- }2 G& W3 d
                //插入中间
    ; ~8 U7 _% G9 q* k" |            Node prvNode = get(index - 1);
    . y, L7 C. h9 q* j! a2 G/ a" W! C            insertedNode.next = prvNode.next;
    % m; \4 |5 G" ]- t" B3 `* T            prvNode.next = insertedNode;
    ! V( J1 `" X3 G5 D; I5 }* i        }8 z* X, Q3 r; x- S* @* L2 N
            size++;6 F( P! C# X+ a: v! w, x
        }
    / b& i& d6 n$ d/ V4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除
      ! W: {/ K4 Z& M( g: V! o; y
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即; K$ ~" T0 S& k+ C( b/ b+ `7 z; a
    可。

    9.png 9 V) K+ j& o! U
    6 Y' q1 n9 u$ Q7 i+ e' l6 f
    4.1. 头部删除

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

    10.png
    ! M3 R; K: [  Z3 s- J$ b/ Q9 T& e# z( p' E
    4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要
    : x* p2 X6 R* o  F2 C/ D; ~删除元素的下一个节点即可。

    11.png ! H- f% R9 w( X! h) u- j2 f' \

    0 f' ?; [% M+ z
    2 d5 e+ ?. u" B* @- u这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。% H- q/ {! L: P
    如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)  g$ v7 d: ^& s
    /**
    6 z4 F* {* P0 u  o( b$ @     * 链表删除元素
    2 K1 u( P. x( V. x, w: _     *, n! N1 m3 f$ a2 U& a$ \* U8 K  g
         * @param index 删除的位置* g9 Z" X& y+ E& u% V
         * @return 被删除的节点' C  d; n! t* M& h' b
         */
    2 X0 d* d$ `- P) w2 Y  V/ d& u    public Node remove(int index) {2 j4 g. b( p5 Y. N
            if (index < 0 || index > size) {
    8 D' u9 x6 C" R1 `; n            throw new IndexOutOfBoundsException("超出链表节点范围");8 M+ Q/ h2 h$ S9 t3 |
            }) r0 _- t  ~3 q0 C
            Node removeNode;
    + B7 d3 `& G6 H, Y( [        if (index == 0) {
    2 G% g1 [% B. O+ W* O            if (size == 0) {* z' d' i0 k$ d- i# d
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");& v' f; l# c6 O8 h
                }
    - V$ i) [" }) N- w$ B$ U            //删除头节点0 `, W7 {4 U% r( m) J
                removeNode = head;; S* c! q0 \- W" k' r
                head = head.next;
    # c- Y( D2 |+ P6 w( [1 K        } else if (index == size - 1) {+ P' B. E0 l6 [9 w6 x
                //删除尾节点. W% K8 Y0 y8 C& A, W- o  k
                Node preNode = get(index - 1);- M% r: P  g2 u3 O
                removeNode = preNode.next;
    4 {) L  ?- R+ J3 ]            preNode.next = null;1 q$ _6 F! y1 C  f& A5 l6 Q& o
                last = preNode;* G9 Z- e5 x% P3 |/ M% o
            } else {
    - P0 ~$ t, Q( I0 v            //删除中间节点
    ! A* p4 `! s6 ~0 T            Node prevNode = get(index - 1);
    ( q  C  |; Q9 u' l( A            removeNode = prevNode.next;  o1 E2 @4 n: ?9 j( s& C2 y) o
                prevNode.next = prevNode.next.next;
    7 q0 C% F) N& X0 K# |        }
    ' A, o5 F1 N9 a4 p, W) O; ?        size--;
    4 p, o) L: j  h4 E) X' f        return removeNode;
    / k. D+ z1 y. X    }2 K4 _% c+ w8 L6 z
    Java实现链表的完整代码package chapter2.part2;
    ; ], O# N! g7 O, Q$ y
    ; h# p6 ~  D. U* Q/**
    4 M! k6 Q) j- j9 f% W- m * Created by IntelliJ IDEA.: F2 l; e3 v3 w# ]" R
    *
    : d) K- v0 S5 Q  A; K * @Author: 张志浩  Zhang Zhihao/ s! `. ^; a" Q: ^* ^6 X
    * @Email: 3382885270@qq.com6 W. j9 j6 m+ d1 z: w" p7 p
    * @Date: 2020/5/3
    # p: O) H5 z8 ~+ K* S * @Time: 13:39+ p, [- `9 Z5 ]
    * @Version: 1.0
    * j5 Y2 Z5 |! N; T5 m8 f* q */
    4 F: h& k: n; S- j3 jpublic class MyLinkedList2 {
    9 e$ U: D- U( q* a1 {2 b    private Node head; //头节点
    # ^$ e$ b- b$ s$ _1 s! N' l( y; f    private Node last; //尾节点+ e/ z6 S% c- E1 @$ J! _
        private int size; //链表实际长度4 O% L3 L# K8 y8 x2 g
    ; z# G, A1 |% [& x3 }: M
        public static void main(String[] args) {( a. p$ M, d0 o, @1 x. R6 n
            MyLinkedList2 myLinkedList = new MyLinkedList2();; n9 w9 w. `9 N
    //        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    ' q2 b( a) N; j; i6 ^- R/ m//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
    0 q. q. K) W5 I# L, t        myLinkedList.insert(0, 3);
    # M, m5 G% {% k) F        myLinkedList.insert(1, 7);
    3 |2 h) q4 t( ~* `; d' F        myLinkedList.insert(2, 9);
    " f( [: T, `3 a3 ]% U' F        myLinkedList.insert(3, 5);+ A$ V1 p2 w/ `! k" X6 Q( v
            myLinkedList.insert(1, 6);1 D) W2 o! {- S- A* O6 n
            myLinkedList.remove(0);
    , \$ b' S0 x8 z2 [        myLinkedList.set(0, 23);3 Q1 Y6 ^/ D, Z6 K7 e
            myLinkedList.output();3 \) w6 T" P' ^0 f7 ~8 `
        }
    $ w3 i, }; y3 P! B" {4 Y- Z9 P
        /**1 z* g( b$ e* R+ l& B) B
         * 链表插入元素
    & N' L! R' l7 N1 N     *4 K) U) g% `2 \. g
         * @param index 插入位置0 h$ X8 ]7 k6 s& O2 n' I  n
         * @param data  插入元素 被插入的链表节点的数据
    ( j6 x  c9 M9 Z9 F3 Q% X& B     */
    0 q. l, a) S% K- h! |% C& c; \    public void insert(int index, int data) {
    2 L# X* |" S% `' i+ p        if (index < 0 || index > size) {
    - W+ x' y5 M# O# g5 d- B( d! B# X            throw new IndexOutOfBoundsException("超出链表节点范围!");
    ' @1 x$ a: ]1 U1 M5 p1 W- l        }
    : C/ D. x7 |& x3 M1 D( ^- ]        Node insertedNode = new Node(data);
    * G6 \, I& X' t* T# r7 M# j        if (size == 0) {8 o3 t$ D' h: D4 j" Q& w
                //空链表. Z# v) d- Y6 M+ B
                head = insertedNode;
    1 g  a7 @  Q. J1 E9 T: i            last = insertedNode;7 e% a* U2 r! `
            } else if (index == 0) {1 C- g. ]' _7 ~
                //插入头部
    & ]$ Z; o% [/ K/ ~8 t            insertedNode.next = head;
    3 u, G0 y5 B3 B- N. b5 J; A            head = insertedNode;
    . c' I# d3 ^) r        } else if (size == index) {
    6 |6 ~6 M. K  U. [3 w9 L. F            //插入尾部2 [- _6 q3 o, Q2 j
                last.next = insertedNode;* O3 n" p) f7 r9 c+ C3 l0 R& K4 r
                last = insertedNode;9 l/ W: y8 A. J" {5 A% c
            } else {4 s8 k2 u. |. B7 Z2 q
                //插入中间
    / l7 Y: I% F: |            Node prvNode = get(index - 1);
    $ T* \* Y; s" k% v( P3 }3 I- u; ?" J            insertedNode.next = prvNode.next;. L/ e& c+ n6 h6 i  O. p
                prvNode.next = insertedNode;# y  z2 c6 c+ m$ O! r! i7 A; g
            }3 `3 ^. c% o' r
            size++;
    7 T: E3 P& B& P' W  w5 E    }/ V' [; `6 e6 d- P9 [6 {+ Z
      D: p9 T. Q1 i' g& z7 _
        /**( u4 D4 ]/ L& E+ j
         * 链表删除元素- Q9 [$ _& o0 Z) K4 z% O, E
         *
    3 K/ t6 a3 C; c$ h     * @param index 删除的位置* w5 w0 u& M# l% V% n9 ]) T
         * @return 被删除的节点
    7 b9 T% p7 V5 k4 [3 V+ q+ P     */
    % r2 L0 I% R1 O" I5 Q" ^/ {    public Node remove(int index) {
    1 D. b# k- n' A* w# P! G: w" i" k9 j        if (index < 0 || index > size) {
    7 z- _6 i; n" g            throw new IndexOutOfBoundsException("超出链表节点范围");! k5 b4 v; A9 u( q3 ^6 M- a8 @
            }' K1 i: J4 `. `* @5 e2 e
            Node removeNode;
    % ~& E. @/ ~! _! s        if (index == 0) {3 o6 X8 R7 Q6 w+ Z: d9 u; ]7 j
                if (size == 0) {# C1 G$ ?, \  P- G+ J; P
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");. A% F) [0 y6 r0 K
                }
    2 P) n/ Q- u0 C% ~& r4 B9 _            //删除头节点0 A$ \( `, p- ^' v0 e7 J% c
                removeNode = head;
    ) M; \6 t" Z" V            head = head.next;0 x) s* z" D0 ?3 u
            } else if (index == size - 1) {# A' i" _- H% m' l  A9 Q+ {5 O
                //删除尾节点
    7 X( |2 `6 B9 A: ]# Y            Node preNode = get(index - 1);
    - f8 `/ X: {7 ]3 a% G$ c4 p            removeNode = preNode.next;, k( Z1 j" R5 e" |6 C* q2 v5 H
                preNode.next = null;
    8 `8 w  |' \# m0 {, {2 W6 E! X7 y            last = preNode;
    + l' q$ }3 }8 r7 B# Q        } else {
    $ g7 X9 ^7 u& j! t, m4 M            //删除中间节点' e; t  m: Z) w5 O
                Node prevNode = get(index - 1);( |; b7 C' D' q' D5 y3 B; V9 |/ l# E
                removeNode = prevNode.next;
    & B$ D8 a# s% k            prevNode.next = prevNode.next.next;
    : R1 h4 w! u" L; P        }
    + [( A4 G2 V! n: a- i+ Q1 G. E  _3 v        size--;
    . e9 A" n. H0 L' H. e        return removeNode;
    4 i1 K* ?& G* j2 F2 s; M; b0 @5 W    }  m+ V4 z3 Z- j7 f# E* T
    4 b. f/ x! y! t$ `1 J
        /**
    9 s( z6 E! n$ }% n, v7 \     * 更新节点 将列表中指定位置的节点的data替换为指定的data。+ _9 n: Z+ {, D% V% g
         *) n# W9 K8 |" H: ^( g: K$ @$ J
         * @param index 需要更新的节点的位置: h" j% g, o9 H# w
         * @param data  新data
    ( d' I# u" K! I! H; r     * @return 旧data$ U9 x3 {. U: P9 i! Y
         */2 ]9 {8 z% A- j& U; D
        public int set(int index, int data) {
    & Z5 b% i1 [+ c        Node x = get(index);
    9 |& G; s: ?# Y( J& k1 P; Q        int oldVal = x.data;/ d% q' S" w% I8 G
            x.data = data;4 w* T3 y% T" n5 y
            return oldVal;. o0 s; F2 k$ D0 n! v/ a# r3 D
        }# W8 X0 g; S3 t# n! z

    * q/ u; w/ e- a+ |    /**
    4 e2 \' G' L  D% z) d     * 链表查找元素) `( U% o0 n% Y+ P2 a* S' ^( G
         *
    ; ]' X2 p# [6 p, B; J" B     * @param index 查找的位置" g$ q, p- k- U6 [
         * @return index位置的Node对象
    " B/ t: ~9 ]! s! N1 w- ~4 R4 K; `5 ?     */- v, _, f* X. `5 U
        public Node get(int index) {
    1 d' `% H3 a' e. c# z" q) K0 x        if (index < 0 || index > size) {
    ' K, _# S2 s* @$ K            throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    ( e1 i& r' K1 F  @. b6 R        }
    $ T. p; f+ n+ W1 ]        Node temp = head;" Y6 n' H8 o, d; M$ K, V- r
            for (int i = 0; i < index; i++) {
    , ^& m/ c% d7 Z0 {/ u            temp = temp.next;
    , g4 h% g; X' A  `4 j        }0 d9 g; b6 ?7 i/ e. N+ Y: L9 i
            return temp;
      o% C6 J- K9 i( w5 x0 j3 [1 |4 F3 Z    }' ]5 Y( R$ w: x( Z, p

    7 l9 R! p1 k' L0 t    /**
    * c6 [/ X% k* D7 j2 D     * 输出链表
    6 {9 p9 ]* n% C( r     */' n2 E! C5 ]4 O+ c) X
        public void output() {4 r% P# U; V$ P/ S
            Node temp = head;% N' L) ?3 Y9 y
            while (temp != null) {) u. U) z2 q# ?
                System.out.print(temp.data + " ");- `; x2 X. F" o2 [; l
                temp = temp.next;
      N2 b6 U, c' X        }
    / [8 X3 u! ]# o& m0 P, z    }
    ! \3 t9 D* @/ w: |
    * c, L. Y3 c1 k& ^- O. E+ |/ Z: G2 g    /**
    ! ?8 Q5 o4 J9 b$ C     * 链表节点
    % u8 Z% {4 [+ m  I4 @+ D. K' T     */
    + {6 [8 w; e' L8 L7 F    class Node {
    ) ]5 m# F( D# V        int data;
    # y/ `" K" Z3 M" v% f( p0 _2 _        Node next;3 [# C, r7 w, i/ j3 X$ Y
      q+ A3 ]1 x/ f( H  y+ ]1 r! H" C
            Node(int data) {; [6 u% V; x4 j7 E& u6 P+ S
                this.data = data;
    8 l+ I: S' I0 X  R3 Y' J  ^& c        }4 I7 L8 C: u7 B) j. u6 a; g
        }
    0 O. C# z" V' [& n- x/ I}3 y2 W  f! B& _% @0 o( G

    % F% K/ |& K& n$ ~  h
    ! n- {: \+ b4 Q: k9 h& Z二、双向链表 12.png
    1 G6 B# _) i( C4 T( t双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。1 C, I+ {9 H# g8 A  [
    " g. [; {' Z5 s# z# G
    ' R$ k& i  Q( ]1 P8 [; B+ `4 O
    ! r$ }! }6 M3 P4 y1 Y- v
    ! x3 U5 ?7 b" r6 r: I  D  l
    ————————————————
    8 \0 `9 `, @! s8 H7 b# D版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ; M7 W: H0 w" q. G- m3 f原文链接:https://blog.csdn.net/weixin_43124279/article/details/1059044682 e6 p0 D$ C+ v
    + N; z' {- U; l/ F4 Q0 b: I

    , c2 D, _! j; ?! d% n- ^- t

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

    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-4-23 09:07 , Processed in 0.440396 second(s), 54 queries .

    回顶部