【单链表】大数据,请把它推给还不会单链表的人(下)

本文涉及的产品
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
简介: 【单链表】大数据,请把它推给还不会单链表的人

4.尾删:删除单链表尾部的最后一个结点

void SListPopBack(SLTNode** pplist)
{
  if (*pplist == NULL)
  {
    return;
  }
  else if ((*pplist)->next == NULL)
  {
    free(*pplist);
    *pplist = NULL;
  }
  else
  {
    SLTNode* prev = NULL;
    SLTNode* tail = *pplist;
    while (tail->next != NULL)
    {
      prev = tail;
      tail = tail->next;
    }
    free(tail);
    tail = NULL;
    prev->next = NULL;
  }
}

ce9b3a41d610467c8e247985ce9ef49b.png

f056b2d7c6fe471699a4978fbb72470a.png


5.头插:在存储第一个元素的结点前插入一个结点

void SListPushFront(SLTNode** pplist, SLTDataType x)
{
  SLTNode* newnode = BuySLTNode(x);
  newnode->next = *pplist;
  *pplist = newnode;
}

6.头删:删除存储第一个元素的结点

void SListPopFront(SLTNode** pplist)
{
  if (*pplist == NULL)
  {
    return;
  }
  else
  {
    SLTNode* next = (*pplist)->next;
    free(*pplist);
    *pplist = next;
  }
}

ea59364cd36049d6849b1f3b1fe3f76b.png

7.在pos结点后插入一个结点

void SListInsertAfter(SLTNode* pos, SLTDataType x)
{
  assert(pos);
  SLTNode* newnode = BuySLTNode(x);
  newnode->next = pos->next;
  pos->next = newnode;
}

12381cc44d384c98865f6ea0614a0524.png

8.在pos结点后删除一个结点

void SListEraseAfter(SLTNode* pos)
{
  assert(pos);
  if (pos->next == NULL)
  {
    return;
  }
  else
  {
    SLTNode* next = pos->next;
    pos->next = next->next;
    free(next);
  }
}

74c800ca4af84485b68cde59c0629b72.png

SLTNode* SListFind(SLTNode* plist, SLTDataType x)
{
  SLTNode* cur = plist;
  while (cur)
  {
    if (cur->data == x)
    {
      return cur;
    }
    cur = cur->next;
  }
  return NULL;
}

279625c7eb844afcbf36672e2a174e05.png


10.单链表的销毁

void SLTNodeDestory(SLTNode** pphead)
{
 SLTNode* cur=*pphead;
 while(cur)
 {
  SLTNode* next=cur->next;
  free(cur);
  cur=next;
 }
}

有小伙伴看到这里就可能会问了,为什么单链表的接口这里没有单链表的初始化,那是因为,单链表的初始化和销毁也就是对头指针进行操作,那个一步就能完成,所以在主函数里面就可以完成,可以但没必要创建一个专门的接口去处理。


另外插一句,单链表的头很重要,


例一:如果要想清空一个结点,只用phead=NULL即可,只要头指针还在,队伍还可以重新拉起来,只要青山在,不怕没柴烧;但是要销毁单链表则需要将头指针free掉,这样这个单链表才真正的out了。


例二:只要找到了头指针,就可拉起整个单链表,遍历就可以找到每一个结点。(这就是为什么在一些操作时要始终秉承这不能修改phead这个原则的原因)


小小实战:

请写用无头单链表依次尾插五个数1,2,3,4,5,并且删掉2这个数,并将删除后的链表反转,(暂时还不会写的话合理利用到上面的接口实现哦,相信你能独立写出来)


反转:


before:1-->2-->3-->4-->5-->NULL;


after:5-->4-->3-->2-->1-->NULL;


