QQ登录

只需要一步,快速开始

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

    ' Q0 w- ^/ t* {' F0 N1 J【Java演示】什么是链表?数据结构. p/ X. M8 z3 [/ ?- g
    一、单向链表5 E' \( F, G$ ~, \$ K0 w

    ; M; Z2 y3 ^3 F9 z; z 1.png ( ~  ~! G; H$ g/ \& K. _
    链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。# A/ Q9 X) j4 m9 y' c- g1 U
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。
    ) Y2 t# p  Q1 q% J& X) Z9 K+ q链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。
    ) Y4 @- u9 V- G  g4 x3 J- }8 f, I. i$ z5 j% K, m0 z6 E( I
    什么叫随机存储呢?8 p7 [; p, I, s2 a) @" F1 ]
    8 h" V8 D, `" x: G0 P! K
    如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
    5 r3 W( F$ K7 R' j上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    8 o0 o) ~1 r4 D% T4 h 3.png 1 |0 C! Z8 `+ V4 Y! N* h

    0 [# {# k" t; Z6 I/ n

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

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

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

    4.png $ A5 ^* c) _. [+ R* @9 |

    5 @2 w3 w3 ~/ S& i/**
      I$ a( k; U- y- |$ M: d1 X     * 链表查找元素
      F. D( S3 s8 m     *
    2 }9 _8 ]) B) R7 P& q" J' Y& d     * @param index 查找的位置+ b9 `6 q  X- h5 Y" R. ]" j! U0 a2 [: O! ^
         * @return index位置的Node对象& L7 V/ L* Z: s
         */
      R" y1 ^# {* ~5 b8 j+ h    public Node get(int index) {
    ; x9 H. i/ z: g$ c  N2 n        if (index < 0 || index > size) {
      b+ z, y8 b: h7 ]; x            throw new IndexOutOfBoundsException("超出链表的节点的范围!");# P" j& t! s3 X1 I
            }
    % b7 {1 S8 B. I' c) _$ \, s        Node temp = head;
    9 U/ N( E# e/ i7 W        for (int i = 0; i < index; i++) {% ~2 j8 J) L( e7 u# g! Z
                temp = temp.next;, t+ S4 T& K6 ^4 y' w4 J
            }
      q8 d8 e0 M$ ~0 @8 f" _        return temp;
    5 P; Z- O. B4 ?+ Y    }0 `6 V; \, y) E# n
    " h, ^4 `; T- j% i2 K

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

    2. 更新节点 5.png 6 |4 G6 ]6 a1 P9 d) m3 {

    / ~4 n( _2 T6 m: a如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。
    9 d( Q( o3 e- Z. a: S如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)
    6 I$ I, k+ U, l7 I1 J/**9 W0 ?5 J! J: i4 x- y. G3 }
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。7 S4 k& j9 S. O
         *# F5 P3 }& J8 H! y6 I) h# Y
         * @param index 需要更新的节点的位置& K& n7 Q7 G; a. T
         * @param data  新data4 R2 f2 O% l1 \8 ^$ Q. U4 ]
         * @return 旧data3 l* {6 @' `  U: F6 k1 R5 V) t
         */5 c  _" j" e+ p3 k5 U. C: S
        public int set(int index, int data) {: w) }5 o0 |0 d$ Q
            Node x = get(index);  v+ y" x) A$ q& _, @" J
            int oldVal = x.data;4 r" }+ ]! j9 w8 w! K6 F# `3 p% {
            x.data = data;
    / b% B/ n2 F4 d/ U. ~1 D+ r        return oldVal;
    $ w. G# S" f; x, h: @' a9 @, e    }
    / g8 g# F7 l+ d6 [1 T, u/ W# W. k2 g3 w) i1 [  I# W5 b* x
    3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入' X2 J, [' ?/ Z: y5 R) l
    3.1. 尾部插入

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


    . Z3 `, G+ R& m7 P 6.png ; u$ R; g- L* j; d6 T' D$ n2 q
    3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。; g  _4 e+ b# W9 R
    7.png
    " B6 e" s; [; F1 }$ B9 r; E- K- Q5 O7 F
    3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。8 r6 N& x/ m6 s6 ?, t
    8.png 0 H9 x5 Q0 p+ Z

    9 T! `1 F, M$ }% V, b6 Z8 f; O三钟情况的代码合到一起! F! h* K9 c4 P) G
    1 ~* o4 w: l- [. H, X, U
    /**
    ' ^) x' |. `. J     * 链表插入元素
    4 h! n4 F. W; Q0 I* s+ W     *
    , d7 z( {  Q5 e: J, P     * @param index 插入位置
    9 G9 Y, @- ]4 \/ a0 B! _     * @param data  插入元素 被插入的链表节点的数据$ E% ~; B$ w, Z% O2 e
         */! i) A3 K2 l  `
        public void insert(int index, int data) {
    2 H) ?0 ?/ D6 b# A& y        if (index < 0 || index > size) {
    3 ^/ `/ p, y# Z. `$ m6 a            throw new IndexOutOfBoundsException("超出链表节点范围!");( j: o" X/ O, `8 x9 z
            }
    5 ^& e- j$ a' L. B2 g6 w9 _2 p0 G        Node insertedNode = new Node(data);; Z6 A" R3 q7 j4 U1 }
            if (size == 0) {; `; O: n9 t- n1 O' t- W6 j: B
                //空链表
    & u" R7 ^! ?6 m8 o+ F2 D            head = insertedNode;9 p3 k! X( f/ Z" |* a' w$ Y' i( }
                last = insertedNode;" q0 A  j( G2 G: T/ [' \+ \3 G
            } else if (index == 0) {" H7 w0 k: B$ s" x1 [% k% s" B& g9 n
                //插入头部/ _/ ^# J  k; ]: S% X
                insertedNode.next = head;
    / X2 J+ E6 a1 ?' `6 N            head = insertedNode;
    # {- Z1 ?5 s/ s6 w        } else if (size == index) {
    2 o% e) U6 S+ w. N3 V            //插入尾部
    - |! ^( x" P# q9 @/ [: N/ p            last.next = insertedNode;
    % f8 Q2 N; l: W$ C! a            last = insertedNode;
    + [0 l: L4 N6 c; C; o. `        } else {; @4 Q: J, h# _. K
                //插入中间4 G: C5 M6 I% S
                Node prvNode = get(index - 1);1 y  G$ E- v' n$ @8 M( Q
                insertedNode.next = prvNode.next;
    % N! F6 t4 G+ f, ~  f' @: L            prvNode.next = insertedNode;& M3 o) q; W+ ^2 L  j% C; U. B5 s' i: k
            }. v  q% M  W! t* P( Z
            size++;4 {* m- q: d$ i% [: H
        }: x3 M$ q4 a8 @" B6 M% [% `
    0 |; {+ D' Y& F1 z
    /**/ z$ v- `/ L6 x9 ~
         * 链表插入元素* j- @( C0 {6 O( e( ~+ q
         */ g. w- J# ^  J9 ?& @4 M, U1 F
         * @param index 插入位置( u! }3 T9 D: o6 Q
         * @param data  插入元素 被插入的链表节点的数据
    5 ^% I6 m# ^! _5 s. R* Y     */
    # b# {# k6 I2 |% H3 c3 L8 w9 m% D    public void insert(int index, int data) {2 L* ~! f* v0 k' T
            if (index < 0 || index > size) {/ s$ X$ W2 q6 R
                throw new IndexOutOfBoundsException("超出链表节点范围!");9 H; ?2 v' o( l  }2 F
            }+ H# C% a! f: V; O
            Node insertedNode = new Node(data);
    4 U3 @0 }& e7 g4 C0 N( x        if (size == 0) {$ @; J3 A( P, ?4 K8 s3 T2 Q4 [! C5 Y
                //空链表
    . X+ C: |" P7 J) |) H7 Y' u            head = insertedNode;
    ' `8 j4 H% n) `& a0 c; }            last = insertedNode;1 c8 V" U. X0 ]6 _4 d& p- A
            } else if (index == 0) {# f9 ~" t7 A8 f. o8 y- R
                //插入头部+ {: d% u: A8 T) y
                insertedNode.next = head;
    # o* d+ @' y. t9 u1 w" A9 ?" J            head = insertedNode;' C* I9 S2 _/ v$ t9 d) X, z+ s
            } else if (size == index) {
    5 ?2 S/ G7 j) R# T0 o8 t            //插入尾部- e) s7 J0 ]! J8 w- V+ F
                last.next = insertedNode;8 C4 L( v- ~; A4 V6 R
                last = insertedNode;/ U8 R) g& C! F1 N/ H! f
            } else {: L5 V& ~& P1 D* B" l5 P5 b
                //插入中间) d0 w$ x1 g1 M) n/ R
                Node prvNode = get(index - 1);; f0 Y9 @  K2 p/ u
                insertedNode.next = prvNode.next;
    " c6 V; f% ~4 @            prvNode.next = insertedNode;
    6 H% b7 M  c+ H; s        }; F5 f8 f9 W$ t/ Z+ b/ N- P  e
            size++;0 W& o- l. \; o& ]
        }# ~/ }6 w! Y: I' C6 i/ j( D
    4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除# ~4 w  A' N% R- v" s
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即
    4 V% A# t3 l) Z+ k3 ~. P8 R$ ^可。

    9.png # T$ h( E, B4 h  L! V0 Z# v

    1 F% C- q" E9 t; u$ X) y# y4.1. 头部删除

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

    10.png   B, T7 s4 ]7 Q+ k6 e

      I9 D: G; `; W8 c. r4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要
    9 E" t: ^: {! I5 P6 d) R$ Q删除元素的下一个节点即可。

    11.png 1 P( i5 Z& U; X/ b/ o8 C

      u1 I9 V2 V) _9 z2 d' n7 S
    - l% z* O7 I. |# i这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
    : f- K7 }( i( U. [如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)5 _/ Q1 W4 w! ?8 _
    /**7 B( f, P  N% [. \* f) p. P; `
         * 链表删除元素
      G2 {9 u- r! T9 B     *" B* }! S3 A+ n3 d
         * @param index 删除的位置3 v0 K$ f6 U& ?) S0 d
         * @return 被删除的节点  N* X% J. v# w* A4 v' q
         */
    ' y9 J; _+ {' U0 l7 \2 v0 }    public Node remove(int index) {
    " Y6 m. C8 N3 Z5 Y5 h        if (index < 0 || index > size) {
    * M. M3 c2 h+ Q4 Z5 t            throw new IndexOutOfBoundsException("超出链表节点范围");
    * b' G) S; u. h5 V) o; i        }
    3 @  I# Z( w" j* W# T        Node removeNode;$ l5 |2 ?$ A3 c( c0 V# u7 C9 {$ @
            if (index == 0) {
    . y' E6 Z7 p2 k# \$ ]            if (size == 0) {
    , }% i. d# k3 o+ D+ e                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    5 i$ u! a, j9 M7 G' L/ @            }0 _. k6 f/ K* J
                //删除头节点- Q# z, |% }- L
                removeNode = head;
    - q3 l* J. x: ^* |7 {            head = head.next;
    ' E7 b  ~- V" U- G- v# T        } else if (index == size - 1) {
    - ]# d& r, X9 {2 s8 L7 j            //删除尾节点
    + l1 J4 J3 y  L3 a            Node preNode = get(index - 1);, \( e& k- h; A9 ^' E
                removeNode = preNode.next;
    # s6 v$ O- {# F8 T            preNode.next = null;
    2 S' r6 L! l. \6 a0 r6 X            last = preNode;6 i; F; Z# `* O8 n  i3 N
            } else {! c! f4 B) G/ a0 T
                //删除中间节点; e' s- |' _% v1 x
                Node prevNode = get(index - 1);
    8 b+ a5 }' {* Y4 f" O, t; U            removeNode = prevNode.next;, D6 i* X3 \3 U3 {2 G
                prevNode.next = prevNode.next.next;- s# b9 |9 x, Q9 ^( @$ u! P' H
            }0 i7 z2 k5 f) l* L" r
            size--;* m$ v" y" t0 {, ?- Q
            return removeNode;
    " Z5 J5 P$ g& K$ }( m: J" h    }) C+ j7 M. W2 _- \0 E) B% ^
    Java实现链表的完整代码package chapter2.part2;" [9 _& A! V! O* A
    , a0 O0 x6 a: }
    /**
    - n5 B+ H& R+ A* X- G) J* J. y * Created by IntelliJ IDEA.
    , }0 k& a' K7 ?. ^" }! T9 y *7 s" \8 j$ a" V+ \% A6 o
    * @Author: 张志浩  Zhang Zhihao
    / {  F+ U. ~4 z2 ~( e3 q * @Email: 3382885270@qq.com+ B0 m8 N# S/ U
    * @Date: 2020/5/33 [+ _; ^. M2 G2 Q
    * @Time: 13:39$ R; a$ Q! W7 m
    * @Version: 1.00 r# Z& B/ E# _( v3 t. C
    */
    6 ^* h" ]: }+ H, a  S. ipublic class MyLinkedList2 {
    ' I6 p6 A( R# d/ o8 `    private Node head; //头节点
    2 h7 h: \. m$ `* L( w" X" _' b$ c    private Node last; //尾节点; }' I! d! a7 Q3 l
        private int size; //链表实际长度
    % R: E$ j5 u4 W* o( g" N: L
    % d6 _+ z3 Q$ ^3 g    public static void main(String[] args) {8 D- _6 b# a3 \7 J0 Q
            MyLinkedList2 myLinkedList = new MyLinkedList2();  Q' X6 F8 J) `0 J7 ?& I
    //        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    7 q6 \. T6 M( l# ?+ g. u//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
    * H( k3 y" {4 \- w/ z+ W        myLinkedList.insert(0, 3);# E5 {' r# c& k1 R* ?8 s* C% P  A
            myLinkedList.insert(1, 7);1 L" U* d4 B, z7 O" t% m) J
            myLinkedList.insert(2, 9);+ b% D  ]  P7 N  e
            myLinkedList.insert(3, 5);. D: H. ^! c6 m3 d
            myLinkedList.insert(1, 6);
    ) p! M# g$ D' I% d$ u/ ?% G        myLinkedList.remove(0);0 G0 E9 c6 @8 g! [
            myLinkedList.set(0, 23);) {' B. m/ s, L6 h
            myLinkedList.output();
    ( Y" V; A* r- w. w- t3 `2 v4 j- c    }
    : o/ u6 g+ V, [+ o* l$ K: O8 L/ H. j3 o
        /**
    ( ?$ [# ~) ^- j$ _, H     * 链表插入元素  T9 g7 }3 Y* q3 Q$ W, ]8 e) z$ v
         *% Y. x/ n- p8 A* I
         * @param index 插入位置# K6 q3 j4 g3 I
         * @param data  插入元素 被插入的链表节点的数据
    ; d1 r+ _* g6 ]' z. c8 h) U- e- ]$ \$ Q     */9 H0 `; |! P0 D
        public void insert(int index, int data) {
    ; Y/ ^4 p/ ~& e. i4 H; j        if (index < 0 || index > size) {
    % z2 ^, g" \7 D) b9 ^$ \            throw new IndexOutOfBoundsException("超出链表节点范围!");" r. @! U* c+ @2 J( B5 d  m
            }
    ; y' {0 n/ o; Q, W+ d" i        Node insertedNode = new Node(data);
    2 c- Q7 t6 C& g- X. w/ c        if (size == 0) {
    ( P" u1 u% u0 t0 j) B1 a            //空链表
    - E+ D* C% ?; _            head = insertedNode;8 ~6 _4 ]* t8 A5 h3 y; g
                last = insertedNode;
    - x4 Z; S* t  n" I        } else if (index == 0) {8 @6 P1 X) p/ C% }9 c
                //插入头部
    . {" Z1 [2 I3 V- l5 ?& b. q            insertedNode.next = head;. Y2 V; [) s3 }
                head = insertedNode;" d, t" [! z5 I# e  f& k4 s
            } else if (size == index) {
    * L/ c( j5 ^* i$ j            //插入尾部( W! r2 ^& G# D& t8 D6 w
                last.next = insertedNode;/ P9 M) C+ F- e3 A$ k
                last = insertedNode;, v( K; m% J. Y3 j. D" T. T
            } else {
    4 B, |) w, |9 g' A; u            //插入中间$ O; C; A; J9 H5 @4 ^5 q. z3 `
                Node prvNode = get(index - 1);8 U6 ?$ w- [% I+ m$ p9 x
                insertedNode.next = prvNode.next;  g: B% P/ v# D
                prvNode.next = insertedNode;
    - S+ n+ R% M, M6 O5 Y- F/ w% u        }1 j5 E) {' ^0 \+ Y* \, ^
            size++;
    7 Y" c9 J. u. _2 q4 C    }* G* n8 E3 ]- Q8 Z  L2 C

    * h" v* A8 n. J8 b1 t7 G- l3 R    /**' F/ A( T1 Z- c* L% @. _. O
         * 链表删除元素( T. |- X8 ~5 |4 M+ I
         *
    ! A' E9 P! H8 z" }( u     * @param index 删除的位置% p7 \0 u+ y$ m- I9 G. C2 O3 b
         * @return 被删除的节点
    & l! }2 m& ^. ~% e; G# A' m- x     */
    8 J& S7 s5 U' Y- ~3 C2 r    public Node remove(int index) {3 ]* _9 X$ B! }2 H& ]
            if (index < 0 || index > size) {
    $ G+ I9 e4 C' ^/ z# f0 V1 Q            throw new IndexOutOfBoundsException("超出链表节点范围");
    ; z/ Y; v( n# e' r        }# s3 P2 q( ^8 I: I- j4 A
            Node removeNode;
    0 V4 z2 L  ]0 t$ H! y        if (index == 0) {' ^. @- u- c+ n& X# A$ L. H( R
                if (size == 0) {' [4 e8 s8 }" H. y! z9 n
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");9 T. ?- A7 g5 P/ {% D$ |. a
                }3 t2 B; s; Y$ s) [* `9 v3 ]* l# t
                //删除头节点
    # W+ w% R5 \1 P" [" B& O3 e            removeNode = head;$ H% r: e2 j! j- ]
                head = head.next;( O5 Q8 N4 B9 L- Z- L
            } else if (index == size - 1) {2 G1 |! K' d9 f! V
                //删除尾节点
    : J5 h: D, x- L6 W            Node preNode = get(index - 1);& I% Z* l, @( A+ N$ I. S; i
                removeNode = preNode.next;/ s) c" [' \% `: B- J
                preNode.next = null;" m$ {6 f- |( o* d+ A, i
                last = preNode;
    # Y2 u, y. M$ E: W        } else {. B/ }. {) `$ l4 u# c7 j, J
                //删除中间节点
    4 _6 w1 d, p$ {1 i6 D( ]            Node prevNode = get(index - 1);9 i+ Q# k6 ^5 m! ~" G$ g! _
                removeNode = prevNode.next;  B$ t: `+ c7 s4 g# Y; @
                prevNode.next = prevNode.next.next;
    ) t. j: Y) p& x; A        }( o" S6 `( m) y' R' }3 d
            size--;) ]+ X) I+ h$ {; s, t
            return removeNode;( ?! D6 Y4 l7 t9 V! h, a8 N
        }
    + n0 @7 i- B3 B: ]0 m2 B) ]
    9 |+ h/ O- e9 N- s    /**, C/ f, o3 m* i3 Z4 B% Y- o
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    / \& b! s4 Y) a/ h: s! K     *# G. G/ J% @/ f. H, d- ^
         * @param index 需要更新的节点的位置
      F7 f2 Y( B( J     * @param data  新data
    ) Y- d  E/ |9 h5 j# J5 S  l     * @return 旧data
    . [) Q: i& n7 X9 O     */
    & e% ^- \" V- n: }  ^- D, h    public int set(int index, int data) {
    + n) v$ q$ j# V; o  P5 D" I        Node x = get(index);7 H2 T1 w" `, E* V( ]* Z1 D8 g
            int oldVal = x.data;
    1 K6 z  ~+ C6 a0 a! ~- K        x.data = data;. C" V3 F3 u6 A" d4 g
            return oldVal;
    : L# m0 T# @2 V    }5 r5 y0 K7 H. v% f+ V, `: R7 G

    - y. F1 R' ~  y2 s    /**
    # C  x$ j. g7 E2 l! }, k, {! \* {9 u     * 链表查找元素# T0 j8 f# p* h& b9 ~
         *9 s. e1 V: ^$ K3 n0 e% i
         * @param index 查找的位置
    0 @$ X! ~/ Y/ @+ U     * @return index位置的Node对象
    , \# M8 `, g$ h( O. q1 P3 N* `     */
    2 l8 Z4 Y) c2 }; i7 c    public Node get(int index) {
    0 o' }( c2 i) S" I1 z& u        if (index < 0 || index > size) {
    5 o6 y  e8 \: s+ N( R& l2 L            throw new IndexOutOfBoundsException("超出链表的节点的范围!");4 D7 _" o, Q: u5 L; w+ V/ g
            }' m: k1 g  P6 s9 P4 d
            Node temp = head;3 u& w5 A0 r  g  l( `
            for (int i = 0; i < index; i++) {
    ( Q, \& U: H% s% M2 q            temp = temp.next;4 P# V# W$ h! C5 S4 ~
            }6 L( o" Z' j/ |2 _+ `: @2 q5 a/ v5 \
            return temp;3 R/ k6 x1 I4 p8 u3 Z
        }
    : }7 Y7 G( _1 U7 p
    3 Z4 u- L+ ?  B- c, k    /**. c! R8 l( o! [  W: ~2 \) a  R- ^
         * 输出链表- `$ s; s7 w  b( ?4 k9 E6 R
         */1 V& d, V$ T& y( v; H$ z
        public void output() {
    . ]/ ^4 U0 _8 E7 m, s  Z% B        Node temp = head;" q5 G, ]- q. s6 n. y
            while (temp != null) {
    ) ^7 m- a3 R* x4 P8 A+ N1 Z. M3 t            System.out.print(temp.data + " ");  q5 E5 M" k- Q( W0 O  i
                temp = temp.next;
    ! q5 F. V/ ^5 d: Y" D  i; j        }
    + L, {/ p3 n! C) s" R: q4 `/ C    }- N! D! ~% D! |- A" h! r
    . }& m7 z; D0 I2 p- u& ^
        /**- u4 w8 c0 `( i8 `) W- Y
         * 链表节点" F: K4 y5 h0 K$ Z' _% ]5 F
         */
    $ c0 _6 D3 K2 @1 U. {$ g$ T5 h& G    class Node {
    1 l/ X9 L/ r. ?1 o! b        int data;
    ! R" f3 Q* H9 |5 k9 p2 K        Node next;8 p  ^9 F- {4 ^+ C% H
    ' l2 h% a* L1 q7 U4 d
            Node(int data) {8 T  L/ f+ Y  k. B5 f2 r$ g8 b
                this.data = data;
      ^1 U8 s, f8 U        }
    , I& Y; p+ T% `, X3 [    }
    3 D% n, L( J4 V9 j* J}+ Y7 K* a+ J' I2 o& ]/ w; `" {
    % }% J  a9 e7 c" M) Y

    " Q% G" ]+ j9 a% m/ w1 n" |' v二、双向链表 12.png
    4 N3 _9 [/ S, p4 K( Y; V双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。4 w9 v: ~- w. I3 s0 t
    2 N! x7 X$ |5 I
    7 D6 k0 \- r$ Y- |
    ) S: I- Q* S0 F2 Y$ X4 j
    8 W  E0 N) \: g' A
    ————————————————* c* @; a  e6 L$ f
    版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。% {, y6 g/ Y4 G! g4 C- Z
    原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468
    7 m$ w7 Q* F9 l+ N( }4 u: ]3 A
    4 T# z3 {/ `$ a7 E
    ! p, k" U" l( o, }+ T) k

    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-19 09:26 , Processed in 0.460364 second(s), 54 queries .

    回顶部