数据结构——链表

Posted by Beyonderwei on 2019-01-17
Words 846 and Reading Time 3 Minutes
Viewed Times

一、概念

  • 线性表:多个数据元素组成的有限序列。
  • 链表:线性表的链式存储结构

    二、分类

    1.单链表

  • 概念: 链表的结点包含数据域和指针域,指针域只有一个,并指向下一个结点。
  • 特点:插入删除数据的时间复杂度仅为O(1),不需要预分配存储空间。

    2. 循环链表

  • 概念:单链表中,终端结点的指针由空指针改为指向头结点的指针,形成一个环。
  • 特点:相对于单链表,循环链表可以在任意位置开始访问到整个链表,尾指针的存在方便了链表的合并。

    3. 双向链表

  • 概念:结点中除数据域以外包含两个指针域,一个指向前驱结点,一个指向后继结点。
  • 特点:相对于单项链表可以实现双向的查找。

    三、单链表

        注:C语言实现,包括单链表的创建、增加数据、查询某一个数据、删除某个结点、获取链表长度等。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    /**
    * singly_linked_list.c
    *
    * Created on: 2020年1月27日
    * Author: Beyonderwei
    */

    /*----------单链表----------*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>


    // 定义链表元素所存储的数据类型
    typedef int ElemType;
    // 定义节点的存储结构
    typedef struct Node
    {
    /* data */
    ElemType data;
    struct Node *next;
    }Node;
    // 定义链表指针
    typedef struct Node *LinkList;

    /**
    * Function 创建带有头节点的单链表,即创建一个头节点
    * @param:
    * list: 链表
    * @return 指向链表的指针
    */
    LinkList createList(void)
    {
    LinkList list;
    list = (LinkList)malloc(sizeof(Node));
    list->next = NULL;
    return list;
    }

    /**
    * Function 向链表追加数据
    * @param:
    * list: 链表
    * elem: 要追加的数据
    * @return 指向链表的指针
    */
    LinkList listAppend(LinkList list, ElemType elem)
    {
    LinkList tmp, node;
    tmp = list;
    while(tmp->next)
    {
    tmp = tmp->next;
    }
    node = (LinkList)malloc(sizeof(Node)); //生成一个新的节点,来存储数据
    node->data = elem;
    node->next = NULL;
    tmp->next = node;
    return list;
    }

    /**
    * Function 按照条件查找链表中的某个元素
    * @param:
    * list: 链表
    * elem: 要查找的数据
    * @return 指向该结点的指针
    */
    LinkList getElem(LinkList list, ElemType elem)
    {
    LinkList tmp = list;
    while(tmp)
    {
    if(tmp->data == elem) // 可以改为按照data中的某个条件来查找
    {
    return tmp;
    }
    else
    {
    tmp = tmp->next;
    }
    }
    return NULL;
    }

    /**
    * Function 获取链表的长度
    * @param:
    * list: 链表
    * @return 链表的长度(不包括头节点)
    */
    unsigned int getLength(LinkList list)
    {
    unsigned int length = 0;
    LinkList tmp;
    tmp = list;
    while(tmp->next)
    {
    length++;
    tmp = tmp->next;
    }
    return length;
    }

    /**
    * Function 按照条件删除链表的某一个结点
    * @param:
    * list: 链表
    * elem: 要删除的元素
    * @return list: 删除成功
    * NULL: 删除失败
    */
    LinkList deleteElem(LinkList list, ElemType elem)
    {
    LinkList last_node;
    LinkList tmp = list;
    while(tmp->next)
    {
    last_node = tmp;
    tmp = tmp->next; //因为头结点没有存储数据,直接略过
    if(tmp->data == elem)
    {
    last_node->next = tmp->next;
    free(tmp);
    return list;
    }
    }
    return NULL;
    }

    /*---------测试代码----------*/
    void main(void)
    {
    LinkList list;
    unsigned int length;
    list = createList();
    LinkList e;
    listAppend(list, 1);
    listAppend(list, 2);
    listAppend(list, 3);
    listAppend(list, 4);
    listAppend(list, 5);
    listAppend(list, 6);

    deleteElem(list, 7);
    deleteElem(list, 5);
    length = getLength(list);
    printf("链表长度为:%d\n",length);
    e = getElem(list, 6);
    if(e != NULL)
    {
    printf("查询的值为:%d\n",e->data);
    }
    printf("链表第一个元素:%d",list->next->data);
    }

四、循环链表与双向链表

    对于以上功能的实现仅仅是在单项链表上做了一些改变。


本文为作者原创文章,未经作者允许不得转载。

...

...

00:00
00:00