QQ登录

只需要一步,快速开始

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

    9 E" |4 f' q6 m4 K5 ]【Java演示】什么是链表?数据结构
    - |5 w5 B$ ?9 z6 J; I0 s/ C一、单向链表* X0 o7 U5 u+ f( B
    ) I- ~% A% [3 [* y: \+ t" `, s
    1.png " r. J: |6 J+ R+ Z5 ]6 K2 W
    链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。
    8 Q9 F. C( x- c* y" W/ ~' [单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。9 `9 r" p5 f. J" B: \$ J
    链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。
    ( l  x0 Z4 F2 t8 ]9 d! W- o3 f# d& f) r6 A
    什么叫随机存储呢?
    5 g; z& C! o) [  Q7 A$ k) ^: W0 w& k9 F6 U- F# M: F
    如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。3 a. G" s* b- s5 ~8 {; }
    上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。  w! _% u& p5 e# t6 t
    3.png
    7 _; }6 m$ Q6 ^( a8 g+ `* ^1 `9 \8 y/ K* d. c: E$ V/ N4 T+ s

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

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

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

    4.png
    # p0 s8 Q% Y- r- B" w1 a5 A; B- W6 `* @! L: g
    /**
    $ q0 o5 d6 b, l* y     * 链表查找元素5 Y& P: z8 p" C4 T. @' P3 D% f
         *( S8 a; U1 a# H$ b$ d: E$ r4 \
         * @param index 查找的位置  T5 P/ F5 y+ E2 p3 x
         * @return index位置的Node对象
    / t2 A. H9 c  E; M; D* w9 }' U! {     */
    ) Z) D: D# L7 O1 Q5 ~3 O# J. |    public Node get(int index) {
    5 B& c; X5 S$ G        if (index < 0 || index > size) {! e- N1 `5 q& a/ R
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");8 B& `" e5 S7 w- Z, O
            }
    / T$ R: J7 I7 A1 S; _# q3 @        Node temp = head;2 W$ x$ @2 L" [
            for (int i = 0; i < index; i++) {% c2 o1 e4 j: {2 @" _8 r$ H
                temp = temp.next;4 G6 o! z- b. z; t7 S: \( I$ p
            }
    $ s! y3 |- _; ^  W7 E2 M9 G! A        return temp;" k6 x1 i: j2 d9 [2 {8 t# [
        }
    : n1 V/ V% S% |9 l+ \
    * Z- B# G% k  D5 [( ^: S; j3 @

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

    2. 更新节点 5.png 8 K. P, p7 U; A9 z
    5 n) `3 A( d+ ]' R$ S
    如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。' r+ E- H  H; ^# d
    如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)& ^( w1 ^: _8 Y
    /**
    / k  E# T7 q0 S     * 更新节点 将列表中指定位置的节点的data替换为指定的data。6 k, r# l2 f  m/ L) J
         *
    - J; H. f; Y& k* _& G" l% W     * @param index 需要更新的节点的位置
    3 q/ z0 n7 H2 i. x" y. ?( |     * @param data  新data. L; f  Z7 \, _# p! m
         * @return 旧data, {& a% I4 s2 [+ `
         */4 o/ [$ w8 S) Y1 z5 M
        public int set(int index, int data) {
    ) _4 x; K9 J) f        Node x = get(index);
    8 S9 B1 }1 n" F3 j& o1 T  z        int oldVal = x.data;
    + F8 H& m+ L; s        x.data = data;& S1 f, H; s# v/ M1 u& m4 Q- K
            return oldVal;
    # T0 ?; W- P( j, R$ h% q/ k    }
    4 L( `% L' u; J2 n
    " c: G6 S) |. w# w3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入% p, n3 w$ V5 _# E( ~( c
    3.1. 尾部插入

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

    : T. C+ ?5 g6 Y1 P
    6.png
    & }" H7 S  y% g" m' `1 m" ^3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。- O, P. e1 }- m) X
    7.png " `4 s6 z5 R" Q' T% D; R
    . _: |6 Z" @8 G) }$ x' H
    3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。
      6 q# t" f3 h9 y
    8.png 2 s# i3 J9 j' _0 y8 T" X# H4 M

    * J3 b: i& L+ j0 L4 j1 s三钟情况的代码合到一起
    6 M7 E4 i, O# g" D. ]2 I. G# g) x- ?3 m  [; G, [' P
    /**
    6 n, w5 Y: K* u; @8 f  p' p, h     * 链表插入元素: Q; Q' g% U% d$ n5 u
         ** l" I; Z( w1 I! v
         * @param index 插入位置
    " F9 }! {( F: C( F" L     * @param data  插入元素 被插入的链表节点的数据
    ( P5 X9 W: k% ~9 u- d. z# p     */1 z( h# U4 @! t  M
        public void insert(int index, int data) {
    % i. z. D, h' Z# G        if (index < 0 || index > size) {
    ( W( ]* U3 B$ D" O! Y            throw new IndexOutOfBoundsException("超出链表节点范围!");
    7 ]* [2 M2 d/ Q, _# @4 A+ P9 a& ^        }+ \# s9 B7 E1 {
            Node insertedNode = new Node(data);
    1 E8 _9 B3 K$ u. u1 j        if (size == 0) {
    5 n- k/ r8 t1 p2 H5 ?            //空链表3 e, i$ X$ g9 Z' \2 Y" g$ k+ ?+ T
                head = insertedNode;) n$ h9 h" ~7 `/ ?* s
                last = insertedNode;
    ! O7 G$ L: B3 t  i! \1 F5 r        } else if (index == 0) {
    3 J9 w) ]/ m, `3 b( v% S            //插入头部, z  m/ H6 ^7 j) N8 q4 V4 t0 V
                insertedNode.next = head;
    # l8 ^/ C- d: a  t' t4 Y; v- M            head = insertedNode;
    8 g& B% l( F* }        } else if (size == index) {: D9 E  R9 b1 u, ]7 @3 z  U3 g/ z8 R. O
                //插入尾部) {: y0 W) o0 G3 Y/ P/ U( M
                last.next = insertedNode;3 ]0 X- Z1 N/ q, f3 G% r: |
                last = insertedNode;& P" y- v9 ^. b! Q0 p& x
            } else {
    ! `$ Z# n' p$ l# Z) q) Q9 R            //插入中间
    0 C1 M! k& M0 N7 P            Node prvNode = get(index - 1);
    ( e+ z% u( v. M' ]- g3 ?. K            insertedNode.next = prvNode.next;
    # p) J+ f) h0 t6 F9 E( y; ~, d, Q            prvNode.next = insertedNode;
    % H9 g6 N* A+ N8 E1 @; ^$ ]        }9 e% u- Q% D* T. @
            size++;
    0 i+ P# C7 {9 v; }. T    }
    , w. D+ t0 T% i) `7 m- u
    ( v/ L# s% c: Y6 @) V  G" b4 i$ g/**
    4 G: P" [0 M3 g     * 链表插入元素4 e% _" E9 \% W: \; n
         */ q( i, A4 M2 W
         * @param index 插入位置8 W! ?) U+ `) S% w
         * @param data  插入元素 被插入的链表节点的数据
    7 J6 X# B2 }6 z1 \5 H& A9 F     */
    ' h. }) w, b/ j6 u/ \* F    public void insert(int index, int data) {+ N" b) }  ~3 z2 g3 ]
            if (index < 0 || index > size) {! ?* g2 o9 i5 c8 W$ z( s$ C. j$ M
                throw new IndexOutOfBoundsException("超出链表节点范围!");
    8 p) M  h+ `4 y; R+ p3 [1 _        }3 G, k! s7 S: o" c2 z* y9 m
            Node insertedNode = new Node(data);' }) q) O: |; X8 G' V
            if (size == 0) {
    : W/ H; P* j& Z& G' G1 E            //空链表
    / D( `3 S! P" h; _' R            head = insertedNode;
    4 |1 |) D7 Q0 z+ j            last = insertedNode;  h) Y) p1 e1 ?% P- s
            } else if (index == 0) {
    3 L5 y4 U  k7 K8 a9 T* [4 s+ y            //插入头部
    3 A% I, N) Q- J! H% o5 d            insertedNode.next = head;% t. \0 F% @, b+ a! N5 t
                head = insertedNode;2 K( E5 V  B: j
            } else if (size == index) {2 {* ?7 c( Z/ e
                //插入尾部
    + q( P' N2 x) o& e6 b            last.next = insertedNode;! P& H' |4 G9 N
                last = insertedNode;& V& T' x% L. b3 _
            } else {
    # Q( r5 R1 S, {( R2 y            //插入中间
    2 A1 A2 {. }/ J& l- |; d3 N            Node prvNode = get(index - 1);* J. g8 K1 ^" w8 `( |! g; e
                insertedNode.next = prvNode.next;
    ( W% }: D& m5 x+ `9 p2 B            prvNode.next = insertedNode;& \2 o) V7 g# ^; a1 e/ y: n4 z
            }
    3 Z, Z; ?0 H( s9 |  \        size++;: N( u( o; R" W# Q1 ^* `" F
        }
    0 `- G; V7 y2 c/ }4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除# `+ ^! o7 j; v& [, {- v9 q8 s
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即. h0 X1 v( t9 n+ N# ]
    可。

    9.png
    ' `; W, [; S8 w1 }! M) ^1 n/ m
    : Q% \% s) @/ Q6 c7 V9 ]$ @: g% B4.1. 头部删除

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

    10.png
    2 [/ v0 F- a* h( ?" o, Q% R( a
    5 ]3 S+ b7 q+ T! N) K9 C* c: G4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要
    3 l5 w& j% W. T: f删除元素的下一个节点即可。

    11.png
    , c( ?+ k7 P# K* S! B5 @
    ( l- g5 T* m. L+ l2 z" _& o0 z: a: R+ T. X$ Y/ |! @
    这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
    ( ~  M6 K) ~7 Q7 M; G; d; i  e如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)
    % Y6 F4 _* P, ]6 r; J/**
    8 l9 |" {' s# q" N5 O/ J     * 链表删除元素
    + X( F  D" k# S' K) S* M# S0 w     *
    2 S; b$ ~$ b; G7 X) o2 F1 v     * @param index 删除的位置, `- V& b, }; B! h' Z" K0 X
         * @return 被删除的节点
    ; k& J5 k% X0 Q/ x     */0 w9 S  Z6 d* l7 t; ?
        public Node remove(int index) {
    . g; g$ `2 N% c$ l4 d        if (index < 0 || index > size) {/ A; G* r$ G# v) f4 ]5 O  R0 \
                throw new IndexOutOfBoundsException("超出链表节点范围");
    ; P7 B) P! j$ E        }
    * n5 `/ F1 N7 o& w        Node removeNode;
      b9 n. O3 t% @- O3 M        if (index == 0) {3 I1 X3 p/ R& E
                if (size == 0) {+ ?. ~* [  }" t) @! f
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");- W: i  M# H( C( K, ?
                }/ N; E$ ]; b5 t$ L. A
                //删除头节点
    , f$ _! I) A9 u            removeNode = head;% u0 O9 c3 C& F/ }7 G" J
                head = head.next;
    5 L$ r8 A. \4 y        } else if (index == size - 1) {
    ( X2 w/ X* T% U: R            //删除尾节点
    8 O# ]7 O: y3 x7 c            Node preNode = get(index - 1);4 H5 q( J" Y+ N3 l0 C/ @
                removeNode = preNode.next;# K9 i. A* S% B# N+ o
                preNode.next = null;
    # z" u* b& Y: `            last = preNode;
    # f' z$ n: n0 C) f, f        } else {" c4 E0 e# K" V0 R5 t
                //删除中间节点. B+ s' g+ I9 H# P% a
                Node prevNode = get(index - 1);
    ( j& `" ~5 ?$ B; N" f) D# w- G( w            removeNode = prevNode.next;
    0 E" n+ n0 n1 M1 c# x2 k4 o: g( \            prevNode.next = prevNode.next.next;
    , |) s6 s$ Y3 y! \) b7 Z& t% [        }* N' I* c* C% T
            size--;7 p) B) e# ]: r/ W
            return removeNode;
    7 X# O, R) ]1 _; c    }! G" Z/ n# R' k
    Java实现链表的完整代码package chapter2.part2;7 O; W/ d- K8 }: B
    . B) F% w, x1 G( f& a% o
    /**
    0 N9 n, w* z* d# @: f * Created by IntelliJ IDEA.
    3 O7 G' l4 s3 C- T; L *
    : m8 A1 |+ H& e# s* Z' [ * @Author: 张志浩  Zhang Zhihao
    % b5 K$ [7 g: _& v" ` * @Email: 3382885270@qq.com6 M$ N7 s5 M  ^# s: ~8 f  v# e
    * @Date: 2020/5/38 p2 C" l! u& W. Z9 ]- e0 T% L
    * @Time: 13:39
    + f& E9 H1 J! r, ~1 g * @Version: 1.0
    $ e1 J% m/ x3 I */
    % `; w; _6 p9 _5 H' }1 ]; H; U& wpublic class MyLinkedList2 {6 Z" |6 {: N$ [4 N: R
        private Node head; //头节点
    # a. `) @5 G; X) P- Y    private Node last; //尾节点9 p( @; G& ^& |: d, o/ B2 q
        private int size; //链表实际长度
    % x5 I5 v. g; m. [" K3 `5 V$ ]9 ^
    " g$ \1 a+ q1 u6 a$ I    public static void main(String[] args) {& i# z7 @/ q) c% @7 |8 V
            MyLinkedList2 myLinkedList = new MyLinkedList2();
    ; [  j* U6 o' s) Z. i. g& a8 |//        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    " M$ ^2 ]0 t9 S0 H$ \% q//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围  g# M0 K3 v% i7 S8 s4 y9 g
            myLinkedList.insert(0, 3);
    ! e0 ^& w6 R# p0 `$ [5 r" O% M! ~        myLinkedList.insert(1, 7);
    ! L6 ]% \3 H# r$ {6 j        myLinkedList.insert(2, 9);. \* Y- |; x0 e* u: L& ]. f
            myLinkedList.insert(3, 5);
    : y4 |- G& Q& z        myLinkedList.insert(1, 6);7 G. I$ v5 X3 e6 Z* Q, L/ y
            myLinkedList.remove(0);( l% n3 \$ b" E" ~
            myLinkedList.set(0, 23);
    , q' S. M( h! D        myLinkedList.output();
    ; P3 G6 c2 C; W9 E    }
    # [$ r" N. f# ?/ P2 S9 V5 u$ L9 D7 z- w% `6 C" G4 Y* Q
        /**: B, \5 ]5 s' ]5 M% B/ G7 }
         * 链表插入元素
    $ }6 Z/ p  J/ j     *8 s1 J9 W( z/ y- T/ a; S6 G- ~: q
         * @param index 插入位置% G8 x3 h/ q0 b7 i  b
         * @param data  插入元素 被插入的链表节点的数据
    ; J, C6 M: n7 W5 j* B     */
    3 o/ Q! W( l8 S, N' P7 g    public void insert(int index, int data) {
    % E0 }5 p2 O! ]7 X0 p5 o2 o8 k        if (index < 0 || index > size) {( x3 F$ \/ O! q- e* m
                throw new IndexOutOfBoundsException("超出链表节点范围!");& v4 A9 h, J3 b
            }) n7 c, J. I( }: K! L4 F$ y! R
            Node insertedNode = new Node(data);
    0 \# s9 Y+ g+ v        if (size == 0) {
    % g( i4 P  F2 K' g            //空链表
    0 t2 E& x: g; I9 a; U- W            head = insertedNode;
    - g% ]+ \) y7 A            last = insertedNode;$ N5 u% ]- [9 _" l& r
            } else if (index == 0) {
    2 o$ n) J) j% l: C( H) K            //插入头部* x0 B; G- W3 V- j1 _! h3 }" [4 j
                insertedNode.next = head;
    1 w& t& v2 U7 I2 a) w; u! g            head = insertedNode;' K; ]" T9 g8 e0 @
            } else if (size == index) {' F: G* [. }5 P# L( H
                //插入尾部+ U' b# d! E) f7 Q2 d7 ~$ @# @
                last.next = insertedNode;
    / E, c1 X$ y9 U            last = insertedNode;# U+ t+ H9 A5 m! g# y! H4 |
            } else {2 U& f7 k1 \3 U& q. [. [
                //插入中间1 G# f2 e4 \: f  D8 X
                Node prvNode = get(index - 1);
    + M5 b- r7 w% {& Q% S7 X9 I1 K            insertedNode.next = prvNode.next;
    & y0 w+ N1 j# r            prvNode.next = insertedNode;8 B! P2 j- ?  A* A
            }3 z/ ^4 }/ U4 f" l- s) m; y, U
            size++;
    ; r8 ]$ p6 l, N6 ?    }
    % u! h) {$ k( ~
    8 M: y7 q2 A$ [' D- @    /**
    0 O6 P, Q- `2 u& x     * 链表删除元素# K$ ?- W0 D' G  ^
         *
    / C/ i. h, I/ P6 H& h     * @param index 删除的位置1 u5 O* _# v, u
         * @return 被删除的节点
    ( E  p0 s& ?/ Q+ C. {     */
    9 ~  S  R5 O* u) {    public Node remove(int index) {
    5 t9 q9 o. |" s" i# b& A        if (index < 0 || index > size) {
    & }" U, I" x; ?, \) `# V( v            throw new IndexOutOfBoundsException("超出链表节点范围");
    1 Z  R8 K/ y* u/ ?) k( {; r' }        }% G4 |4 A- H" l0 T8 q3 l
            Node removeNode;4 H: a' V/ t! s+ y# l2 K) K9 c
            if (index == 0) {
    + v4 H! c3 I* B  I2 u& p# j0 C            if (size == 0) {
    6 W2 I! ~8 M9 t9 F# f6 O) K( Q  C                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    3 \$ d4 ^; [6 Q) j( V- s            }( q" v. V6 \1 g1 J
                //删除头节点
    ( g) p1 H3 f7 F/ k7 L            removeNode = head;1 F. F% m. Z2 Q) s
                head = head.next;2 Q) P, u5 U5 \% v/ ?/ x
            } else if (index == size - 1) {
    / r+ A) p! a! S$ V; g$ H2 `" Y            //删除尾节点- h  h8 n" B* Z$ b
                Node preNode = get(index - 1);( Q* z' M: B2 {: J0 ~
                removeNode = preNode.next;: q/ ^5 t# H! k: a; m
                preNode.next = null;
      ?% |' H5 u0 f            last = preNode;
    ) [- N2 J% }8 O- b1 I        } else {
    & F" d- R$ C: J            //删除中间节点4 Y# _9 S& X  j5 S3 o
                Node prevNode = get(index - 1);
    1 X& Z; q" L8 F9 \) ]- b4 a            removeNode = prevNode.next;
    0 t' i6 B" @6 @4 t/ B            prevNode.next = prevNode.next.next;
    0 @9 _5 Y8 Q9 M, P' B) ^        }8 Q1 v! `; v7 b  q: ^0 }! U! b$ ?2 c) h
            size--;8 y, x# b+ h5 l9 {5 d5 G* k5 \
            return removeNode;
    ( `7 A9 y2 l, }0 I4 N    }
      s/ G! n' M! I# H2 |7 H
    $ O! x) ?8 {# d8 A$ J; _    /**
    1 w/ F; X2 d3 V# D: i4 O     * 更新节点 将列表中指定位置的节点的data替换为指定的data。  r6 w2 |) X- {3 ?
         *
    % C* f; G* s) i, D     * @param index 需要更新的节点的位置2 ~) u# x" e4 f" H- `. a  ^6 m
         * @param data  新data# M% v: a, a0 J: c' u( ]
         * @return 旧data* B, A+ r3 _) _# j% k9 F
         */1 }! e7 a1 c. g, G1 v
        public int set(int index, int data) {# w  b3 m. F: A- I8 G
            Node x = get(index);) [7 Z+ m- R9 r  d
            int oldVal = x.data;
    1 q( j5 S" `( O5 @, d        x.data = data;8 t# L# |& {$ c, k* I" S
            return oldVal;
    9 X2 r8 f9 k8 m7 d% O$ W# j3 _( D    }
    ! }, l# x' k9 L8 o* g7 _: r" i& D* n. [! o
        /**% \# u* k( K5 {: q
         * 链表查找元素
    , ]4 [& o# C- P, J/ ]# A     *
    * O) f/ ]) @5 S/ Q     * @param index 查找的位置5 A2 X- J, r* p; }8 x7 L
         * @return index位置的Node对象/ G& Q1 A/ B9 E1 P3 T2 N# }; x
         */1 K5 K- M$ l- O# J# t3 A3 H: O9 a8 l
        public Node get(int index) {
    - x4 M4 O8 ?* x        if (index < 0 || index > size) {- \  _! E9 L  \/ }! a: \5 x
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");+ f" H+ N$ K3 E, _
            }6 b+ l5 h% `( e! p! v, E# J
            Node temp = head;
    : k1 F/ k0 o; i7 G$ z3 a+ K        for (int i = 0; i < index; i++) {
    : b6 o" M5 i0 h4 J, P! F            temp = temp.next;4 {* H! |/ L1 b- P
            }
    9 W- d  O4 M# m1 q        return temp;
    5 O3 C+ A0 b; f, ?& [3 B  i' J    }
    6 `4 V; Z5 Z0 W+ h) a
    + l2 O. a  g, t+ _$ V% N    /**% w6 X6 L$ _* x
         * 输出链表
    1 J' M; \# `# A     */6 N3 s5 J. E: C! U( L
        public void output() {
    8 g" F" G. e, `4 X# [$ J        Node temp = head;
    5 S% j0 L0 A5 }$ S7 _% B/ f        while (temp != null) {$ M9 R4 }& k/ E/ F/ |
                System.out.print(temp.data + " ");
    4 A; k7 p( K4 y* N0 ^/ Z; s% K* @            temp = temp.next;
    / a2 d' k! ^7 B        }
    0 r/ [" o& a& Z  x' M& ~    }
    & r& p0 u( x3 T0 |; o1 |! G# G5 {4 q
        /**
    9 X- F" Y! u; d     * 链表节点
    - x/ @+ \9 M5 M6 Q     */2 _/ t  T" Q: W
        class Node {
    5 S& Y9 J( u6 O+ L  F/ G3 D! e& c2 X$ p1 T        int data;9 E* M2 N' \3 |9 a( }# m) f- n% h
            Node next;1 q* I* K/ E7 S; l
    ; U6 A4 P' @6 r* h
            Node(int data) {
    8 P5 j( \$ ]+ r4 ?+ @3 _& s            this.data = data;
    4 \* J6 h8 f- [        }
    9 B/ R4 h6 ]& `# d, C    }
    5 c) q7 N: C$ x9 H7 P}
    9 |2 C' q- E/ f/ |- f, E7 d, |  I' v  d/ ]9 F' W

    1 B5 g9 S7 A0 {9 k* d二、双向链表 12.png
    ! C3 o0 k( l" q6 ]& _  x双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。
    6 v* s$ Y( m5 q$ y
    - k+ ~5 V' R7 A" }7 l) R( y: ~. g# p

    , g' b( l0 p3 E- Z0 u
    $ c3 U! f' L$ x. Y8 e. I8 S————————————————/ Z2 {2 q& Z. ]: z+ R4 `
    版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    4 h/ ~3 g# H7 I) b原文链接:https://blog.csdn.net/weixin_43124279/article/details/1059044685 _" l; Q. o& z
    2 s8 ?" `* m/ Q& h# H6 @: y/ e- i5 [
    . b: j; L* N& w$ [# ]' d

    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 04:00 , Processed in 0.461880 second(s), 54 queries .

    回顶部