环形链表去掉了空结点,其尾结点与头结点相连
总结了一些创建链表,前插入结点,后插入链表,插入,删除,求长度,查找,和求约瑟夫问题的一些操作
环形链表先就这样了。
以下代码:
#include<stdio.h>
#include<stdlib.h>
//环形链表去掉了空结点,其尾结点与头结点相连
typedef struct node
{
int data;
struct node *next;
}Node, *LinkList;
//创建链表,前插入结点,插入,删除,求长度,查找,约瑟夫问题
LinkList createList(LinkList L, int i) {
int data;
LinkList p, q;
if (i <= 0)return L;
L = (LinkList)malloc(sizeof(Node));
printf("依次输入%d个数据:", i);
scanf("%d", &data);
L->data = data;
q = L;
if (i > 1) {
for (int j = 1; j < i; j++) {
p = (LinkList)malloc(sizeof(Node));
scanf("%d", &data);
p->data = data;
q->next = p;
q = p;
}
}
q->next = L;
return L;
}
LinkList getNode(LinkList L, int data) {
LinkList p = L;
if (!L)return L;
while (p->next != L) {
p = p->next;
if (p->data == data)
return p;
}
if (p->data == data)
return p;
else return L;
}
//添加数据到表头
LinkList addHead(LinkList L, int data) {
LinkList p = L, q;
q = (LinkList)malloc(sizeof(Node));
q->data = data;
if (!L) {
L = q;
q->next = q;
}
else {
while (p->next != L)
p = p->next;
p->next = q;
q->next = L;
L = q;
}
return L;
}
//添加数据到表尾
LinkList addTail(LinkList L, int data) {
LinkList p = (LinkList)malloc(sizeof(Node));
LinkList q = L;
p->data = data;
if (!L)
{
L = p;
p->next = L;
return L;
}
while (q->next != L)
q = q->next;
q->next = p;
p->next = L;
return L;
}
//获取长度
int getlen(LinkList L) {
int cnt = 1;
LinkList p = L;
if (!p)
return 0;
while (p->next != L) {
p = p->next;
cnt++;
}
return cnt;
}
//若数据n在链表中存在,则把m插入到n的前面,否则插入到链表的最后面
LinkList InsertNode(LinkList L, int m, int n) {
LinkList p = L, pre = 0, newList;
newList = (LinkList)malloc(sizeof(Node));
newList->data = m;
if (!L)
return L;
if (L->data == n) {
LinkList q = L;
while (q->next != L)
q = q->next;
q->next = newList;
newList->next = L;
L = newList;
return L;
}
while (p->next != L) {
if (p->data == n)
break;
else {
pre = p;
p = p->next;
}
}
if (p->data == m) {
pre->next = newList;
newList->next = p;
}
else {
p->next = newList;
newList->next = L;
}
return L;
}
void deleteNode(LinkList *L, int m) {
LinkList p = *L, pre;
while (p->next != *L) {
if (p->data == m) {
break;
}
else {
pre = p;
p = p->next;
}
}
if (p == *L) {
LinkList q = *L;
while (q->next != *L)
q = q->next;
q->next = (*L)->next;
*L = (*L)->next;
free(p);
return;
}
if (p->data == m) {
pre->next = p->next;
free(p);
*L = pre->next;
}
}
void PrintList(LinkList L) {
LinkList p = L;
printf("数据\t当前结点\t下一结点\n");
if (!p)
return;
if (p->next == L) {
printf("%-4d %p\t%p\n", p->data, p, p->next);//64位操作系统中,指针为8 byte
}
else {
while (p->next != L) {
printf("%-4d %p\t%p\n", p->data, p, p->next);
p = p->next;
}
printf("%-4d %p\t%p\n", p->data, p, p->next);
}
printf("------------------------------------------------------------\n");
}
void YueSeFu(LinkList *L, int m, int n) {
while (--m) {
*L = (*L)->next;
}
//直到剩下一个为止
while (getlen(*L) != 1) {
for (int i = 0; i < n - 1; i++) {
*L = (*L)->next;
}
printf("'%d'被移除掉,剩余数字排列为:\n", (*L)->data);
deleteNode(L, (*L)->data);
PrintList(*L);
}
}
int main() {
LinkList L = 0;
int num1, num2;
//尾插法创建链表
//printf("输入你要创建的结点个数:");
//scanf("%d", &num1);
//L = createList(L, num1);
//PrintList(L);
//printf("输入你要添加到表头的数据:");
//scanf("%d", &num1);
for (int i = 1; i <= 5; i++) {
L = addHead(L, i);
}
PrintList(L);
printf("当前链表的长度为%d\n", getlen(L));
printf("输入约瑟夫问题起始的位置m,与报数n:");
scanf("%d %d", &num1, &num2);
YueSeFu(&L, num1, num2);
printf("插入数据m到链表中数据n的前面,请输入 m和n:");
scanf("%d %d", &num1, &num2);
L = InsertNode(L, num1, num2);
PrintList(L);
printf("以数值n的结点为头结点,请输入n:");
scanf("%d", &num1);
L = getNode(L, num1);
PrintList(L);
printf("删除数据n的结点,以n后面的结点作为头结点:");
scanf("%d", &num1);
deleteNode(&L, num1);
PrintList(L);
return 0;
}