QQ登录

只需要一步,快速开始

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

    ; L( G4 H% e4 n  n8 [【Java演示】什么是链表?数据结构; ?, x% {! N/ |
    一、单向链表
    5 B" W; x; ]: |& h; t& |) P4 {4 A. Y9 |  s
    1.png
    0 c1 x2 S# P% V+ N: Q# H链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。# C: ~6 O: j6 g) f3 G1 I# \) ^
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。! P3 J% {3 n' g5 j
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。/ Q* c- |, d% E6 F/ j" V; p! B+ X% c

    # `' n* S, I: @6 u4 O什么叫随机存储呢?: s1 D1 J" T5 h! B

    ( p8 K8 D, {8 K9 c5 f" a如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。( _, z  v+ N, j( I
    上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。5 T. F; e3 m. G- c2 p
    3.png
    / a  d, m" L. i% v1 E1 z2 @  j
    , v" w1 U) N7 W- L( s, h1 q

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

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

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

    4.png 7 `8 @0 R% f9 P" ~' Z# R6 @

    : N2 D/ F4 m0 |. _' a  h3 i/**9 g- k" I# v8 @
         * 链表查找元素
    $ |* V7 s* T6 o& g2 K$ F; \     *" B7 N  h2 \" a5 O# j
         * @param index 查找的位置1 x- X/ i8 B1 E! K1 h
         * @return index位置的Node对象$ r0 j4 M: G5 s1 s" n
         */- ^+ Q$ R2 a( K4 ~" v: z% ?
        public Node get(int index) {
    . J. v6 X' J2 A) Z4 Y        if (index < 0 || index > size) {# H' D# ?8 t0 J5 Z6 H5 a: R
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");3 ?3 Y2 V+ q& {* w7 \$ B& E
            }& ^+ Z( V" B* O' X- B' A
            Node temp = head;
    6 X' v% d4 @2 g        for (int i = 0; i < index; i++) {& `8 P) F/ `) A& f) A7 s) f. K
                temp = temp.next;+ s6 s( n4 j2 A0 l
            }: H: l, y( {2 C) }
            return temp;
    / H# z7 m* d+ }9 h9 l1 W    }
    7 y$ i. C0 J9 j* p( S5 v0 |; Q/ Y- j" z" _, k4 P5 |' `

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

    2. 更新节点 5.png 8 F, h; w+ T" o* D9 I

    * ]! k$ F6 _  P& A" ~. b如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。" l4 F! g  W# I! t' h* ]# B; A' h& D
    如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)( S$ A( r% ^, c# V5 }; L
    /**5 B* ~. D7 a" u5 j) b
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。3 T4 }- d0 k. T+ I/ J
         *9 e& [; ?; f" J2 A
         * @param index 需要更新的节点的位置
    9 F: d6 V$ T3 K9 @2 U     * @param data  新data8 X+ L# _- X' M$ ]
         * @return 旧data
    - G! k! s/ N! k1 Q     */
    2 x$ j0 v* _4 q' g# @3 T    public int set(int index, int data) {6 T2 S2 \3 X' Z8 J4 h, q
            Node x = get(index);0 ?: [# R- G) ]
            int oldVal = x.data;
    1 Z( \' z; q2 d+ N: I% B* L0 F0 m        x.data = data;+ q2 Z  S- k0 t2 K, {# V3 a! `; r) \
            return oldVal;) _" V/ c( @, {* ?3 O
        }
    : F2 `9 ~* z7 Q* x
    - r( S$ X% w$ R1 A9 I3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入/ x# ]' H- w+ V0 Y! Z
    3.1. 尾部插入

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

    ' O5 }& Y2 T& B4 e- O) K. v
    6.png
    7 M  L2 I/ c$ ^7 k  K2 t3 a3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。7 h" i+ D9 q" o( M: R! _; b
    7.png $ {" r5 a5 P6 a, k
    + l9 x, D7 ^9 c& M0 m
    3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。+ c( r& Y$ q: E0 N8 v7 h
    8.png 1 L7 u4 N1 l" j& q9 r7 M
    ! Y* B3 P4 C6 [
    三钟情况的代码合到一起
    6 b0 j  E, ]5 w. c, g$ z" `' A
    + ~$ z( X$ H0 g/**; U9 f5 u" B  X& }/ M
         * 链表插入元素8 P# P- v0 p5 ^& E
         *
    # \6 V1 P  ?. |" h" O' b" I     * @param index 插入位置
    - A; i+ Z$ r) I' V     * @param data  插入元素 被插入的链表节点的数据, O6 G! k! k7 E! H
         */
    / ?5 L0 Q! g& [) G    public void insert(int index, int data) {
    * }1 K) g/ X' s6 M$ C" g        if (index < 0 || index > size) {
    * F0 T. s0 R: ~( H: }0 n5 f, U            throw new IndexOutOfBoundsException("超出链表节点范围!");9 t, o  [+ p- y6 T2 Z# d
            }) j2 j6 t1 L  g* [+ M/ c) X9 I4 C
            Node insertedNode = new Node(data);
    $ H! f+ X* B+ b  d1 u0 g        if (size == 0) {
    ' \# U/ j! N# ], m7 Z! W! D6 g            //空链表
    / ^. o. O4 g; Y            head = insertedNode;) a7 E. W" @8 H3 s9 x
                last = insertedNode;
    & g4 q; U5 C/ C% K  x7 B# \        } else if (index == 0) {1 E; d. J5 y: x* L0 }* K
                //插入头部9 E' `  T5 ^1 _* j5 I
                insertedNode.next = head;
      m& Y0 T3 [& T- U2 a6 j            head = insertedNode;
    * ?" u- O4 f6 t        } else if (size == index) {
    : O; e0 v! z# }, m            //插入尾部
    ) R2 S6 h7 N0 a" }8 Z2 @6 |$ B            last.next = insertedNode;' s8 I$ V! F: i* ?. }
                last = insertedNode;! f4 G$ }- R2 r! ]
            } else {  A0 i  a) e6 b
                //插入中间
    9 \2 t) Z; h# z6 b% x) S            Node prvNode = get(index - 1);4 O8 N" g" ~1 G3 \2 J7 b% t
                insertedNode.next = prvNode.next;
    / z4 J: `3 Z5 m$ z8 v) W9 r1 \7 H- X            prvNode.next = insertedNode;
    ) b" n2 [8 g# ]        }# D( `$ s4 s. v, {( P7 X( Z: n' N
            size++;
    . u5 H- u. i1 p. Q* j) U7 r' g    }
    ' R% N3 z' c" B5 ?: m0 q0 V& j3 @! \! d" L4 w
    /**: F6 `6 ], A6 J7 M9 l  \- L( Q
         * 链表插入元素/ H6 o; q1 C& q  e8 d4 ]
         *# h1 c6 }! r$ a' q$ u; @
         * @param index 插入位置
    / Y( C* g2 V) u" Y9 Q9 r     * @param data  插入元素 被插入的链表节点的数据: G; G% t$ Y. O. {9 B* q3 G7 T
         */" [. F0 b+ d& G  P) e1 z
        public void insert(int index, int data) {
    4 Q" m! Z, A" ~, ?$ y( U; w9 w        if (index < 0 || index > size) {( Q3 e- k' {1 O
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    ; @) s" b* Z/ v* R        }! @8 `/ w" _$ T5 F7 O
            Node insertedNode = new Node(data);; S+ Y, o9 z) k. c& h) X# W5 T
            if (size == 0) {
      D9 \) s* R  v% I2 d' p0 z            //空链表
      G( b4 H$ S8 z2 R% t* `& t            head = insertedNode;  N# {- M, C' ~) R; [) h) k
                last = insertedNode;
    . i; l/ v% ?9 e" H        } else if (index == 0) {5 }0 `/ v9 _8 [4 D1 \
                //插入头部( t: S/ Z2 U( y* `% H
                insertedNode.next = head;
    7 K/ }% U1 Y2 }( L" }            head = insertedNode;$ z/ H! m: p! f. I) z/ T
            } else if (size == index) {) \( k, [+ Y- y
                //插入尾部
    % @  `% \) }( ?1 A6 X( [            last.next = insertedNode;2 t9 U# H7 o' @; d
                last = insertedNode;
    ! o; K4 ~( F2 S' ~+ e        } else {4 N' D% G, @4 q9 O5 A) @% G
                //插入中间8 [2 S' I8 V$ y
                Node prvNode = get(index - 1);
    ; I2 R+ X& ~, c% _9 O            insertedNode.next = prvNode.next;
    & G" Q. n' _  s/ Q0 O5 g' C            prvNode.next = insertedNode;
    ; t5 y* F0 i! S) \        }
    3 b3 w1 E7 j) ^% a. Q* ^3 X3 A        size++;3 [4 `/ m7 b& S6 b4 |
        }; J* o* z1 m  D5 r5 ?# H% x& h6 ^
    4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除
      / i8 T5 A" U8 ^5 Z, b, I# k1 m
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即% Y' z1 `" J8 p
    可。

    9.png * I# f& V8 R; b! m, u- M# u' }/ O& I( u
    : _2 V, r! u% o( `! Y4 x% `5 z
    4.1. 头部删除

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

    10.png
    ' K! u2 Q" i- m# ?, O# l+ P( {; A% L7 p( l. d- }
    4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要' `  d9 H( X5 R6 V+ h6 y. Q
    删除元素的下一个节点即可。

    11.png
    - v5 C% f/ M# l* r! c" M- ^1 O( n2 _  ~; x4 Q7 \  p1 A; h
    9 t& b+ n. Y) J  Y! z- |: S
    这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。- F) H5 V, U* _
    如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)' ^3 q' I8 r2 r' l: w4 t
    /**
    " t* b0 v4 I0 p8 k     * 链表删除元素
    ) `) l, d$ n7 @& U/ G4 ?     *
      m# m! Q* V3 T. e5 U     * @param index 删除的位置
    ' C4 A3 s5 D; m1 \2 b7 D     * @return 被删除的节点8 \) @+ j6 g4 v- m) {  J
         */
    4 R" Y  M1 g2 z. i9 ^( l% K    public Node remove(int index) {6 w" q4 n, v7 b' T* a! f
            if (index < 0 || index > size) {
    ) m8 a; y' w% K- `            throw new IndexOutOfBoundsException("超出链表节点范围");
    4 ?9 _! J$ E0 U( F6 g, {        }
    / D+ b/ ]8 T7 t! _3 W        Node removeNode;
    4 }% P( H) y2 G) s) q1 q% z        if (index == 0) {
    3 Z; I3 e& y. _5 ~8 z            if (size == 0) {
    ! b. l! N8 K+ B  R$ ~, ~                throw new NullPointerException("当前链表为空,不可以进行删除操作");8 R2 a( l  R4 p* d! O! B8 P
                }
    " C" Y0 {0 v" A            //删除头节点3 I: `( ]& {" g
                removeNode = head;
    + v8 m& A( a# F% Q" a$ z- j            head = head.next;; f% z) G' |7 N) q/ X
            } else if (index == size - 1) {
    . H) @+ H/ {3 u: p8 x0 ^            //删除尾节点9 h( k3 r# C& g3 x$ @0 s3 _
                Node preNode = get(index - 1);
    9 n2 u$ f$ C, g; e( `; C9 K  S  K            removeNode = preNode.next;
    * |! k3 s. }, }4 W  {* W* C            preNode.next = null;& \. y- H$ J! W9 a8 f
                last = preNode;: L# l) }( i) J
            } else {$ b, Q5 x  g/ n+ ~/ }
                //删除中间节点
    1 R# c: @/ t8 K            Node prevNode = get(index - 1);
    0 ^  W" Q, X" v& X            removeNode = prevNode.next;
    6 P6 H1 K/ `9 R" r) D            prevNode.next = prevNode.next.next;
    ' P% q9 z  X- ^  _. b, M" k+ C        }, y; L* M! ?5 |. J  X3 `, l
            size--;
    ; U6 Y. p/ a  Q2 D) K+ s* R+ Y& q( S. u        return removeNode;
    5 a7 F. G9 q2 U8 Z  c    }
    1 Q0 I) W% M1 f2 L4 ]# `. X/ JJava实现链表的完整代码package chapter2.part2;
    1 z& B, O" |4 c6 D( W8 |
    , r8 f' p# N: i6 M" e( `0 i! h/**
    . W( O$ `5 q7 [5 k+ j8 O * Created by IntelliJ IDEA.
    / `; f% E5 X4 n/ P *- O, ]  p( ?" k) @
    * @Author: 张志浩  Zhang Zhihao4 E) y; B- F. u) i9 _, u
    * @Email: 3382885270@qq.com8 k; W. ?9 r' @7 ~! w& |" B
    * @Date: 2020/5/3
    0 h$ g6 i1 E" {* v9 G) E# p * @Time: 13:39
    & v( _$ ~' r1 q+ Q9 L2 I * @Version: 1.0
    : s& n/ a; Y: O3 n7 X */
    & y* {; {2 d& l9 Z: Hpublic class MyLinkedList2 {. I0 J8 {# [) {! X9 n: H6 D
        private Node head; //头节点8 u; V* V" r2 \/ x
        private Node last; //尾节点
      X/ m3 K3 g" E' H; C    private int size; //链表实际长度
      I0 Q7 U8 }- Y: i5 c+ [# C$ S  L+ u9 v
        public static void main(String[] args) {
    $ |" H/ C+ a* U, X" \0 z        MyLinkedList2 myLinkedList = new MyLinkedList2();
    % F1 D" e- A3 S- a4 ~/ K1 E3 Z//        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    2 l* n1 W% U9 ~% N//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围& B+ p; _0 t1 j2 z$ [' T3 ?+ ^
            myLinkedList.insert(0, 3);1 |; ?& Z4 ?9 R  L9 E
            myLinkedList.insert(1, 7);
    , H; F- C8 M: U6 E, |        myLinkedList.insert(2, 9);- I, }+ Q& }$ i) C+ y4 j( f
            myLinkedList.insert(3, 5);, r8 m6 u4 f  `+ }* K
            myLinkedList.insert(1, 6);
    3 s* b9 m% L( y5 A% [/ |        myLinkedList.remove(0);
    6 r2 ^, R2 o( |6 x        myLinkedList.set(0, 23);7 y9 }( O6 J) z& v" y+ K
            myLinkedList.output();
    2 }8 O2 W: w1 F+ U9 c    }
    5 |: p. c! T& W: b$ A8 S  }
    7 Z) |7 k2 D9 E    /**4 Q" [7 A  U* g/ G5 E
         * 链表插入元素9 R$ V1 p1 D0 e+ |3 G9 m6 Q% X
         *
    / f, ^/ q  ?0 E' ]0 V     * @param index 插入位置
    . A5 X/ P) p& S& C     * @param data  插入元素 被插入的链表节点的数据- U/ G* `* P* W2 |6 C7 l
         */
      k4 h6 w0 z- O8 d+ k7 b* @    public void insert(int index, int data) {
    8 y6 z, P7 r* `, J! _        if (index < 0 || index > size) {
    & i8 G9 h4 W4 ^3 ^9 n& l( f            throw new IndexOutOfBoundsException("超出链表节点范围!");- ?9 K' V& T% {  N" f+ `5 B1 p
            }7 a/ u2 u% |2 F& R  Z8 Q% D" R
            Node insertedNode = new Node(data);/ O2 e  X$ E1 J4 l
            if (size == 0) {( m' `, h- g$ v0 V$ v8 i) j6 a! b
                //空链表" q5 U$ t+ o7 E" G/ P
                head = insertedNode;
    5 j$ _/ Q. P$ E            last = insertedNode;3 ^" k( X) a: W; Q& ~0 u0 U3 Y
            } else if (index == 0) {* _( `! ^4 j$ |- p; m
                //插入头部; n: z9 b, U. F/ y
                insertedNode.next = head;; l+ B  p" {' ~. l; R
                head = insertedNode;
    8 @! r2 x0 v  D! Y& c        } else if (size == index) {5 {* W% F- j9 p& T2 b
                //插入尾部
    & v3 K6 \5 o& k( W/ Y% ^! Y            last.next = insertedNode;) U8 S# ~$ |  C- [$ k3 H: f
                last = insertedNode;
    $ c+ }# F0 R- P( M1 T7 k        } else {! V* t0 e# m2 r; l; X
                //插入中间! O3 x, X8 ^8 ^: G
                Node prvNode = get(index - 1);
    ( l% V4 H+ f7 q; d2 Y& S            insertedNode.next = prvNode.next;
    % X$ L' l/ ?! h7 F, Y3 U            prvNode.next = insertedNode;
    + i+ }9 E% Z& y2 `9 f        }1 |! \1 ^. l. `; m
            size++;
    : \% S- h- T/ K2 t5 S0 f4 W5 s    }  ^5 p6 E) Q+ B4 y* z
    5 [6 ]8 Q# c; }! _
        /**
    , c  d; h2 p& k* R     * 链表删除元素, b( }+ h6 B  L5 q7 q; g  V+ I
         *) T# z9 K& x8 i, E7 _% I8 A
         * @param index 删除的位置
      y  M* z- }$ O4 |3 M     * @return 被删除的节点2 U; N; s+ ^& q
         */( S5 S. t, u- m
        public Node remove(int index) {
    3 W; C1 }! B8 ?        if (index < 0 || index > size) {
    + M( V5 R: v6 u. @9 E  Q            throw new IndexOutOfBoundsException("超出链表节点范围");2 I; d# F) y/ V- T& l
            }5 Z! M. f* ]9 u! @: L: C
            Node removeNode;4 m+ n! @4 p. Q- d" q
            if (index == 0) {( S+ M! b) r1 X2 {' B
                if (size == 0) {
    0 a" Q6 E  F" p1 T: p! C. h5 B                throw new NullPointerException("当前链表为空,不可以进行删除操作");* Y0 o: g  y+ U9 e3 K+ b! A
                }
    % R% c1 u9 J6 K: t+ q            //删除头节点
      o  C4 V# o1 @* L, T* ?            removeNode = head;) J1 k4 a# W4 {- B( z- N6 w
                head = head.next;" z! q$ q" \# o* C. g
            } else if (index == size - 1) {
    9 i7 L! K- h  A" N  ]            //删除尾节点% F, s4 n7 O# D4 ?* a
                Node preNode = get(index - 1);
    ( R  T5 J$ }7 H: M1 \8 ?4 d6 K            removeNode = preNode.next;; `  z$ [! O4 }: @  N
                preNode.next = null;9 M5 S* \) j5 P5 N
                last = preNode;$ e" I" a$ C2 ^/ f) a& f
            } else {+ M3 T9 r% [( r+ U) m5 v5 t7 k
                //删除中间节点
    ; j: Y0 ?. b0 V9 O            Node prevNode = get(index - 1);
    : ]* B( @3 n% w, s            removeNode = prevNode.next;
    & l- U2 o) V% S/ g. o  G            prevNode.next = prevNode.next.next;
    ! l1 W' @; U5 W0 t        }* H- B/ m2 `* \' R$ h% [5 p4 V6 }
            size--;$ p* q6 b2 N9 d; d: a" N- X
            return removeNode;% t+ w" j% s- T/ L2 }7 X
        }5 K6 E/ C8 `- V/ r
    4 m( A( G+ p! F+ h# r9 r, d
        /**1 |: F6 M, j* c: ~- h1 Q
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。: {% k2 `  d- S: L
         *
    ' `: X7 y  u5 Q+ K     * @param index 需要更新的节点的位置- B/ ^/ Z  |9 Y1 c
         * @param data  新data6 }# R/ H; f8 N( @& Z6 {
         * @return 旧data
    2 t6 M# o! x4 C' x. {     */
    , x( u  v% o# k  m! ^( I' b    public int set(int index, int data) {5 H* k: f3 [6 o" ]% o1 e5 A
            Node x = get(index);/ Z4 v6 R/ U$ ?/ z& z/ q5 ^
            int oldVal = x.data;
    & k, S( Q6 s% }0 B# J: }) G        x.data = data;, o0 I/ Q- `3 n: S% h, j7 `
            return oldVal;
    4 E  I9 S0 n: \; h& @    }
    5 |; H( {( C/ K0 f6 W
    9 g0 q% [6 i4 ]3 l  \    /**' r% O) e/ O3 a6 d' j% b
         * 链表查找元素
    7 y. G7 e# h2 t( W     *
    3 C+ E5 b! }# f! y* D/ n$ d     * @param index 查找的位置
    % l8 J& E& V% C" F2 \. W     * @return index位置的Node对象) g, X8 R3 g4 y+ p
         *// _. M: G; P& n( I$ Q
        public Node get(int index) {' t( G& \/ x) |; v4 B- h& o
            if (index < 0 || index > size) {
    5 m3 U2 L. x; s  Q( {1 p- v+ F            throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    & v7 `# R1 y  f+ m. Y        }' w2 x  j. F2 Q- b# j
            Node temp = head;
    & S, |; x& h! T) i9 h! u/ E. ^4 K; i        for (int i = 0; i < index; i++) {
    ' `* _  S3 F* E8 d            temp = temp.next;" x$ }$ q9 P7 C8 y8 Y) _
            }
    6 C% M9 I' l/ ~  G        return temp;1 ]$ F0 Y  }! S$ k6 r4 r7 O
        }6 h! b$ v) p- @. h( ^
    , w4 G( @$ |' C1 ^+ K
        /**
    1 h: n0 q) V7 ?! i) [' t     * 输出链表; J; H  S, B! E7 X& d
         */3 z. I3 d% t+ w
        public void output() {
    ; @0 f+ e0 w# |        Node temp = head;
    % q# R9 l: y* e4 y2 H. W1 i& {6 K        while (temp != null) {$ U% D2 h* _* Q
                System.out.print(temp.data + " ");
    & _6 q3 a. d8 N' g& c9 c4 u            temp = temp.next;
    & e* h/ O$ U0 i2 u. }        }
    ' A% e" R7 o9 o+ z% W    }
    5 F9 p. K' k  ]( b$ J1 n% a
    4 W7 F9 \: x1 |    /**. H/ f8 h3 G2 y( v* s  H
         * 链表节点- D% O- K5 ]: O
         */
    4 c5 U9 {6 M* @3 j1 Z5 }    class Node {9 w- _/ z) M4 c' f. t7 c8 {
            int data;
    0 M! V2 |& K/ u" P' w, o        Node next;& i# ]0 U, {9 a/ k  U% T
    1 T4 i% Y) h# D( M0 M. l6 d* A
            Node(int data) {8 |1 Y3 o- u7 |% k8 ^/ M
                this.data = data;
    - d! d7 }* U+ s" i  Y- V, W/ m. L* \        }+ i- r% F/ K$ ^7 p
        }; o! A4 o9 J0 T' H# a
    }( F9 g4 |$ X' {) @  Y- r

      @$ f, h$ D5 l7 D/ l2 Q' p! @6 h  J) p9 ?9 d7 z, ^) {
    二、双向链表 12.png
    ; \/ G+ m: t- g  p2 B双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。
    7 q' P& l' e; Y, |
    $ q, ~% [/ T- R( j
    8 l* F& ~5 Q8 }% M3 s5 ~
    4 m8 y7 y4 V  [: p
    4 f3 i5 O! E4 L4 |————————————————
    ( ^, {2 W% g! \: L' J# h1 v% ?% M版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
      H' Y7 C6 M  s3 q3 i原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468
    9 l7 M3 p  x0 n# r  u8 [+ U
      s, h7 K6 s$ |9 A& w/ Y% [% b" T2 `
    ; q" A: M! P: l8 u/ w+ U: c7 _

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

    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-1 02:28 , Processed in 0.444791 second(s), 54 queries .

    回顶部