代码参考:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
typedef struct SLTNode
{
  int date;
  struct SLTNode* next;
}SLTNode;
SLTNode* BuySLTNode(int e)
{
  SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
  newnode->date = e;
  newnode->next = NULL;
  return newnode;
}
void SLTNodePushBack(SLTNode** pphead, int e)
{
  SLTNode* newnode = BuySLTNode(e);
  if (*pphead == NULL)
  {
    *pphead = newnode;
  }
  else
  {
    SLTNode* tail = *pphead;
    //尾插找尾
    while (tail->next != NULL)
    {
      tail = tail->next;
    }
    tail->next = newnode;
  }
}
void SLTNodePrint(SLTNode* phead)
{
  SLTNode* cur = phead;
  while (cur != NULL)
  {
    printf("%d->", cur->date);
    cur = cur->next;
  }
  printf("NULL");
  printf("\n");
}
SLTNode* SLTNodeFind(SLTNode* phead, int n)
{
  SLTNode* cur = phead;
  for (int i = 0; i < n; i++)
  {
    cur = cur->next;
  }
  return cur;
}
void SLTNodeErase(SLTNode** pphead, SLTNode*  pos)
{
  SLTNode* prev = *pphead;
  while (prev->next != pos)
  {
    prev = prev->next;
  }
  prev->next = pos->next;
  free(pos);
}
SLTNode* SLT_Reverse(SLTNode* phead)
{
  SLTNode* newphead = NULL;
  SLTNode* cur = phead;
  while (cur)
  {
    SLTNode* next = cur->next;
    cur->next = newphead;
    newphead = cur;
    cur = next;
  }
  return newphead;
}
int main()
{
  SLTNode* phead = NULL;
  SLTNodePushBack(&phead, 1);
  SLTNodePushBack(&phead, 2);
  SLTNodePushBack(&phead, 3);
  SLTNodePushBack(&phead, 4);
  SLTNodePushBack(&phead, 5);
  SLTNodePrint(phead);
  SLTNode* pos=SLTNodeFind(phead, 1);
  SLTNodeErase(&phead, pos);
  SLTNodePrint(phead);
  SLTNode* newphead=SLT_Reverse(phead);
  SLTNodePrint(newphead);
  return 0;
}

打印结果:

78127b8e89a04d728e35a847170908b4.png


相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
目录
相关文章
|
7月前
|
存储 缓存 算法
链表全景:探索单链表、双向链表与循环链表【实战演练】
链表全景:探索单链表、双向链表与循环链表【实战演练】
87 3
|
7月前
|
存储
【单链表】数据结构单链表的实现
【单链表】数据结构单链表的实现
|
7月前
leetcode:203. 移除链表元素(有哨兵位的单链表和无哨兵位的单链表)
leetcode:203. 移除链表元素(有哨兵位的单链表和无哨兵位的单链表)
40 0
|
3月前
|
存储 算法 C语言
C语言手撕实战代码_循环单链表和循环双链表
本文档详细介绍了用C语言实现循环单链表和循环双链表的相关算法。包括循环单链表的建立、逆转、左移、拆分及合并等操作;以及双链表的建立、遍历、排序和循环双链表的重组。通过具体示例和代码片段,展示了每种算法的实现思路与步骤,帮助读者深入理解并掌握这些数据结构的基本操作方法。
|
6月前
|
存储
链表入门(单链表讲)
链表入门(单链表讲)
链表入门(单链表讲)
|
5月前
链表4(法二)------7-4 sdut-C语言实验-单链表中重复元素的删除
链表4(法二)------7-4 sdut-C语言实验-单链表中重复元素的删除
33 0
|
7月前
|
存储 编译器
单链表与双链表实现
单链表与双链表实现
|
6月前
|
存储
【海贼王的数据航海】链表—单链表
【海贼王的数据航海】链表—单链表
34 0
|
7月前
特殊链表(循环单链表,循环双链表,静态链表)
特殊链表(循环单链表,循环双链表,静态链表)
56 3
|
6月前
|
算法
数据结构和算法学习记录——线性表之单链表(下)-头插函数、尾删函数、头删函数、查找函数、pos位置插入&删除数据、单链表销毁
数据结构和算法学习记录——线性表之单链表(下)-头插函数、尾删函数、头删函数、查找函数、pos位置插入&删除数据、单链表销毁
65 0