单循环链表的基本操作(educoder练习笔记)

前言

最近学习了循环链表,每天都在写代码->改代码,单循环链表对于我而言,可能就是与之前学习的单链表由尾结点从指向NULL变成指向head的转变~一开始写这道题的时候,也会一个顺手判断条件错写成NULL。好了,开始正题,下面就是今天我写的一道关于单循环链表的题目。

本关任务:

1.创建一个空的单循环链表;

2.实现递增有序的单循环链表的插入和删除操作;

3.实现单循环链表遍历并输出结点数据元素。

提升要求相关知识

1.与一般链表相比,单循环链表的尾结点指针指向头结点(下图中绿色标记的为链表头结点结点)。

2.为了访问方便第一个结点和尾结点,将头指针指向尾结点。如下图所示。

定义链表结点类型

struct node
{//链表结点类型,包含一个存放整型数据的 data 成员,和一个指向下一个结点的next成员
    int data;
    struct node* next;
};
typedef struct node* n;

创建空循环链表

struct node* createRlist()
{//函数功能:创建一个有一个空循环链表,返回值为头指针
    struct node* head = (struct node*)malloc(sizeof(struct node));
    head->data = 0;
    head->next = head;
    return head;
}

有序插入数据元素并使其递增

struct node* insertOrder(struct node* list, int insData)
{
    //在单向递增有序的循环链表(表头指针list)中插入数据元素insData,使之依然有序 。返回值是头指针
    n p = (n)malloc(sizeof(struct node));
    struct node* t= list->next;
    struct node* q = list;
    if (p == NULL){}
    else
    {
        while (t !=list)
        {
            if (t->data > insData)
            {
                //在t结点前插入p结点
                p->data = insData;
                p->next = t;
                q->next = p;
                return list;
            }
            t = t->next;
            q = q->next;
        }
        //链表为空的情况
        p->data = insData;
        p->next = t;
        q->next = p;
    }
    return list;
}

删除结点

int deleteData(struct node* list, int delData)
{
    //在单向递增有序循环链表(表头指针list)中删除所有值为delData的结点,返回值为删除结点的个数
    struct node* t = list->next;
    struct node* q = list;
    //count记录删除结点个数
    int count = 0;
    //判断链表不为空
    while (t != list)
    {
        if (t->data == delData)
        {
            q->next = t->next;
            count++;
        }
        t = t->next;
    }
    return count;
}

打印链表

void printRlist(struct node* list)
{
    //从链表第一个结点开始输出单向循环链表中各数据元素的值,每输出一个数据元素空一格
    struct node* p = list->next;
    while (p != list)
    {
        printf("%d ", p->data);
        p = p->next;
    }
}

销毁链表

int destroyRlist(struct node* list)
{
    //从第一个结点开始释放循环链表各结点占用的空间,返回值为最后一个结点的值
    //n记录最后一个结点的值
    int n=0;
    struct node* d = list->next;
    struct node* q = list;
    struct node* p = list;
    list = list->next;
    free(p);
    //判断是否为空链表
    while (list != q)
    {
        d = list;
        n = list->data;
        list = list ->next;
        free(d);
    }
    return n;
}

主函数

int main()
{
  struct node *head = createRlist();
  int num , data;
  scanf("%d",&num);
  for(int i=0;i<num;i++)
  {
     scanf("%d",&data);
     head = insertOrder(head, data);
      
  }
  printRlist(head);
  scanf("%d",&data);
  printf("\n%d ",deleteData(head,data));

  printf("\n%d ",destroyRlist(head));


  return 1;
}

总结

记录一次头歌的习题,这题折腾了一个早上,来来回回检查修改报错,最后终于过啦。这篇文章用来之后的复习,和大家共勉~

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值