QQ登录

只需要一步,快速开始

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

    1 C% n$ l0 {1 p【Java演示】什么是链表?数据结构5 a) S  n4 F% q, P
    一、单向链表
    6 {" f3 M" h9 R! f$ N8 c6 v
    * t* `6 |2 e/ P2 c5 |. B4 B 1.png
    ( G. r% z" L! a4 `& C& t链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。. l1 K9 I& T# I
    单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。
    : O0 l, x' G) j# ?2 t链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。
    ) s" o: p  ]+ A* s# ^; h0 o6 `: J, H3 d2 Z" C4 r+ Z, [
    什么叫随机存储呢?
    9 B  l8 z4 W# d; l' i* ]$ D! `
    7 J8 Z  N$ ^# G, D) t5 ~$ Y: `如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。/ h& I: z0 B- h" j% n
    上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    * V) H+ ~6 X3 n5 t% b" p; Y. f+ ^ 3.png 1 t* C' {& x* ^- V
    # ~/ \5 o% \' d  N1 z

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

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

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

    4.png + s2 z4 Q2 l' u  n
    , q3 l6 w/ ~  D+ j& u! z
    /**8 @4 G2 T  L/ A! d0 o# A2 Q
         * 链表查找元素) I" y/ t: S; T
         *7 T- K7 N1 X2 ^. V& }4 F- ~$ I
         * @param index 查找的位置( w& n6 c$ D/ S6 B, Q
         * @return index位置的Node对象2 z, q* Q7 f; y! {9 W" P
         */3 H0 C5 @, ?% B
        public Node get(int index) {
    9 A9 i  I0 @0 x# S& g/ @        if (index < 0 || index > size) {5 ]/ J3 `; W9 ]) U" m
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    & e' S2 O; [6 P" B" b2 M- I! i        }
    ; [0 C* d/ i. z8 c& i, Q3 |# T+ t        Node temp = head;
    8 I' {' V) B+ }: I' f        for (int i = 0; i < index; i++) {. Y3 x" O' ~. e9 \' W
                temp = temp.next;9 J" P: ]" A- n9 M7 M
            }! h( x% N# s/ f
            return temp;
    7 C4 R8 J* [# Y  N    }
    - }9 a6 p' N9 l
    2 q5 b& L9 z, W; v7 L( n

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

    2. 更新节点 5.png : o* `9 ^$ P; x, K2 g, M0 f' x/ \

    4 w# D  I# I: s: m如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。- r* e- Y2 A" C+ e8 b7 c
    如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)! Y4 g5 f4 Z; O9 z# L7 ]: ]9 m
    /*** R& v# `6 i1 @, u
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    7 R* d) w6 S4 g1 }: V5 K7 X4 H     *% {0 ]" E4 f9 `, e" C) ^( o
         * @param index 需要更新的节点的位置
    . I9 W5 g0 w, L& d, W6 N     * @param data  新data$ A! k% m8 \  C- b( P; }' c+ u3 Y
         * @return 旧data, _7 v! U" m# Y: z7 }
         */4 E8 t. s: i3 m4 i1 }+ c
        public int set(int index, int data) {1 k) [/ o$ l& E' P8 \( ~
            Node x = get(index);
    % Q7 n7 M3 x  c! r9 W. y1 I        int oldVal = x.data;4 u' W# g: F2 a( ~! C9 L. _
            x.data = data;- N2 c8 O; A$ y1 S9 T
            return oldVal;
    / u1 d) @) L/ a. {. V    }
      I7 _/ O/ O3 v" B8 m
    * Z4 \. u4 V5 N! w& ?. j# K$ a3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入
      ; }# x- Y* ?. O' x; L9 a( o; s
    3.1. 尾部插入

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

    6 Q+ V; i. D; C9 v5 n4 G2 A
    6.png
    0 v& w3 e' w! P6 G6 |+ Y5 Z6 D3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。
      " l. u& l" C; k2 t9 I& t! V. T& N- y
    7.png / l, b' D0 p1 D
    / g( \" f$ q1 g1 d+ b& e
    3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。
      0 \! v7 V( c5 b1 p8 L  v* @
    8.png
    1 {  f; N; v* t7 A- v+ h0 x  ]$ ?7 {3 j0 \3 |4 Y- c" J
    三钟情况的代码合到一起; [' ?- f+ h+ t7 t; }- _- C

    " L1 Q$ k! [% R/ O! S5 }/**
    4 g0 X- u$ g  f7 f) }3 r0 y5 Q6 G     * 链表插入元素& f5 z6 t0 l# _4 Z3 S
         *
    ' j6 K5 A; h& y" q     * @param index 插入位置
    6 u) I# ]  q7 f# N     * @param data  插入元素 被插入的链表节点的数据" ?% y$ j7 d0 E, P1 |4 j
         */
    3 t3 w& t9 ?$ J( }! L% B, g    public void insert(int index, int data) {
    2 w5 w+ u+ {3 R* d5 [        if (index < 0 || index > size) {
    : C4 k! I: l2 |- ?            throw new IndexOutOfBoundsException("超出链表节点范围!");
    ! g' `- C3 P  n8 W# ^        }
    2 P& R( M$ V7 T8 f        Node insertedNode = new Node(data);
    / ?" _8 |" x' H3 V: c' ^        if (size == 0) {
    - ^- F: R) _$ l6 H4 Q" K            //空链表7 V" C' x- v1 @* l
                head = insertedNode;- P9 [& J4 i. {3 h
                last = insertedNode;
    0 d; u. s/ t8 S9 v9 I" n        } else if (index == 0) {- Z1 W3 H% n. _4 n6 b6 @0 R8 N, d: {
                //插入头部
    & D+ c: t! r0 L5 j8 [8 t5 o" \            insertedNode.next = head;# j' Y# z6 {# g! s# }
                head = insertedNode;4 g$ f9 u/ j$ ]# R/ h
            } else if (size == index) {1 v  L! k% `2 W
                //插入尾部
    3 O/ Y  D' [$ o            last.next = insertedNode;
    ' a- g- h, h: @! x; x            last = insertedNode;4 ?1 h) ]: |2 s1 q7 E
            } else {! Y2 c8 U- u3 K# Z
                //插入中间
    ' c- n* ]2 m. z            Node prvNode = get(index - 1);
    - T2 }$ s2 P% t- K+ m+ |6 ]            insertedNode.next = prvNode.next;/ J: ?" k8 Y/ K
                prvNode.next = insertedNode;2 p1 d1 f" t, G: h. g% W/ l2 R
            }
    / i, t1 a6 N. Q7 B5 W        size++;
    1 |. D! Z9 V. G' M& z; V0 Z" X    }
    1 P. d, y- H$ o. k8 \$ R) h1 @4 K7 S) I9 ]/ K. y* r2 c) f
    /**3 P$ R* C$ v8 p; K) }
         * 链表插入元素+ O( {: b2 F4 j% y( Z
         *5 C3 i! X+ u- |6 R
         * @param index 插入位置
      ?% e4 l5 P0 U! w     * @param data  插入元素 被插入的链表节点的数据
    / ~; h; w% b5 y& |5 Y  ^     */7 A8 b! K, B( w
        public void insert(int index, int data) {' l8 c, Q* @, e1 F! |
            if (index < 0 || index > size) {
    ( H. t2 c/ v. }- q3 k/ ~7 Y/ Q& `            throw new IndexOutOfBoundsException("超出链表节点范围!");4 z2 R" I) Q1 J5 H* ~
            }1 x/ i% v8 v8 w/ ~
            Node insertedNode = new Node(data);1 [3 o9 N0 c- s
            if (size == 0) {/ f: w. T+ i: W( v
                //空链表
    / l7 O% D2 u; P' y; V$ |8 A. R' j$ X* i            head = insertedNode;
    ( O; q9 s+ [; l6 n/ I            last = insertedNode;
    , J4 b; ]: `& Q7 {        } else if (index == 0) {
    % @4 r, y! v6 u1 m; Q6 J7 O            //插入头部
    8 ]# l. _- }# k! m2 U            insertedNode.next = head;- I& f0 b* a5 ?8 M& H" W9 Y
                head = insertedNode;
    # Y6 p5 P" J: G8 h3 x7 a. D$ i- w% K        } else if (size == index) {
    4 [# i4 E( ]2 G( h" E- U2 s            //插入尾部% a4 m$ [6 }/ Z' l* g1 A/ ?* J- L' x
                last.next = insertedNode;9 y0 M( D8 M5 f/ x4 ~# q2 z
                last = insertedNode;
    # |8 w+ t. s& Y        } else {0 W' ]& d1 i% l% Z& I: l$ p* O
                //插入中间8 F' {$ j8 Q8 Q0 T) x6 I
                Node prvNode = get(index - 1);
    $ l: S7 a( j" ^) T, j$ h            insertedNode.next = prvNode.next;& s8 B( A7 R* G) R
                prvNode.next = insertedNode;
    . y" y: X. k; I8 v        }
    . C9 b! o; v( y* h* l        size++;
    & l2 J" K) A* }6 M# P( d    }
    . }* U- L  o8 H6 _) ~6 Q6 V  _4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除) t9 F3 }" i3 Q& o) R0 Z" Z
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即" H  S" j' R% ?# Q0 ^
    可。

    9.png
    # M: [4 U0 v. X9 S9 s
    ' w  R% t, Q$ b4.1. 头部删除

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

    10.png 2 ~+ o, C0 J& o( m

    & N4 h8 ^1 S; M4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要: S+ |" M8 ~6 k$ \4 O% d
    删除元素的下一个节点即可。

    11.png + E4 }! u$ L( X2 e9 D

    # d; A3 h& o) q+ d  R' g2 B3 Z5 H* c8 O" m
    这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。
    0 }4 P1 [( N6 K9 L. `如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1), K0 y$ Y0 c* F% F/ m
    /**
    6 A$ o6 i8 ?! N0 A% ^* C- p. P: P     * 链表删除元素( M  C3 n; A! A2 a9 v$ |) W
         *$ y6 @/ Y. Q+ Q. R
         * @param index 删除的位置8 i4 j/ u8 g$ Q) O0 i" [8 k
         * @return 被删除的节点
    ! J6 I6 k8 Y% p7 g     */
    ! j3 q6 ^  X5 L" Z1 R$ b    public Node remove(int index) {0 I% c8 Y5 I' ^1 z
            if (index < 0 || index > size) {# \" J( d+ r) w( o1 h
                throw new IndexOutOfBoundsException("超出链表节点范围");
    4 D8 C) U+ Q% P; O6 E/ L1 ?$ a: O        }
    9 @+ x' F. ~6 ?8 s. n/ r' l# v        Node removeNode;3 _9 x" e2 x  m/ g
            if (index == 0) {- T5 l* j9 ~0 b" P
                if (size == 0) {& h* r1 M: {* `+ v1 d! N1 C
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");6 s& v7 C$ v! ^+ m. w  n
                }
    6 m& n8 I0 d% X  [            //删除头节点& m, |, p) r3 S9 ^- Q
                removeNode = head;
    + ^& d6 O% x# S4 v            head = head.next;9 d+ i# h" }8 S  ~; l
            } else if (index == size - 1) {
    - c: @# i2 W" ^0 A( g; N7 e            //删除尾节点8 ?) G# I8 B2 F; A) f9 z, }/ O
                Node preNode = get(index - 1);
    3 o( y! N: \& h) g$ s            removeNode = preNode.next;
    ' T9 ?; V  c1 b$ c- \) f0 V1 Z5 t- h) B            preNode.next = null;
    % Q8 ~3 G$ T! e4 x3 o) ]            last = preNode;' p9 |* R& o+ `" k5 V
            } else {
    0 a. N5 t+ }( X! e" d            //删除中间节点6 l1 q8 {; }* j
                Node prevNode = get(index - 1);' h$ y- R9 L+ t
                removeNode = prevNode.next;
    , I+ H, d% {# }            prevNode.next = prevNode.next.next;' ~( N5 I$ P; U/ Z$ t
            }
    0 i" o1 b% @* [8 l0 U5 k        size--;2 J: h% g' k" f1 C( c: w4 e
            return removeNode;
    8 f& I; h+ T" A1 c4 x  p    }& o7 n+ R+ m0 ~
    Java实现链表的完整代码package chapter2.part2;
    $ r' v2 D" A% y& u9 S6 W: ~. r
    ! M  F: B/ m' W5 Z, r" I. ~7 f; c8 y/**+ p  X2 F3 _- A. e' Q% }  H. ^
    * Created by IntelliJ IDEA.
    2 d; W- F2 |7 t' [- C' p *4 Y! ?" v8 l  g5 S5 g
    * @Author: 张志浩  Zhang Zhihao/ F* f0 f3 I+ p: G6 G' h# r
    * @Email: 3382885270@qq.com5 B& x+ i8 O; H( d& y
    * @Date: 2020/5/38 E! z5 F% ~( F& z" l$ s
    * @Time: 13:392 ~% u' h9 A1 D) U. D2 A
    * @Version: 1.0) v6 D* W% U( i; `8 W
    */
    2 d0 n# N" h% a4 cpublic class MyLinkedList2 {
    ! ]. ~9 y' W4 ]( Y5 e    private Node head; //头节点8 X" r( T. X) y6 V
        private Node last; //尾节点: |1 Y- q5 f' Z, ~2 l
        private int size; //链表实际长度' t6 {! a) S- s+ w! m
    3 m8 G, a% @4 s. a7 u) e$ @% y
        public static void main(String[] args) {5 O9 Y8 L1 M# M% s# \
            MyLinkedList2 myLinkedList = new MyLinkedList2();5 M- p7 [; `% I9 r
    //        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    . _4 A! d( i- \5 [. L4 U/ X//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围
    ( }* N! R8 p7 l) z        myLinkedList.insert(0, 3);$ L% [6 h1 g# J+ F8 L  ?
            myLinkedList.insert(1, 7);, r( T, f% I* h" b
            myLinkedList.insert(2, 9);
    : s( ]6 L/ @* g; V. ?  z8 e2 m        myLinkedList.insert(3, 5);
    ) ~! g7 z2 X$ d2 T1 U8 X0 p4 u        myLinkedList.insert(1, 6);
    : w, c/ `/ H' g% w+ j3 r# m* f; ?        myLinkedList.remove(0);
    % G) [% p6 I! f* z/ t        myLinkedList.set(0, 23);
    0 M* ?7 B& ?3 q" e* J) a0 z) k        myLinkedList.output();
    . f4 h4 U/ {+ c, u1 f    }
    # K9 g1 G- H6 M: K. Q& V2 z1 w- _6 Z+ |; o" l( Q$ j
        /**: l5 C. Z3 H4 Z( V
         * 链表插入元素9 U& ~% y/ O6 }" F  D
         *
    ' f9 N) z4 l2 z! A6 p3 _, H     * @param index 插入位置* L' J4 `  H. J
         * @param data  插入元素 被插入的链表节点的数据
    % ?# K" I/ v! ~$ y     */1 @( }* d# u. L. L6 X$ s9 ?/ \
        public void insert(int index, int data) {5 K, ]( u/ [& z& n9 y# q8 _* w
            if (index < 0 || index > size) {
    3 p. m4 s+ Q8 a( K4 _, t. y. X            throw new IndexOutOfBoundsException("超出链表节点范围!");
    / Q3 w4 }2 U+ M  ^        }# G8 ~# `+ A$ E  ]7 s* j; a) e# N
            Node insertedNode = new Node(data);7 J4 t- |( Z. C# w
            if (size == 0) {. I, ?. V9 }: n7 w
                //空链表
      `* ?" X) u( @- P2 ]5 o. M7 b            head = insertedNode;
    ' U. s; o  u# M1 ~2 k7 `            last = insertedNode;
    7 h. i  P( m4 G3 Q+ y, I5 v        } else if (index == 0) {
    / h; N6 h2 M# T( I( Z2 P+ D" S( Q            //插入头部
    - v' A$ ^$ R+ D% ]1 G7 B5 C0 x1 X            insertedNode.next = head;0 q6 v7 U. T% i# Y& @2 x
                head = insertedNode;
    / M" A8 [( ]8 b4 ]        } else if (size == index) {7 |3 W" ?4 y$ r
                //插入尾部  T# ]: }) ^" Y5 O2 n
                last.next = insertedNode;0 G9 x) Z* k# K! X4 [
                last = insertedNode;
    " t) l6 k6 ^- a4 `4 E) Z        } else {# U6 C" ]9 q, R& x0 |' i4 W6 T
                //插入中间# |. b, C/ Y8 x* W
                Node prvNode = get(index - 1);3 p% a: X' v# J* ~% M& ^
                insertedNode.next = prvNode.next;
    # s  U& s5 }" {( I# ^% I) n            prvNode.next = insertedNode;
      s. w9 Q# j4 }( U% X* {2 E% S        }
    0 G4 s8 W1 a% O* f! i        size++;& O6 H; d' p% {; Y+ ~) F
        }
    9 B8 G$ K9 \! t8 G7 K+ x3 ]7 U& a& |% E, y
        /**
    ( i, Y# P8 F! I" w     * 链表删除元素- I: J9 [+ |' }/ T$ O0 X
         *# W' A- z0 i/ b
         * @param index 删除的位置
    ( W- C. q, v- r  M! w- l* F9 Q     * @return 被删除的节点, F6 P! u2 o* r  Q' ?. W$ Q
         */$ B1 r; f% C: e# m! k6 U1 L% x8 i
        public Node remove(int index) {
    $ N$ g0 U3 }: C) \2 r9 A3 k( j        if (index < 0 || index > size) {# V' H/ l3 n' Q% Y
                throw new IndexOutOfBoundsException("超出链表节点范围");  w/ F, F4 t2 B6 m7 K) [" Z) V
            }
    + O. G- M- p. r( l        Node removeNode;
    , U6 h, A2 r, J        if (index == 0) {1 Z/ o8 F4 P/ e7 \
                if (size == 0) {# N$ _) |: f5 h" h0 q, w. B8 D2 ~
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");
    ( f, t) T, l: _1 D* y) q1 u            }
    , j/ n" M/ \, n5 p& i+ m            //删除头节点- T0 s/ N  ^  }& f% `
                removeNode = head;
    ' N! s; f; t3 Q' b, K            head = head.next;% N5 e/ z, U2 B+ j3 f
            } else if (index == size - 1) {: b; `( M& V4 T$ Z
                //删除尾节点1 s0 y5 F9 {- W( C, p
                Node preNode = get(index - 1);
    $ ?; ]" S8 p$ N7 P! v' y* M            removeNode = preNode.next;4 z$ y: Q/ X2 _2 W6 k/ t% e
                preNode.next = null;; s) t, T! O8 k# b/ J' p
                last = preNode;) u* P6 g4 E4 j- I- N2 v
            } else {
    ! ]8 M) n2 r  v            //删除中间节点% a/ v* h# m* o3 ~4 |  d  A' Y
                Node prevNode = get(index - 1);
      z; q! R& h0 y3 e            removeNode = prevNode.next;
    ' l. w9 A/ `0 e  E8 @            prevNode.next = prevNode.next.next;4 q% t; |5 ]! W- R* [1 k; L* }
            }
    8 E' n6 ^+ F/ j        size--;
    % s/ B- P& K! r        return removeNode;
    2 _& \; k, t( B    }" F! z1 I6 q0 p; \6 g
    , ^; U# |# W4 s9 k
        /**
    8 O+ X$ s7 s7 N( }# s0 o1 _1 k) u. o     * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    - J! B6 |% {  o: q     *
    ) L# R( r, @# a+ |% T* U8 X     * @param index 需要更新的节点的位置
    , L% }6 ^" Y$ [8 l     * @param data  新data6 ]( g  @! [+ s" F' u, W" y0 x- l' \% j
         * @return 旧data
    8 }1 X$ h! m$ n     */# L# Z* t7 I( f1 X, l/ c; @% }) R% r
        public int set(int index, int data) {
    5 A0 z& P5 K8 ]' U4 o" h4 V        Node x = get(index);
    7 m3 H0 P, s0 E+ a/ [        int oldVal = x.data;
    , o/ [$ {  ~0 W# s  [0 Q& D; Z        x.data = data;# u* J+ s/ h7 h' ?  l
            return oldVal;
    ) m3 T8 W7 a5 P$ O# n    }$ S3 |1 t2 U! t: `0 p9 f
    7 X1 l5 U( [) u& t, k8 J2 L
        /**. n6 M8 s9 c% M3 `) T# p* t' w$ f6 R
         * 链表查找元素) P- [8 I, c6 f
         *
    # d  |' c# a5 L9 I5 n* q: \     * @param index 查找的位置4 x0 Z& `/ l& ~% N
         * @return index位置的Node对象' C0 C, U3 W* u; F3 u, t, N
         */
    8 l' v$ s0 t7 h! Y4 @    public Node get(int index) {& A+ w& M" k/ N
            if (index < 0 || index > size) {6 f$ _8 p% f8 F3 @1 Q+ {* O! o
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    . r) F! }7 v8 m* p) ^2 o! s        }* M' J' E! R9 j& K5 E# d3 m
            Node temp = head;
    9 g5 e: W) B& s9 a; V        for (int i = 0; i < index; i++) {
    2 u! M( }! ~! o            temp = temp.next;: }3 T; H  G* q  U, h  h' U" h
            }' \2 f0 M9 i2 Y
            return temp;) \; M# ^6 B7 W8 T; ]( `
        }
    : `, N4 g5 r9 j: B/ Q0 n3 |, L
    ! h3 `2 n9 _- W' x7 }    /**: L/ F7 G8 F* K% D& _
         * 输出链表& x& b) |: W8 Y# F9 D. R" g
         */
      R6 r5 a1 S$ b: J' B    public void output() {
    ; u5 o  ^" s7 P: v* U6 i        Node temp = head;
    3 a7 ]) Z8 }' B% d        while (temp != null) {* ^- P6 F3 p3 Z. ]' q
                System.out.print(temp.data + " ");8 M$ d, A6 M6 h  P8 k4 U) y3 C
                temp = temp.next;
    & Z: U# y: S; r; V        }
    ' M! `! x) T( \+ b    }
    8 g  ]8 C4 Q" z" |( d* W; O# E; W' d: N
        /**5 [& H+ S' P5 C( n% X0 O
         * 链表节点; t# L7 J4 y5 i
         */3 g* |  Y3 X9 ?8 F2 W+ P, ~3 P
        class Node {& i& O! z' G1 X' H' {; l% [% M
            int data;
    4 b, X' E# y/ }        Node next;. C7 f, o  U8 _; ~
    6 B! ?: e& f! l' I( v/ [
            Node(int data) {
    9 r5 Y/ E( G- H2 M            this.data = data;
    ! W+ R$ Q# N! }        }# W5 i. {9 }4 v+ Q% c
        }8 o* Y, J- X1 v# Y  P
    }
    / K! p0 s0 _$ G8 s3 ^5 u- r& ]; T* n6 L" G
    5 p1 J& G* o0 p; ]8 s# Z
    二、双向链表 12.png
    3 e  |0 n+ d/ r/ b+ C3 N3 b6 w双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。! u* x/ m5 D! Z2 }3 ]
    7 b  `0 ]3 O( i4 d# V) B
    ' R: _) U8 D2 Y5 J
      N0 Z- W8 q/ |2 q# y' G

    2 }: P, S9 r( M3 A————————————————
    5 ?% L' Z% Y( I1 P- n0 E1 ^版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。6 G; M9 c# j! ^+ s5 i
    原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468
    4 L( _/ K! Z) \2 i. |' G/ k
    7 P. U8 z( r, n' Q  O, N" S! A! `, R. G! W4 G) H( G

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

    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-6-14 07:08 , Processed in 0.488417 second(s), 53 queries .

    回顶部