QQ登录

只需要一步,快速开始

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

    ( M; Q% Y3 u4 M% L$ g  `【Java演示】什么是链表?数据结构
    5 Q4 g3 |. e/ W一、单向链表, m6 j& U2 x0 }; Y4 ^% t

    ) h$ |  c/ H$ m/ w! ?' c& Q 1.png
    & O/ K$ ^! |  m; M3 B- \链表(linked list)是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。
    + X/ y3 }. S/ c; F6 S5 s单向 链表的每一个节点又包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。
    0 u9 S- I! S) q$ X- A: E* j链表的第1个节点被称为头节点,最后1个节点被称为尾节点,尾节点的next指针指向空。
    4 p3 k7 I0 A: W$ O# w
    $ Q- W. p3 k. u& q什么叫随机存储呢?/ \( Q6 n4 a! f9 P' l+ h, w
    % I& y/ j, |; Y( ^$ V
    如果说数组在内存中的存储方式是顺序存储,那么链表在内存中的存储方式则是随机存储 。
    ! E; h, k% n) ~1 ]' v上一节我们讲解了数组的内存分配方式,数组在内存中占用了连续完整的存储空间。而链表则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。
    % q! ~3 r% y% r" Q 3.png
    ( G$ z! S+ b+ X2 ^6 {! S0 Y2 P* @) `; P$ d# K+ a

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

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

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

    4.png
    % s: L: s, y! [; n/ T4 l. Y6 H* c) ~8 e$ C; F9 U- K3 c
    /**
    8 O% m6 d/ k- f, h! W     * 链表查找元素, u  h0 p: Q3 I" z" [( j
         *1 n9 O# ?5 z4 K# u4 ^7 O- Y
         * @param index 查找的位置" N. |6 _' [8 t4 r8 f, ^* x  }
         * @return index位置的Node对象
    % y/ y: b6 y, J; Y     */* ?+ R! z: O- b  v: d$ M7 h
        public Node get(int index) {
    7 M) Q1 o$ X  Q+ _' l$ z        if (index < 0 || index > size) {% S! s) T, H' \, u
                throw new IndexOutOfBoundsException("超出链表的节点的范围!");
    ; y. W+ R* F* L) }# u" O+ T% P        }3 X( [- r* i* A5 N" Q. Q3 p8 W, ^
            Node temp = head;
    % F, R, p; u  u; a  H; k) Y+ [        for (int i = 0; i < index; i++) {% B  z9 W  I1 d8 D1 M1 k. x' i1 N
                temp = temp.next;
    5 `: O+ o; ?2 v' D( s+ R        }+ n' E# o0 D8 F% {7 P3 q' b
            return temp;% m. M+ G) s! B/ s: Q- o: U
        }, i& g5 ~8 H4 P. N; w7 m

    / X& b8 @" L/ `

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

    2. 更新节点 5.png
    4 x3 Q( k  X2 M7 Z' t9 Y' M
    1 G4 `$ W6 T  c8 o( f; n如果不考虑查找节点的过程,链表的更新过程会像数组那样简单,直接把旧数据替换成新数据即可。. W  {# F$ t: I4 N4 |( h
    如果不考虑查找元素的过程,只考虑纯粹的更新节点操作,时间复杂度是O(1)) B6 u- V: q, U
    /**4 u: w7 q3 l* [1 `! x  M
         * 更新节点 将列表中指定位置的节点的data替换为指定的data。6 a, U% @- j$ C1 n  i( ^1 n
         *
    2 E: ^" m' j! Y8 }/ @     * @param index 需要更新的节点的位置2 ]3 D  o1 \$ J% G8 H9 _% s8 T
         * @param data  新data, @6 a0 S3 V& C5 f
         * @return 旧data7 T% D2 {' c( n% b7 r2 A
         */4 `- `" i* @) X+ J+ w0 e
        public int set(int index, int data) {
    8 r, v% \( E7 d7 k! f  F) Q        Node x = get(index);0 f7 g6 {$ ^$ V- p
            int oldVal = x.data;
    + X  @3 I4 B: A/ C. z- i  K& w        x.data = data;0 P, n, G# O' f+ Y% s; _4 p
            return oldVal;
    . x9 J& i- b) G) l% i    }' h% B. x" }3 q( Z# {: S
    ' b2 ~3 t) D; ]4 |* |7 z
    3. 插入节点

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

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

    • 尾部插入
    • 头部插入
    • 中间插入
      3 W# T# N, H& ?
    3.1. 尾部插入

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


    # K! J1 J/ q6 R8 r3 C 6.png
    7 V; ]/ {, L% U/ f' _& X3.2. 头部插入

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

    • 第1步,把新节点的next指针指向原先的头节点。
    • 第2步,把新节点变为链表的头节点。+ v# a% @$ M" O+ n. I9 z( r
    7.png 1 g* v5 ~; ~! W. M
    2 o: Y4 |& U$ C6 K- J$ K* M
    3.3. 中间插入

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

    • 第1步,新节点的next指针,指向插入位置的节点。
    • 第2步,插入位置前置节点的next指针,指向新节点。4 Q" d0 }% N4 \2 X! J9 z6 c8 I; a
    8.png 2 [. P( b; x5 u' H3 t
    $ I4 @& O# _' j$ D3 v
    三钟情况的代码合到一起
    4 M6 ^; Q0 q+ Q" K
    " V$ J6 C. |2 P  @8 B4 E& a/**
    , }+ m, b6 E4 `! N% O+ K     * 链表插入元素
    ' e5 t+ R/ d! i& ?, P     *
    , g/ Y7 @/ s3 t# n     * @param index 插入位置
    5 e9 d* G  z# ]3 D6 v! t     * @param data  插入元素 被插入的链表节点的数据
    ) J6 R0 s, W  t     */1 j1 J4 _& ~: x" p
        public void insert(int index, int data) {
    ) X$ v" g3 ?; N/ H        if (index < 0 || index > size) {& c2 R: f/ h, s( C: n& |7 n
                throw new IndexOutOfBoundsException("超出链表节点范围!");. J! L4 [7 }' G6 ?% }
            }
    " ?) }& R: h4 P1 ?/ Y& X        Node insertedNode = new Node(data);
    9 r8 M( v# r/ C' Y' V7 n        if (size == 0) {
    : x! Y0 j( r/ w4 ~' o* \) v& U. G            //空链表5 Z$ `6 e9 {- q* \9 E) ]# C$ T
                head = insertedNode;9 m5 U! W: f/ u" T+ w
                last = insertedNode;% p6 }( P# p( z
            } else if (index == 0) {
    # B9 ]% D  D; J! s* b            //插入头部
    + \/ y- s4 C7 D/ p            insertedNode.next = head;
    ! P' f8 x! D/ y/ D" y            head = insertedNode;& ?- W' g( p6 Q1 d  _" [0 G; f
            } else if (size == index) {. B" w- B7 u/ P
                //插入尾部
    5 J8 H- ?$ d: C# Z            last.next = insertedNode;
    0 w6 x, o/ P$ v$ [% R0 t( Q# p            last = insertedNode;* w) O5 b" n) b( s9 z
            } else {
    8 e  W/ }- j! R8 R! E            //插入中间- V" @4 v0 G, S: A
                Node prvNode = get(index - 1);' ]! y- y9 W2 s) y
                insertedNode.next = prvNode.next;& y- A5 x5 b& f2 i! W
                prvNode.next = insertedNode;; z  G# {& a  d* J
            }* X1 Y5 u2 M+ y" G
            size++;
    ( w$ t$ `  i- A, X8 W) y# i# X  l    }& s% @, h8 W0 v) a- t; G; c: n6 T
    6 c% Z- q2 T" D( G
    /*** z& M6 h" |* B9 b
         * 链表插入元素5 N0 a: l' [! \7 B4 [/ u
         *! }: y; E* I6 i- U# F9 f/ \
         * @param index 插入位置
    # i/ v; V- I2 M4 Q) Q     * @param data  插入元素 被插入的链表节点的数据
    4 A3 v: {3 e$ w( o     */, ?. @' S0 d- _
        public void insert(int index, int data) {
    8 i* F) n' }" A: ~* C+ N& A        if (index < 0 || index > size) {: O2 Z, H% @1 S
                throw new IndexOutOfBoundsException("超出链表节点范围!");* V1 }% C( L2 o. k! x9 t! Z
            }
    1 y7 h; E# N5 Q2 \# C. u8 u: S9 f* q        Node insertedNode = new Node(data);
    2 I$ X! V9 x5 S- C7 f! s  {        if (size == 0) {  w& K  H1 x$ s1 \
                //空链表
    # g( f9 B, t! X: {! n3 A0 q0 l            head = insertedNode;
    7 Q8 l8 f6 i" B* ~% S+ O2 e            last = insertedNode;' Y9 g8 g+ D5 N2 T. `
            } else if (index == 0) {9 P9 a. Z6 n( F8 {, Y$ c. m
                //插入头部* V9 r" }# l' ?% `% k: x
                insertedNode.next = head;
    & E9 \/ C) X) N3 Y( z  e1 K2 R7 C            head = insertedNode;1 Z7 ?8 s, x6 q  s
            } else if (size == index) {
    9 o$ I" S+ G9 @( S0 O+ i& Q% I            //插入尾部
    # \5 I) R3 h5 H9 `# Z& ]            last.next = insertedNode;, a7 k0 D7 Z) L# J# i  R0 ?4 D
                last = insertedNode;
      a, a0 |6 G+ U2 M        } else {  H  ^5 O* i3 w4 ]3 b) _% p
                //插入中间
      h1 _& L  o1 o1 y; \2 A' {3 x3 Z            Node prvNode = get(index - 1);/ T! O2 j2 R; M1 D+ t( ?
                insertedNode.next = prvNode.next;
    ' b+ D2 `9 k! f% \            prvNode.next = insertedNode;
    5 p5 _) p- c! P6 T7 ^        }
    7 }2 W+ A8 v1 S. Y$ O% S        size++;
    ( P& w' i6 d$ X- z    }
    ; C! N% R7 Y  \. e! S- a  ?4. 删除元素

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

    • 尾部删除
    • 头部删除
    • 中间删除. k! a. u  R3 z5 \9 a  K2 o
    4.1. 尾部删除

    尾部删除,是最简单的情况,把倒数第2个节点的next指针指向空即) c! [2 d6 S2 K
    可。

    9.png 8 I; D" n9 d) v: u6 U
    ' I, j1 \7 `! M8 q4 G4 o4 ?  r
    4.1. 头部删除

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

    10.png
    ) L3 C/ y0 h" W; ?' G: @5 F" T
    + v3 i1 R9 s2 ?4.1. 中间删除

    中间删除,同样很简单,把要删除节点的前置节点的next指针,指向要
    & q$ T/ S0 |4 S) D* S3 R删除元素的下一个节点即可。

    11.png
    5 X1 G) L6 ~* C' z' l: |
    % F' |1 p3 F, z4 _9 [- X6 L* y  {
    % ]0 v8 j- s8 m: @这里需要注意的是,许多高级语言,如Java,拥有自动化的垃圾回收机制,所以我们不用刻意去释放被删除的节点,只要没有外部引用指向它们,被删除的节点会被自动回收。5 |3 V: m; R6 O! E! `! W
    如果不考虑插入、删除操作之前查找元素的过程,只考虑纯粹的插入和删除操作,时间复杂度都是O(1)
    * s9 C5 W! X: z# x. j# f  F/**8 n7 ], E- Y" V5 q/ i; h! u$ z
         * 链表删除元素
    4 l4 ?0 n( t, _5 z2 i. K     *# h4 D: l$ U7 U. I
         * @param index 删除的位置
    0 B% P! e; V2 x: g$ E8 L9 \& H     * @return 被删除的节点
    / t2 p( C( W3 ?# d/ B- ~     */- x7 A7 Y5 f3 f1 W+ j  n
        public Node remove(int index) {
    . I* k5 y+ Q5 F        if (index < 0 || index > size) {% n. b4 i9 U. e' Y0 \( N
                throw new IndexOutOfBoundsException("超出链表节点范围");
    ( R, ]( u, s# M3 @/ d        }
    , X0 q! j  K2 u3 l        Node removeNode;, R' _0 T! r( J" Q0 b+ ?
            if (index == 0) {
    7 i9 Q4 P; d) Y7 r/ ^/ r            if (size == 0) {% H& @$ {2 i: b: h. w8 W: v
                    throw new NullPointerException("当前链表为空,不可以进行删除操作");4 j0 \: [( a9 S7 ^! s9 J, S6 Z
                }
    6 `7 P% y( C$ h$ A* r            //删除头节点0 q; }# P( S* A! Y$ T7 P: S
                removeNode = head;2 R2 ]. j6 \3 Z
                head = head.next;
    : M4 D7 \* y9 _, }! U# {0 M        } else if (index == size - 1) {9 Z$ U! I9 f; |1 E
                //删除尾节点* I- O9 `5 @( @7 k2 Y7 {! \: V$ z
                Node preNode = get(index - 1);
    7 U' p* _* M: d, U            removeNode = preNode.next;
    . b  ?- W# n, Z+ i" b% y1 h. o            preNode.next = null;
    # N$ G1 ?; Y" }            last = preNode;. |) R- b% o" K/ l& W, e
            } else {
    ( f. o$ q8 ~  q  z$ ^- o, I# ?% B& m            //删除中间节点
    ! p+ E' g; U( j8 a+ y& B( y  Z            Node prevNode = get(index - 1);# |4 n1 m+ B8 y" {: V2 x
                removeNode = prevNode.next;
    2 y$ \8 x  [$ L            prevNode.next = prevNode.next.next;
      i/ }. o- T4 ^5 R        }
    & j$ R# {) A# u, }6 {6 n, S6 R8 u: S        size--;
    " @0 H$ M; W1 m- `2 c        return removeNode;
    6 e1 K/ ^/ T8 B& F    }
    - j7 {; V1 k+ |0 [; s; dJava实现链表的完整代码package chapter2.part2;
    8 K$ f) A0 b1 s9 E0 m. \
    # w" N# }! {' U. k7 {& f/**
    0 @% J$ u3 E. q$ M( J * Created by IntelliJ IDEA.5 V, |: c' X4 H/ f4 g
    *
    ' ^9 ^: Y9 a9 W* e3 ~2 f- t * @Author: 张志浩  Zhang Zhihao* D* O# b7 s) Q3 Y- j: U' {3 p! `
    * @Email: 3382885270@qq.com; C8 N. ~+ V( O5 |& k2 B6 W' P! |
    * @Date: 2020/5/3
    ; L( }) B  q. v& Y * @Time: 13:39! e1 G. X* U: m2 i! p
    * @Version: 1.08 g( U" J8 V% Q2 _, S
    */
    $ d% n4 A7 f8 z- Ypublic class MyLinkedList2 {+ I+ I. c' F/ b" k2 z7 }1 s8 _
        private Node head; //头节点' `0 a, S+ F% z( j8 P
        private Node last; //尾节点# @  E' K- A+ K
        private int size; //链表实际长度( `' {; s4 D4 m% M
    , T1 f+ |4 M2 ?5 Z9 L
        public static void main(String[] args) {
    & x+ Y# n  U6 i: o! L        MyLinkedList2 myLinkedList = new MyLinkedList2();
    # {( V1 _4 `* w& c6 w* {4 n//        myLinkedList.remove(0); // java.lang.NullPointerException: 当前链表为空,不可以进行删除操作
    9 k1 H7 A. O3 K, U% y/ T) p# S//        myLinkedList.remove(3); // java.lang.IndexOutOfBoundsException: 超出链表节点范围# m* s' O- c6 p2 C8 k
            myLinkedList.insert(0, 3);
    " ?/ K/ H2 x7 ?: y$ r3 Z        myLinkedList.insert(1, 7);  i, B6 t( U/ Q* g7 T3 K
            myLinkedList.insert(2, 9);% J' V, t7 m  V. D
            myLinkedList.insert(3, 5);" k$ T7 w7 ~, x/ q# W
            myLinkedList.insert(1, 6);
    * I2 O8 |* V. `$ i5 s. R        myLinkedList.remove(0);& {% Q% W- u* g  ~' j/ |2 d
            myLinkedList.set(0, 23);6 p8 h7 @3 S+ J  _
            myLinkedList.output();
    3 g% Z# [* ]1 g  L6 u# ^$ k2 l( Q    }
    ( Z: N3 k* L" m
    0 X9 f! w7 G- S& B4 x8 y+ v- I    /**7 W. t" ^& P7 i% H1 U6 O2 J
         * 链表插入元素# B' Y2 V; N- k4 @
         *
    3 k$ |- I( ~$ |8 F4 N6 O- g5 S, Q     * @param index 插入位置
    3 x' ]# l. H3 j3 ]- Z5 P! t7 |     * @param data  插入元素 被插入的链表节点的数据
    ; s: r$ U% Y* T' H9 q     */
    - M; F: w; l/ [$ J    public void insert(int index, int data) {# P$ M* J# t6 |( K2 r* W4 a
            if (index < 0 || index > size) {
    * l! y4 m5 I3 F            throw new IndexOutOfBoundsException("超出链表节点范围!");
    1 A" M9 @( J9 I7 V: ^/ e5 {  T        }
    7 Z$ O  ]+ ^* N/ o# E- D        Node insertedNode = new Node(data);
    # ~3 f. r6 I& n        if (size == 0) {
    ) r: x. p7 W$ A5 C: V) @# Y            //空链表
    / [3 \, a5 o/ a) `, z6 i. e            head = insertedNode;5 |9 C% I! L: s8 x& g
                last = insertedNode;
    $ a7 j! J; `1 X# ~        } else if (index == 0) {4 p: l- W0 ~$ ~% v5 H
                //插入头部
    3 {/ y; o! o  D* ~, J5 R( |            insertedNode.next = head;
    8 M/ I6 u0 L, T3 c            head = insertedNode;
    5 ~  J' p' n) h4 y6 B' t1 |. w        } else if (size == index) {
    * ]7 s. x( g9 w+ u: K4 g            //插入尾部0 o3 j8 R" e! m/ }! i1 y/ I% D
                last.next = insertedNode;1 {. g8 [6 ]) B2 o9 P
                last = insertedNode;) E# u4 h; b- m8 S
            } else {
    8 x% y1 P/ _1 u+ v            //插入中间
    1 l( @( K5 E% z, g; P# b7 K            Node prvNode = get(index - 1);
    * k) T, y5 P! a: p            insertedNode.next = prvNode.next;; s/ l. J$ h1 [; u( ~
                prvNode.next = insertedNode;' \+ W% t6 V" a$ ~; s" F$ w
            }3 _% P9 C. O  I* c7 `5 `0 q8 _0 b
            size++;' L; d4 ?/ ]6 h3 h
        }
    0 P. o/ l1 j* o# K
    5 r, h$ w: q! ^  \1 u    /**
    + w# y& ~" p$ }4 _. W! U     * 链表删除元素# M& n: w  \; t  y. P+ g, m5 W
         *
    & u9 j& @8 ?2 V7 N: }1 t     * @param index 删除的位置4 K) \+ ^- H) c' c6 j1 V: O) t
         * @return 被删除的节点
    . K; U4 S# ^& c2 u( X/ E  q     */
    + D" }  w' p  I7 ~9 `    public Node remove(int index) {( Z8 R- {2 G9 g6 j% c
            if (index < 0 || index > size) {' W* Z8 T, g( |" W. \9 E& v1 |: p, U
                throw new IndexOutOfBoundsException("超出链表节点范围");3 p+ Z) j% Z! g2 l. r
            }: q1 m; U" F  ?+ w- B; [$ N
            Node removeNode;
    3 }6 w/ {. x2 @; z* E        if (index == 0) {) {7 {6 D$ f% \: i
                if (size == 0) {
    ' V: T. y4 f7 F4 V  `* o                throw new NullPointerException("当前链表为空,不可以进行删除操作");
    1 }9 @" |! d. w5 g$ _  V            }
    ' E( M$ l3 _3 H% j: W/ x            //删除头节点$ n! Y! M3 p' s
                removeNode = head;
    - v5 F  C% f& b$ \1 R1 F            head = head.next;! \7 U* Z! S$ U! u- Z8 g
            } else if (index == size - 1) {
    + t( N( H" V" `! f9 z0 F            //删除尾节点9 t2 f. u) K4 l- l) }9 Q7 p! i) U
                Node preNode = get(index - 1);3 l  C9 `( l! v$ u: x: z) X8 Y
                removeNode = preNode.next;
    & D( T( q% r, F4 Y- K            preNode.next = null;
    , j( W" z& Y7 s9 g            last = preNode;
    - r9 t4 L, G4 z, x, ^        } else {7 K6 H  y9 K8 D! h% p
                //删除中间节点" a( |7 `. i: C, t+ c% u
                Node prevNode = get(index - 1);
    1 z7 o# u: `+ G8 D  R' ~$ J            removeNode = prevNode.next;
    : Y8 i& k2 I8 ~) e) H            prevNode.next = prevNode.next.next;
    2 p3 D& W% M8 D: o        }
    9 \  j6 P9 f! F. x$ {$ o        size--;
    & I9 H0 K% G' [/ E$ K        return removeNode;
    0 A+ r: e6 K& b9 w/ Q6 r; s    }) s0 H$ n6 R" G5 y" _

    . t8 W8 f) V" ?" l7 w5 \- A    /**
      B4 V. o. {# ~7 W* M4 D     * 更新节点 将列表中指定位置的节点的data替换为指定的data。
    ' \$ q/ z$ X6 W9 c     *" P3 x) |. a) D
         * @param index 需要更新的节点的位置# t, u" S! W% G* R( T# m/ S1 I
         * @param data  新data
    . C3 y) \6 L8 S& Q: _* ^     * @return 旧data
      Q7 q) \( ]7 V, H! ^( c* p0 i     */8 Z& }/ g1 p4 L( W* o6 a" u% ^8 r
        public int set(int index, int data) {. i% Q* i! p: B. f! C5 T: M3 d
            Node x = get(index);
    - h! {6 b- b9 r2 b        int oldVal = x.data;1 G6 w' W8 F/ q3 e& \# {
            x.data = data;
    / y; }% r. A4 V% b/ D4 d, i, }        return oldVal;
    * `: @- |) D& s! ~( c    }9 m# y0 ~5 k+ [/ W/ I7 c* a% i: Z, r

    - }5 d3 d. h" t    /**
    " Y, v8 t3 H  U: {     * 链表查找元素. q- _) Y$ S" j$ W) v
         *7 x3 a( r# r' [; l* N: _
         * @param index 查找的位置
    / _+ i; ?+ H' C2 l  {     * @return index位置的Node对象% ^9 ?0 T3 H8 r- e5 P  f5 n! u
         */- Z& I8 ^% u$ b( _7 Y6 i- _; E
        public Node get(int index) {
    ; {; e, d* J; d# v        if (index < 0 || index > size) {
    4 k% \7 V" a8 @            throw new IndexOutOfBoundsException("超出链表的节点的范围!");' T5 l0 G$ N" K" \; @9 E$ ?
            }
    4 N. ~4 q+ P" `. Y3 `- V        Node temp = head;
    1 x# V) s) C$ I- o# m        for (int i = 0; i < index; i++) {9 Z2 L3 a+ J# }  F5 c
                temp = temp.next;
    : W# k7 T+ m" Z        }
    " |' G) R6 U6 @' _. C  U) j        return temp;
    ( c6 O; O1 \2 ?; J" V7 T    }
    : Q5 m# V' V6 f- A: z0 P% ~9 _5 v6 u: G  x: u
        /**7 I; e1 h) D% i
         * 输出链表
    / v- N% o9 ~6 ]* Z0 L( Z0 x1 C     */) a( ?9 H. s( R% \: s, H
        public void output() {
    . ]/ n7 M8 u) g4 P: o3 H0 x5 l( @/ E        Node temp = head;
    5 ~) D8 f9 P4 a/ x        while (temp != null) {2 p: @3 ]7 ]5 d7 O3 ]) ^0 L/ x
                System.out.print(temp.data + " ");
    $ @8 U* f- M: [6 f" Y$ P1 J: c& S7 `            temp = temp.next;0 w7 {) z% X* i( K
            }* G' _2 L7 x9 b1 h" p0 U  h
        }
    , H5 a. F) w4 I5 j1 x0 {- L6 r. e* j! d2 I- ^
        /**
    ) l6 v8 Y& d2 ~- H0 E( E9 r     * 链表节点
    , H& T4 e- |* q# I0 x4 S# j     */
    0 p+ N. j: Y% y5 D" j' p    class Node {: o8 ~  s2 I. }& O
            int data;" e! m& a' B, f, x4 S* h/ u7 O
            Node next;
    & T: X* t7 S0 C& l
    # I4 \5 I, O  A/ e: n% P, ?        Node(int data) {
    0 X3 h' V6 K- o5 c. q7 k+ @* d6 p2 a( U            this.data = data;
    4 w0 C* l! V3 m  ]) d; j        }9 ~' q# G- y  p5 r# j
        }) p" w# r2 Y  w7 v, x
    }
    2 o! ], z& j4 x# W7 C# w4 t; u: m! [1 ]. A! T- ~" k& D8 l

    ; W0 L3 d, t9 @. i2 m2 ~6 G二、双向链表 12.png
    ! n) G" L* W, U0 R' K* u双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev 指针。
    ( E) _- I) P) @& p+ m
    " D  w( g9 E6 Z/ `
    " b+ ?- E, P4 Z! M* @) `+ `. B& P; j/ k
      K. r6 A/ e% v6 q3 B) u
    ————————————————: C* k/ P5 R( P. U$ R( j# ?2 s
    版权声明:本文为CSDN博主「爱做梦的鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。1 O% {- G( b  d8 Z* y' a
    原文链接:https://blog.csdn.net/weixin_43124279/article/details/105904468+ R- _) s* {9 r7 X/ D
    0 S9 x+ `2 a& c+ L3 E+ f
    ! X( ]3 [, U: |, U: P

    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 15:35 , Processed in 0.551951 second(s), 53 queries .

    回顶部