数据结构:链表

    在学习算法时,发现用什么数据结构来存储数据是很重要的,所以学习数据结构也是必须的,先从基础数据结构:数组,字符串,链表,栈,队列,树,矩阵,邻接表,哈希表等,数组和字符串我们已经了解的很多了,所以我们从链表开始学习,了解什么是链表,链表存储数据的方式,以及如何对链表进行各种操作,如何用数组来模拟链表,如何用栈来做链表相关的题目。

1.何为链表

  由于顺序表的插入删除操作需要移动大量的元素,影响了运行效率,因此引入了线性表的链式存储——单链表。单链表通过一组任意的存储单元来存储线性表中的数据元素,不需要使用地址连续的存储单元,因此它不要求在逻辑上相邻的两个元素在物理位置上也相邻。同时因为单链表是非随机的存储结构,即不能直接找到表中某个特定的结点。查找某个特定的结点时,需要从表头开始遍历,依次查找。

      我们再看链表是什么:

      链表其实是由一个个结点组成,每个结点之间通过链接更新串联起来,每个结点都有一个后继结点,最后一个结点的后继结点为空结点

     图中就是一个链表其中橙色结点被称为黄色结点的前驱结点,黄色结点被称为橙色结点的后继结点,链表其实有单向链表、双向链表、循环链表等,这里先只介绍单向链表。那既然结点存储数据,怎么找到后驱结点呢?下面一起来看看吧

2.链表结点的定义

typedef struct ListNode
{
   int data;
   struct ListNode* next;
}ListNode;

     这就是一个结点的定义,我们把一个结点看成一个结构体,其中data是数据域,可以是任意类型,而struct ListNode* next定义了一个指向ListNode结构体的指针,这个指针的地址是后继结点,将指向下一个结点,这就是指针域,如下图所示  

      下面看看具体怎么创建一个链表的结点

3.链表结点创建

ListNode* ListCreateNode(int data)
{
   ListNode* node=(List*)malloc(sizeof(ListNode));
   node->data=data;
   node->next=NULL;
   return node;
}

     我们先用malloc函数分配一块内存空间,用来存放ListNode即链表对象,将数据域置为函数传参data,将指针域置为NULL,代表这是一个孤立的链表结点,最后返回这个结点的指针。

4.虚拟头结点

     为了方便对链表进行操作,避免第一个结点无法操作的问题,我们往往会建立一个虚拟头结点,这个头结点上不存储数据,只是指向链表的第一个结点

ListNode* head=ListCreateNode(-1);

5.链表的创建及初始化

     单链表有两种:一种是带虚拟头结点的,一种不带虚拟头结点。总的来说,带头结点的单链表相对于不带头结点的单链表来说,更加方便对链表进行操作,所以很多时候我们都是用带头结点的单链表,这里我们也只用学习带头结点的即可

5.1初始化带头结点的单链表

void InitList(ListNode* head) {
	head=(ListNode*)malloc(sizeof(ListNode));
    head->next=NULL;
}

5.2创建带头结点的单链表

5.2.1头插法

         头插法顾名思义就是从链表开头插入,先插入的后输出,后插入的先输入,例如,我想创建一个链表(4,7,9),输出就是(9,7,4)。

ListNode* HeadInsert(ListNode* head) {
    initlist(head); //初始化
    int n;
    scanf_s("%d",&n);
    for(int i=0;i<n;i++) 
    {
        ListNode* node = (ListNode*)malloc(sizeof(ListNode));
        int data;
        scanf_s("%d", &data);
        node->data = data;
        node->next = head->next;
        head->next = node;
    }
    return head;
}

5.2尾插法

     尾插法顾名思义就是从链表末尾开始插入,先插入的先输出,后插入的后输出

ListNode* TailInsert(ListNode* head) {
    initlist(head); //初始化
    ListNode* cur = (ListNode*)malloc(sizeof(ListNode));
    cur = head;
    int n,data;
    scanf_s("%d",&n);
    for(int i=0;i<n;i++) 
    {
        ListNode* node = (ListNode*)malloc(sizeof(ListNode));
        scanf_s("%d", &data)
        node->data = data;
        node->next =NULL;
        cur->next = node;
        cur = cur->next; 
    }
    return head;
}

6.链表基础操作 

     创建完链表之后,我们就要对链表进行操作了,常见的操作就是增删改查

6.1遍历操作

void PrintList(ListNode* head) {
    ListNode* cur = head->next;
    while (cur) {
        printf("%d ", cur->data);
        cur = cur->next;
    }
    printf("\n");
}

6.2求单链表的长度

int Length(ListNode* head) {
    ListNode* cur = head->next;
    int len = 0;
    while (cur) {
        len++;
        cur = cur->next;
    }
    return len;
}

6.3查找操作

6.3.1按值查找
ListNode* locateElem(ListNode* head, int data)
{
    ListNode* cur = head->next;
    while (cur && cur->data != data)
    {
        cur = cur->next;
    }
    return cur;
}
6.3.2按位查找
ListNode* getElem(ListNode* head, int i)
{
    int j = 1;
    ListNode* cur = head->next;
    if (i == 0)return head;
    if (i < 1)return NULL;
    while (cur && j < i)
    {
        cur = cur->next;
        j++;
    }
    return cur;
}

6.4插入操作

void Insert(ListNode* head, int i, int data)
{
    ListNode* pre = getElem(head, i - 1);
    ListNode* cur = (ListNode*)malloc(sizeof(ListNode));
    cur->data = data;
    cur->next = pre->next;
    pre->next = cur;
}

6.5删除操作

     将链表的第i个结点删除

void Delete(ListNode* head, int i) {
    if (i<1 || i>Length(head))return;
    ListNode* pre = getElem(head, i - 1);
    ListNode* cur = pre->next;
    pre->next = cur->next;
    free(cur);
}

6.6判空操作

bool Empty(ListNode* head) {
    if (head->next == NULL) {
        printf("Head is null\n");
        return true;
    }
    else {
        printf("Head is not null\n");
        return false;
    }
}
  • 29
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

c++机械师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值