数据结构day5(单向循环链表)

 单向链表只能单向遍历,所以引出单向循环链表,单向循环链表尾结点

指向头结点的地址。

以下为单向循环链表增删改查约瑟夫循环功能函数的实现

head.h

#ifndef __DD_H__
#define __DD_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef char datedef[20];
// typedef int datedef;

/*
typedef struct
{
char name[20];
int age;
int score;
}student;

typedef struct Node       //定义单向链表结点
{
    union                 //数据域
    {
  int len;                //头结点的数据域 (链表长度)
  datedef date;           //其他结点的数据域
    };
    struct Node *next;    //指针域
}*linklist,Linklist;

linklist creat(int flag);    //创建新链表

*/

typedef struct Node // 定义单向循环链表结点
{
    union // 数据域
    {
        int len;      // 头结点的数据域 (链表长度)
        datedef date; // 其他结点的数据域
    };
    struct Node *next;              // 指针域
} *looplist, Looplist;
looplist creat(int flag);               // 创建新链表

int indel(looplist L, looplist p);             // p后删除 (中删)
int insert(looplist L, looplist p, datedef e); // p后插入 (中插)

void output(looplist L);                // 遍历

int h_insert(looplist L, datedef s);    // 头插
int h_del(looplist L);                  // 头删
int r_insert(looplist L, datedef e);    // 尾插
int r_del(looplist L);                  // 尾删

void yuesefu(looplist L, int m);        // 约瑟夫循环

void L_free(looplist L);                // 链表释放

#endif

fun.c

#include "head.h"

looplist creat(int flag) // 创建链表新结点
{
    looplist L = (looplist)malloc(sizeof(struct Node));
    if (L == NULL)
    {
        return NULL;
    }
    if (flag == 1)    // 头结点
    {
        L->len = 0;
        L->next = L;
    }
    else if (flag == 0) // 其他结点
    {
        strcpy(L->date, " ");
        L->next = NULL;        // 初始化
    }
    return L;
}

void output(looplist L) // 遍历
{
    if (L->next == L || L == NULL)
    {
        printf("遍历失败\n");
    }
    printf("输出的元素是:\n");
    looplist p = L;
    while (p->next != L)
    {
        p = p->next;
        printf("%s\t", p->date);
    }
    puts("");
    printf("该链表有%d个元素。\n", L->len);
}
/*
 *for(int i=0;i<p->len;i++)
 *{
 *p=p->next;
 *printf("%d\t",p->date);
 *}
 *puts("");
 */

int insert(looplist L, looplist p, datedef e) // p后插入 (中插)
{
    looplist s = creat(0);
    strcpy(s->date, e);
    s->next = p->next;
    p->next = s;
    L->len++;
    return 0;
}

int indel(looplist L, looplist p) // p后删除 (中删)
{
    looplist q = p->next;
    p->next = q->next;
    L->len--;
    free(q);
    q = NULL;
    return 0;
}

int h_insert(looplist L, datedef s) // 头插
{
    if (L == NULL)

    {
        printf("头插失败\n");
        return -1;
    }
    looplist q = creat(0);
    if (q == NULL)

    {

        return -1;
    }
    strcpy(q->date, s);
    q->next = L->next;
    L->next = q;
    L->len++;
    return 0;
}

int h_del(looplist L) // 头删
{
    if (L->next == NULL || L == NULL)

    {
        printf("删除失败\n");
        return -1;
    }
    looplist p = L->next;
    L->next = p->next;
    L->len--;
    free(p);
    p = NULL;
}

int r_insert(looplist L, datedef e) // 尾插
{
    if (L == NULL)

    {
        printf("链表不存在\n");
        return -1;
    }
    looplist p = creat(0);
    p = L;
    while (p->next != L)

    {
        p = p->next;
    }
    looplist s = creat(0);
    strcpy(s->date, e);
    s->next = p->next;    // s->next=L;
    p->next = s;
    L->len++;
}

int r_del(looplist L) // 尾删
{
    if (L == NULL || L->next == L)

    {
        printf("操作失败\n");
        return -1;
    }
    looplist p = L;
    while (p->next->next != L)

    {
        p = p->next;
    }
    looplist s = p->next;
    p->next = L;
    free(s);
    s = NULL;
    L->len--;
}

// 约瑟夫循环
void yuesefu(looplist L, int m) // 约瑟夫循环
{
    looplist p = L;
    int n = L->len;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m - 1; j++)
        {
            p = p->next;
            if (p == L)
            {
                p = p->next;
            }
        }
        looplist s = p->next;
        if (s == L)
        {
            s = s->next;
        }
        printf("%s\t", s->date);
        if (p->next == L)
        {
            p = p->next;
        }
        indel(L, p);        // p后删除 (中删)
    }
    puts("");
}

void L_free(looplist L) // 链表释放
{

    if (L == NULL)
    {
        return;
    }

    int n = L->len;
    for (int i = 0; i < n; i++)

    {
        h_del(L);        // 头删
    }
    free(L);
    L = NULL;
}

 

main.c

#include "head.h"

int main(int argc, const char *argv)
{

    looplist L = creat(1);

    int n;
    datedef s, e;

    /*
    printf("你要头插的元素个数:");
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
    printf("你要头插的元素是:");
    scanf("%s",s);
    h_insert(L,s);       //头插
    }
    output(L);

    */

    printf("你要尾插的元素个数:");
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        printf("你要尾插的元素是:");
        scanf("%s", s);
        r_insert(L, s);
              //尾插
    }
    output(L);

    /*
    h_del(L);            //头删
    output(L);


    r_del(L);            //尾删
    output(L);
    */

    printf("你要循环数的元素个数:");
    scanf("%d", &n);
    yuesefu(L, n);
            //约瑟夫循环

        L_free(L);
            //链表释放
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值