QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5338|回复: 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
    , S! u: O. i; R* a/ ^2 x
    【Java演示】什么是链表?数据结构8 ?! d8 h8 H+ h% t
    一、单向链表5 P- T- {7 o! o" S7 n3 V
    % R: E' f' Y6 b$ [% S$ G% V2 @
    1.png 6 a9 Q4 i' Q. O- o; Z* _' a
    链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。' b! r4 {; f% k
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。6 N% s5 l" l0 m: c
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。; Y0 t$ R' B5 y2 m
    6 U: s: {( u" }* Y/ h& |0 t, W' b
    什么叫随机存储呢?+ u8 L: F: y* h, w
      Z9 ^. {0 l) q
    如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
    - P" V" t/ I. H" [4 g: G' m上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。0 T+ S+ Z8 \1 G7 X1 ?; l  u
    3.png
    * A# `/ V7 `6 f! Y
    ) K6 n2 Y$ g% `: L! g8 \

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

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

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

    4.png
    - k" i( B# t3 n7 X' M( H. E, D
    /**6 L/ [0 O3 b8 Y9 `7 x4 \9 |, k% G
         * 链表查找元素/ x# T+ r5 ~9 ]0 `
         *
    . G8 d" F. ^6 T. O" n7 H     * @param index 查找的位置: E. D  k% e- `7 l# y; {" B* B# q+ @) I
         * @return index位置的Node对象
    ! E3 J: k% Z/ {# Q, u! n     */
    : V# ?. }  w% K3 H    public Node get(int index) {! q1 r7 v4 c9 M' L- H
            if (index < 0 || index > size) {8 o- d5 D5 {! t$ {4 j0 K
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    3 H; w  \7 q& Z+ `7 H        }3 p( @! Y& u% D8 z4 l
            Node temp = head;( Q- B" C9 ~: r% @+ O6 Y: g
            for (int i = 0; i < index; i++) {& O" s$ u3 @1 G5 m
                temp = temp.next;
    1 L0 u: c9 F! U. r* V        }
    $ \# q( o. D2 W# g        return temp;
    , Z* u3 S4 Q; ?! P! X; f* I    }
    : A2 Y2 f) U) h, {! m- t/ M+ h" z# L- W- L: w! f! w

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

    2. 更新节点 5.png
    + N9 G% |4 l% l" T1 X2 |5 X  c
    $ M0 |; E( |( b; Z如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    ) i; i, J8 ~- x: H; C- `1 T如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1), i" C! H5 h" i
    /**4 x  o* ~. v5 E- u
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。: M# f9 \) i7 x2 \! k# @6 ?
         *( h9 q4 Y, m6 F6 Z
         * @param index 需要更新的节点的位置5 h, C& L0 A& B
         * @param data  新data
    % Y9 x6 S4 q2 I, ~/ l$ A: y     * @return 旧data
    2 N- Z) a  @( y3 R( f+ ?/ H     */* z4 k, A& h" y! A' M: u! T8 O
        public int set(int index, int data) {
    0 l. f% n8 M$ h1 u/ A; T        Node x = get(index);
    % j4 G- t- f. v        int oldVal = x.data;
    2 K6 w8 {4 e/ ]6 q3 e" r        x.data = data;+ C9 ?) ]  E$ X9 p" S3 k) n+ p
            return oldVal;
    3 Y2 W  F+ T" U6 U1 d3 ~( v: E: u    }
    2 {) X2 y0 X, m  `7 c7 K! P0 s& G; K' Y# k" z
    3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入! |' i4 C5 O+ O
    3.1. 尾部插入

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


    $ B1 f' V: z  M& c5 k- P' z' O( F 6.png
    5 V; D! ^) i: R! \3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。
      4 a, R; \5 Z% v
    7.png ( q. M4 ~* {' g3 [" g" L
    8 o, O; d/ @5 I
    3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。
      + w8 i! {) T. v7 F# S8 }6 S9 L' h
    8.png
      `, C  P$ a3 w8 L9 ^6 w5 ^
    . l  j( K7 k" F) O  l, l  l9 u# Z三钟情况的代码合到一起
      p& n5 D0 |: D0 b7 B1 x1 ^8 [( d9 @( P% H1 ]- t  s; z
    /**0 R" q4 H4 _, S+ y
         * 链表插入元素
    - m8 t1 S+ O& r& ~     *
    ! K, T$ j8 l% @& M, q' ]     * @param index 插入位置* w1 S5 W% E0 C, g- \
         * @param data  插入元素 被插入的链表节点的数据
    5 `3 Z9 u5 {. E; B3 X. t6 Y( g# `     */
    & ], i* v, z, h9 L. B0 X) c    public void insert(int index, int data) {/ W$ b4 k) n. Y5 W0 @+ k
            if (index < 0 || index > size) {
    ' ]+ o5 D7 X$ s            throw new IndexOutOfBoundsException("超出链表节点范围!");3 C" B8 ^7 `3 V2 t4 F9 m
            }  \2 d# K( _6 G
            Node insertedNode = new Node(data);" c# Z1 n! h( [$ M
            if (size == 0) {
    ) _0 P& ^% M- D# d0 Y" o/ }  U            //空链表! a% d9 r# t1 }/ X/ d
                head = insertedNode;
    ( k& r# d! w% G( |8 s5 c! N7 }$ F/ l$ c            last = insertedNode;8 K2 |- T0 r* l7 J8 R0 c& `8 Z
            } else if (index == 0) {
    * K+ r+ c; u' n5 z            //插入头部
    % h4 D( _' Q; [* F3 F            insertedNode.next = head;
    . ]' n7 }2 t9 |, \& D% ?            head = insertedNode;
    2 Z7 e4 ]2 B; S9 k& L2 w& v$ m        } else if (size == index) {
    , t. w' n, s* t: M. z            //插入尾部  C3 W8 |  O! A
                last.next = insertedNode;+ G6 e  T9 A! s
                last = insertedNode;
    1 M9 ]! ^. i2 h7 c        } else {" a, c- l: {# Y1 q
                //插入中间
    7 L6 W: X( j) X4 d5 N+ [            Node prvNode = get(index - 1);4 s, T: R/ n1 U  ^
                insertedNode.next = prvNode.next;
    2 U5 h/ O6 C: `            prvNode.next = insertedNode;
    + `: x0 X7 k# h) J) X9 q% {        }
    % Z& d: O5 \) \3 i# m) U        size++;
    9 K* }) n* Q2 \& S0 r. ?, U% Q. [    }* m6 q/ ?- _& }) u
    ; `! K& s' b  M# c1 r3 v
    /**
    $ y- i/ u* I% H% T& z     * 链表插入元素; K$ n( ^1 J. C6 r0 F2 Q; I9 w6 ]
         *; ~- O) P6 y' W4 G$ D2 }& ]. P
         * @param index 插入位置
    / W' s7 O1 a' \     * @param data  插入元素 被插入的链表节点的数据% n" p. T! T) _" E& `- m
         */4 @; g+ h& p3 Y+ u3 N
        public void insert(int index, int data) {
    5 C3 ]9 r6 E! n6 P6 F- }1 d" t: q        if (index < 0 || index > size) {
    . K; J( b- A) \5 ~$ f            throw new IndexOutOfBoundsException("超出链表节点范围!");. o/ I% R1 x* ^  k; x4 k! R
            }4 B- G1 x' W) ], f, E9 }
            Node insertedNode = new Node(data);$ k$ G- D- h+ \8 G( `& D
            if (size == 0) {' D5 `: O/ d. I5 L- i) y
                //空链表
    & R2 m- N3 P3 u( t4 h3 n! X            head = insertedNode;! M7 u4 I7 Z( b$ y: N& D
                last = insertedNode;
    , v  Z7 C- f+ ^; l8 }3 m        } else if (index == 0) {% g; f; t  g; |) S# i
                //插入头部! r! ^$ O  J% {: Z
                insertedNode.next = head;; s3 P" i- o. i, ~' `  i
                head = insertedNode;
    0 }* I8 C7 Z8 a7 g. F, O, I        } else if (size == index) {
    , l) S  \8 h; C9 t! i2 G# x/ R            //插入尾部. o. F% Q" B9 J
                last.next = insertedNode;, Y. l- ]4 a; ^! a. z( q
                last = insertedNode;
    3 X  w# c# C5 c  a- ^/ g3 f$ w5 k        } else {
    2 ]- X, d" ~: \0 g/ f' ~7 j, @- J            //插入中间
    - F5 ^! g" [$ q6 {" d            Node prvNode = get(index - 1);) s" m3 {; k/ _, C) l4 |
                insertedNode.next = prvNode.next;
    $ |3 o! b% R. g3 x. l            prvNode.next = insertedNode;  v  _$ x" g5 p2 h- Q
            }
    & J2 K( A" ?  a; H        size++;! p2 Q' S- f% n9 k  y! U
        }7 u0 F' @, s) `8 ]8 O
    4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除
      1 y# F" d2 Y! t) ^4 `$ @
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即
    1 N3 U) _! o) |  i+ O& B# ]1 [可。

    9.png * ?- |) ~0 w5 G8 ]6 U

      N2 O) `; H& [4 g4.1. 头部删除

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

    10.png
    " s$ j$ Y  G( c  L, Z! ^7 h8 P+ z0 d8 m+ G! I! c9 G: M4 O
    4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要2 J( d. c) F! ?/ s& e
    删除元素的下一个节点即可。

    11.png / a5 p  n' s9 \0 ]! j4 n5 R
    ! ~* |- l- w- I; V/ q: d
    * a1 S, N8 Y$ _" r2 y4 a4 M
    这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。1 F# y' C: `  o5 z% p7 L# C
    如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)
    6 ]  C( g! F; b8 u3 Q% ]/**
    0 r% [+ g- G, I& J& c' h     * 链表删除元素( V& U. K# X5 l! @" ?8 C
         *
    3 r/ |* M' b  E0 e  H4 g     * @param index 删除的位置" }$ _% x9 J( a# O7 @4 P  q# N
         * @return 被删除的节点5 a. `# s( x% {* \: E! A6 U
         */$ J, s* f' T7 h9 M) S' A( M6 _
        public Node remove(int index) {+ `( b0 U3 {0 T) o) S# O+ t: O
            if (index < 0 || index > size) {. e9 B; K" D/ t" c: ]0 s! U
                throw new IndexOutOfBoundsException("超出链表节点范围");
    - v( E- D$ k" N5 M. ~; @        }' b+ f) }5 M; m) n3 z
            Node removeNode;) C2 }! q% U- k! |8 _- N+ v
            if (index == 0) {% X  W( {; z8 ], `) _5 q. t
                if (size == 0) {* o6 a7 K* h6 J) d
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");% o. ?7 M) |0 f- o. C
                }/ I; w$ s  ]: i# _: G* ~* c! U/ d
                //删除头节点
    ! Q, c2 w8 B( T# @            removeNode = head;
    & e. V" |4 N6 A' T4 A. j- U* p            head = head.next;* K# D4 U. B( `5 t
            } else if (index == size - 1) {
    # K; B+ F! Y4 C. U8 Q" C+ Q            //删除尾节点
    / T$ `& x9 A6 c) f' S            Node preNode = get(index - 1);
    ; X% L8 s* e# b3 O, _            removeNode = preNode.next;
    - K4 e& O$ i9 K' s4 ]# |: @            preNode.next = null;
    # b/ S# a: u1 }: ]* B$ s, U            last = preNode;
    2 }9 s' m8 Y. v. P5 F        } else {
    , }" c6 t+ }0 Z7 a7 U2 B            //删除中间节点& b# w3 g3 b0 g3 x
                Node prevNode = get(index - 1);
    . l( q# ?. t7 t) t4 f, M8 v$ L            removeNode = prevNode.next;
    ) w/ S, x/ l3 b8 @9 B4 v5 T8 U            prevNode.next = prevNode.next.next;
    ' o( L9 I2 q; F4 M; ^        }
    & z  P2 z8 ^- y% H& A& a" C        size--;+ f) O5 \/ A1 x4 ?
            return removeNode;
    5 ]; A) F1 c" [6 e6 j1 o- {* x    }6 ], y  x' b( H/ h4 k% P2 R
    Java实现链表的完整代码package chapter2.part2;  ~/ v! |3 f/ z
    / I5 |0 y0 `: C7 E4 z7 R' h4 I
    /**6 p1 M8 ~; Q5 ?0 V" d
    * Created by IntelliJ IDEA.- g5 ~( z. P% t; ^, L1 L% b$ g  C
    *
    ; v. Y3 i5 H& l8 M * @Author: 张志浩  Zhang Zhihao
    2 m0 k# h  _% U) y * @Email: 3382885270@qq.com; k; b2 E- X) l$ x
    * @Date: 2020/5/36 s% O7 [# a; n
    * @Time: 13:39, z+ X9 a3 g# E# u# M2 T
    * @Version: 1.0
    5 N1 |' l" x6 H% d; Z2 J3 C: d8 m8 T */3 n7 Q( L% @/ q- G* a
    public class MyLinkedList2 {6 ]. A2 q4 D& C$ r$ Z
        private Node head; //头节点4 a, B- s- ]) X8 E. x) M
        private Node last; //尾节点3 \9 e8 r' c! z4 s' Y4 g
        private int size; //链表实际长度  }7 e7 b% N% f+ \* V

    , {* q* i4 i: Y9 I    public static void main(String[] args) {
    + T2 P  L: `6 q% X        MyLinkedList2 myLinkedList = new MyLinkedList2();
    5 X6 b' Y( s& o* P" E: Z" q* Q//        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    1 b! P. s$ W. J( e+ k5 ]//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围2 B5 d& v2 w$ V' \9 A$ a" V
            myLinkedList.insert(0, 3);
    ( q2 U7 E- m5 B2 D/ e+ d0 p        myLinkedList.insert(1, 7);+ @" w% x/ }6 W5 L
            myLinkedList.insert(2, 9);: @# s$ w9 `5 @/ ~! `+ t" @* K
            myLinkedList.insert(3, 5);: ]8 Z5 L- u1 c% D" {+ ?
            myLinkedList.insert(1, 6);& N4 T5 `9 r2 t
            myLinkedList.remove(0);
    % Y* ^- F  G3 l. f# a9 S, N/ v        myLinkedList.set(0, 23);7 V7 p7 G. l0 P" y2 t9 u. w0 v$ {
            myLinkedList.output();
    $ e' E) c2 w0 B    }
    & U$ Q& I6 d: a: ^9 d7 ]% z5 c4 ?# V+ L+ f
        /**) [% {9 n' a& h3 z
         * 链表插入元素
    8 y8 p& Y. Y6 S$ X     *3 \7 I6 ^( e  Y) Q5 z3 S
         * @param index 插入位置
    ) L$ P3 K* M& m; |# _8 Y' y9 B0 V7 h     * @param data  插入元素 被插入的链表节点的数据
    ' v7 c0 q5 X7 c* p% ]     */
    2 M2 |3 a) E  r! m    public void insert(int index, int data) {- |( c5 |( X4 B! x4 k- F
            if (index < 0 || index > size) {- h3 Q  E, y1 C1 [
                throw new IndexOutOfBoundsException("超出链表节点范围!");" J' O7 X6 J1 I# d+ K+ R" Y( I
            }# h* p; {# f+ ~: w$ }, d1 x" l
            Node insertedNode = new Node(data);. W1 D# Q! Y3 p% [
            if (size == 0) {& _. ^' [4 m% t
                //空链表
    * P7 y, I9 y) z* w/ `3 ]0 f            head = insertedNode;
    5 F- v& |# m- E( e            last = insertedNode;( @" z' A+ }& }9 y& z  j( l6 @
            } else if (index == 0) {
    3 @$ C4 q. v! H. ?            //插入头部
    ! P# H4 t" Y$ M! X8 n9 H. R5 W            insertedNode.next = head;
    ' }5 b5 n" Z3 K! U* K- Y& k1 \0 o            head = insertedNode;
    0 q8 h8 Q* z5 p' ^. H' M! ?0 D        } else if (size == index) {# ]( s5 v3 l2 X! W
                //插入尾部* d8 O7 S; S) J. m3 O
                last.next = insertedNode;5 V) ~" R4 H. K
                last = insertedNode;4 M0 _3 k* ^2 i" T$ L
            } else {
    . Y0 _& U% _5 t# S6 B4 v            //插入中间
    1 ?8 u) u4 I" c            Node prvNode = get(index - 1);7 j( a2 w4 _. O# d# Z( ?3 F8 z
                insertedNode.next = prvNode.next;
    % e& d  {$ i- M# |            prvNode.next = insertedNode;5 K/ ]8 R: V" k4 ?# ]* i6 O" Z
            }
    % S6 D  v: R# b; ^" r2 c* n        size++;
    * D) B5 X. r' M2 `% K    }( Q1 D: K9 i; K5 Q2 v# j& `1 W

    4 S) D8 Q4 G( I6 j' y5 O4 R    /**
    " g' T7 j; y. w5 N     * 链表删除元素, Y/ {' \& j' b
         *2 {3 J; X1 h5 C
         * @param index 删除的位置% ]. O+ e8 q/ G9 [2 P
         * @return 被删除的节点: ^; V5 b& R# @/ z+ f1 \2 u0 @. ?3 p8 K! J
         */2 N6 k) g& N5 ^1 @
        public Node remove(int index) {
    + [; x& O  y' v: h3 G        if (index < 0 || index > size) {7 m$ u, N3 E# K, z% n
                throw new IndexOutOfBoundsException("超出链表节点范围");
    . |  w5 ~& o  W4 B4 P        }
    4 j0 d! d( q* _0 L! ~4 @        Node removeNode;7 E! W) ]* I" V  k" m2 y( g- b( a
            if (index == 0) {
    8 s: b3 O# Y# }; m- O            if (size == 0) {- P) z8 c& v, w) f
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");
    + S% H; O0 s  T& J4 b' ]) V& B            }
    / L% ]2 L# l( Z3 F2 C            //删除头节点
    2 y+ `- W; _0 s: {3 H" F            removeNode = head;
    ( a: y0 T' h& B  b. Q            head = head.next;/ O" J6 w0 b6 ~, D3 P$ L, G
            } else if (index == size - 1) {4 J% j9 u. n5 i7 c
                //删除尾节点
    ' a! W5 t3 {: S# u& `, K            Node preNode = get(index - 1);( E+ A0 x  K: x) U: A
                removeNode = preNode.next;+ t( \# ^/ n( r) _. M, B
                preNode.next = null;5 U3 W/ |" J& b7 L% v2 x* Z
                last = preNode;
    ; ^7 C9 J2 S+ [0 e3 x! G" M        } else {4 q8 f8 E$ g7 N3 R
                //删除中间节点
    - }* z8 b( L1 {( E% {  h            Node prevNode = get(index - 1);
    ! h7 X: E# k( ]            removeNode = prevNode.next;1 H# o" g( \1 k. v5 P( v
                prevNode.next = prevNode.next.next;
    ; K! {% w- m( ^; t7 Y0 q; |% o        }7 {: l  F5 L1 k+ ~7 z
            size--;+ Z# M. I5 @( K/ Y1 q: ~
            return removeNode;& U8 R! Y. B  h: x; f8 y* y  R
        }
    5 D4 t6 {: v) H) H5 I
    5 M, X) n* e% F    /**9 R5 D  ^% }9 N" q
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。" h' N6 v7 p$ b: T7 k/ J' h
         *
    . G. w$ C2 Q# k: i  n     * @param index 需要更新的节点的位置; l0 K9 J  ~5 J9 \/ l
         * @param data  新data
    : k3 e1 E4 q# J; p) F. u$ k$ @+ _     * @return 旧data
    2 d, \# z5 A% v, H5 _4 l  @     */# u9 B* N2 a" `# N! T3 b1 o" o
        public int set(int index, int data) {
    ( |4 }6 W( k; w0 D  c6 A        Node x = get(index);# q* ]; z$ @8 N4 a) A' _. {$ }$ v3 W
            int oldVal = x.data;- Z. O0 ~$ U7 L  h+ }
            x.data = data;
    * `- Z6 n8 G" z* ?1 T/ C        return oldVal;" z  L, L0 @7 s% t# Z) X
        }
    9 Z0 J8 r# M1 k4 _( L& c, `: F: l% K4 f9 c5 m
        /**
    5 }& ?3 q0 \0 A     * 链表查找元素' V! @( U% p6 E! M
         *
    7 n4 a+ _1 R# `: l     * @param index 查找的位置8 y4 H2 b! S" O! s
         * @return index位置的Node对象
    * q/ [; t! C' @     */
    . {9 J: x% Q4 E% o/ t! v7 \    public Node get(int index) {
    : S4 K- l8 i9 h1 y0 U; B        if (index < 0 || index > size) {; q9 L2 r. J& u' C
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");! d2 w2 B0 y& y4 ^
            }' m# j! h& L) _0 F
            Node temp = head;) G1 C/ J# ]6 y$ V; A6 q
            for (int i = 0; i < index; i++) {  D0 [( _4 q: C1 _' D4 i  O
                temp = temp.next;
    ! }+ j. s! G7 X& f, v& o        }4 w+ S, T# J4 s! P8 _6 c& E
            return temp;
    : u, h" Y# Y7 Y8 ?    }9 g6 Q8 b( T/ P5 G
    , ~7 P8 b; Z4 a
        /**
    ( H0 F) J5 r/ K3 }3 F     * 输出链表9 {: }$ O/ j+ d+ M9 g- O$ L* D& Y9 P
         */
      i1 c% m# K. @% l    public void output() {9 H) w; e& I* g3 o
            Node temp = head;! q5 X* B- \9 b: ~( X: e/ n
            while (temp != null) {
    1 \! s3 i1 O7 T. n% F            System.out.print(temp.data + " ");
    $ X# {1 p$ ^0 Y5 \6 E            temp = temp.next;4 C! J, j& V0 [) {, L7 J
            }
    5 V# z4 p6 `" U- E, v0 A1 Q    }5 q) U! H' q2 ]

    ' Z6 ~2 i, P* l7 D3 }    /**9 m2 I- p( S4 v  }
         * 链表节点
    , r# ]; O& Z  Q4 }# Z7 }- I, O     */8 E5 K( }7 s: f6 X0 ~+ d+ W
        class Node {
      J. o8 \0 d, Y5 e; j. a/ E9 Q* w        int data;) U3 a. l6 c: V/ j# I
            Node next;5 e! M' l; u  D" l' y

    - T4 @9 s4 d5 H& o" Y8 m        Node(int data) {
    4 q8 y- o, I5 S. z4 [! n" a            this.data = data;. X4 b" |, o5 _/ W/ W
            }
    9 v/ x; B' W6 \$ @% P& r    }
    - ~6 v, `4 \' C: e1 V" m. b}
    5 b" f% V1 l, y3 p# b, a1 G7 F( C+ b0 J( d- c  M, \. t' s1 j8 }

    . G7 M1 \; `( m! s! z2 L二、双向链表 12.png & i6 o% x7 s4 ?* v' T0 G! x6 K4 ]# V
    双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。3 [( n" z# z; L! `6 g# S

    : S1 w  N7 Q- R, @% C, @, d
    ! S! `+ Y# t0 C7 {# e+ _
    ' E- o% b# K8 j  D% O9 |+ y; q! e+ W6 U. `# N) i7 y/ T
    ————————————————3 u9 F: `/ y" ~/ b6 C* m$ a4 n; e/ z
    版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。# w3 R' |, U" n3 x5 Y" k
    原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468/ D3 d2 H, t3 O: p! a
    + D1 J: W9 J, e6 h  \- e% Z% b

    : h8 T7 S5 x) B8 H6 D) h7 _

    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 15:40 , Processed in 1.308673 second(s), 54 queries .

    回顶部