单向链表只能单向遍历,所以引出单向循环链表,单向循环链表尾结点
指向头结点的地址。
以下为单向循环链表的增删改查及约瑟夫循环功能函数的实现
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);
//链表释放
}