本周我主要学习了链表的知识,包括链表的输出与出入、链表的逆向输出、链表的插入节点、链表的删除节点、循环链表;

话不多说,直接展示:

001.创建链表与输出链表

输入:

5

1 2 3 4 5

输出:

1 2 3 4 5

#include <stdio.h>

#include <stdlib.h>//……………………可使用malloc函数

typedef struct FFF //………………typedef可用于,快速表达结构体名的声明

{

int data;

struct FFF *next;

} link;

link *head, *p, *q, *r;
//……………………head:头指针,p:代替指针,r:输入指针

int n;

void creating_lianbiao() //………………创建一个链表

{

head = (link *)malloc(sizeof(link));//…………首先分配一个内存

head->next = NULL;//…………………………在对头指针初始化

p = head;//……………………………………用p代替头指针遍历

for (int i = 0; i < n; i++)

 {

r = (link *)malloc(sizeof(link));//………………步骤一致

r->next = NULL;

scanf(“%d”, &r->data);//………………借助r向data中输入元素

p->next = r;//………………………………连接节点

p = p->next;

}

}

int main()

 {

scanf(“%d”, &n);

creating_lianbiao();//……………………引用函数

p = head->next;//………………………………用p指针表示头指针的移动

while (p != NULL)

{

q = p;//……………………利用q指针代替p指针,便于释放内存

printf(“%d “, p->data);

p = p->next;//……………………向后移动

free(q);//…………………………………………释放节点内存

}

free(head);//…………………………………………释放头指针内存

}

002.链表的逆置

输入:

输出后:

#include <stdio.h>

#include <stdlib.h>//……………………可使用malloc函数

typedef struct FFF// ………………typedef可用于,快速表达结构体名的声明

{

int data;

struct FFF *next;

} link;

link *head, *p, *q, *r;
//……………………head:头指针,p:代替指针,r:输入指针

int n;

void creating_lianbiao() //………………创建一个链表

{

head = (link *)malloc(sizeof(link));//…………首先分配一个内存

head->next = NULL;//…………………………在对头指针初始化

p = head;//……………………………………用p代替头指针遍历

for (int i = 0; i < n; i++)

 {

r = (link *)malloc(sizeof(link));//………………步骤一致

r->next = NULL;

scanf(“%d”, &r->data);//………………借助r向data中输入元素

r->next = head->next;

head->next = r;

//…………直接连接r的下一节点连接头节点(head)的下一节点,

//不断这样做,使用每一次输入的节点连接在头节点之后,从而使得第一个输入的反而在末尾,实现逆向。

}

}

int main()

 {

scanf(“%d”, &n);

creating_lianbiao();//……………………引用函数

p = head->next;//………………………………用p指针表示头指针的移动

while (p != NULL)

{

q = p;//……………………利用q指针代替p指针,便于释放内存

printf(“%d “, p->data);

p = p->next;//……………………向后移动

free(q);//…………………………………………释放节点内存

}

free(head);//…………………………………………释放头指针内存

}

003.链表的奇偶分家

2021年12月19日

19:24

1.4 编写程序,输入若干正整数,按从小到大次序建立1个带头结点单链表,设计一个实现单链表分离算法的Split函数,将原单链表中值为偶数的结点分离出来形成一个新单链表,新单链表中头结点重新申请,其余结点来自原链表,分离后,原链表中只剩非偶数值所在结点,最后显示2个单链表,在程序退出前销毁单链表。要求Split算法时间复杂性达到O(n),程序不可存在内存泄漏。

输入格式:

若干正整数。

输出格式:

每个单链表输出占一行,元素间用分隔符->分隔;初始单链表、剩余元素单链表、偶数元素单链表,共3行。

输入样例:

100 2 3  50 2 1 5 8

结尾无空行

输出样例:

1->2->2->3->5->8->50->100
1->3->5
2->2->8->50->100

来自 <PTA | 程序设计类实验辅助教学平台>

/*思路:

利用数组先存入未知个数字,之后再冒泡排序,之后用三个函数创建三个链表,分别输出。*/

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

typedef struct sss

{

int data;

struct sss *next;

} LLL;

LLL *head, *p, *q, *r, *ohead, *jhead;

int num[1000];

//…………创建多个链表,关键在于头节点的不同,例如:head、ohead、jhead…………

void maopao(int num[], int n)//………………先对数组冒泡排序

 {

int i, j;

int temp;

for (i = 0; i < n – 1; i++)

 {

for (j = 0; j < n – 1 – i; j++)

{

if (num[j] > num[j + 1])

{

temp = num[j + 1];

num[j + 1] = num[j];

num[j] = temp;

}

}

}

}

void creat(int num[], int n)//………………创建普通链表

{

head = (LLL *)malloc(sizeof(LLL));

head->next = NULL;

p = head;

int i;

for (i = 0; i < n; i++)

{

r = (LLL *)malloc(sizeof(LLL));

r->next = NULL;

r->data = num[i];

p->next = r;

p = p->next;

}

}

void oocreat(int num[], int n)//………………创建偶数链表

{

ohead = (LLL *)malloc(sizeof(LLL));

ohead->next = NULL;

p = ohead;

int i;

for (i = 0; i < n; i++)

 {

if (num[i] % 2 == 0)

{

r = (LLL *)malloc(sizeof(LLL));

r->next = NULL;

r->data = num[i];

p->next = r;

p = p->next;

}

}

}

void jjcreat(int num[], int n)//……………创建奇数链表

{

jhead = (LLL *)malloc(sizeof(LLL));

jhead->next = NULL;

p = jhead;

int i;

for (i = 0; i < n; i++)

 {

if (num[i] % 2 != 0)

 {

r = (LLL *)malloc(sizeof(LLL));

r->next = NULL;

r->data = num[i];

p->next = r;

p = p->next;

}

}

}

int main()

 {

int F = 1, n = 0;

while (scanf(“%d”, &num[n]) != EOF) //…………存入一个数组

{

n++;

}

maopao(num, n);

creat(num, n);

oocreat(num, n);

jjcreat(num, n);

p = head->next;//……………分三次输出

while (p != NULL)

{

q = p;

if (F) {

printf(“%d”, p->data);

F = 0;

} else {

printf(“->%d”, p->data);

}

p = p->next;

}

printf(“\n”);

p = jhead->next;

F = 1;

while (p != NULL)

 {

q = p;

if (F) {

printf(“%d”, p->data);

F = 0;

} else {

printf(“->%d”, p->data);

}

p = p->next;

}

printf(“\n”);

F = 1;

p = ohead->next;

while (p != NULL)

{

q = p;

if (F) {

printf(“%d”, p->data);

F = 0;

} else {

printf(“->%d”, p->data);

}

p = p->next;

}

return 0;

}

004.循环链表(约瑟夫问题变形)

2021年12月19日

19:34

编号为1…N的N个小朋友玩游戏,他们按编号顺时针围成一圈,按顺时针次序报数,从第1个人报到第M个人出列;然后再从下个人开始报到第M+1个人出列;再从下一个人开始报到第M+2个人出列……以此类推不断循环,直至最后一人出列。请编写程序按顺序输出出列人的编号。 

输入格式:

输入为2个整数,分别表示N、M(1≤N,M,K≤10000)。

输出格式:

输出为一行整数,为出列人的编号。每个整数后一个空格。

输入样例1:

6 3

结尾无空行

输出样例1:

3 1 2 6 4 5

结尾无空行

输入样例2:

10 2

结尾无空行

输出样例2:

2 5 9 6 4 8 7 3 1 10

结尾无空行

输入样例3:

5 1

结尾无空行

输出样例3:

1 3 2 5 4

结尾无空行

来自 <PTA | 程序设计类实验辅助教学平台>

C++:

/*本题思路:

本题思路在于利用两个函数,分别控制创建循环链表、

链表输出:循环链表利用末节点连接头节点,实现循环;

链表输出:连用链表特性实现链表内部循环计数,及时淘汰

部分数字。*/

#include <iostream>//……………………C++万能头

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <algorithm>

#include <cmath>

#include <string>

#include <map>

#include <vector>

#include <stack>

#include <set>

#include <bitset>

#include <cctype>

using namespace std;

typedef struct ss

 {

int date;

struct ss *next;

} gg;

int i, n, m;

gg *p, *q, *head, *r;

void creating_xunhuan()//…………创建循环链表

 {

head = (gg *)malloc(sizeof(gg));

head->next = NULL;

p = head;

for (i = 1; i <=n; i++)//………………先构建一个编号的链表,1~n

{

r = (gg *)malloc(sizeof(gg));

r->next = NULL;

r->date = i;

p->next = r;

p = r;

}

p->next = head->next;//………………使末节点连接头节点,实现头尾相接循环

}

void print() //………………………………执行函数

{

int sum = 0, count = 0;

q = head->next;//………………定义一个新指针代替头指针

while (count != n) //……………………控制淘汰所有人后退出

{

sum++;

if (sum == m)//……………………控制每次淘汰的编号

 {

while (q->date == 0)// ………………再次控制跳过已被淘汰的编号,淘汰

                                   sum=m后的出现已淘汰的编号

{

q = q->next;

}

cout << q->date << ” “;

q->date = 0;//………………标记已淘汰的数字为零。

q = q->next;//………………指向下一个

m++;

sum = 0;

count++;

}

else //………………控制跳过已被淘汰的编号

{

while (q->date == 0)

{

q = q->next;

}

q = q->next;

}

}

}

int main()

{

scanf(“%d %d”, &n, &m);

creating_xunhuan();

print();

return 0;

}

C语言:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

typedef struct SS

{

int data;

struct SS *next;

} LINK;

LINK *p, *head, *q, *r, *pp, *temp;

int n, m;

void creat_lianbiao()

{

head = (LINK *)malloc(sizeof(LINK));

head->next = NULL;

p = head;

r = (LINK *)malloc(sizeof(LINK));

r->next = NULL;

r->data = 1;

p->next = r;

p = p->next;

for (int i = 2; i <= n; i++)

 {

r = (LINK *)malloc(sizeof(LINK));

r->next = NULL;

r->data = i;

p->next = r;

p = p->next;

}

p->next = head->next;

}

void panduan()

{

int sum = 0, rr = 0;

pp = head->next;

while (rr != n)

 {

sum++;

if (sum == m)

{

while (pp->data == 0)

{

pp = pp->next;

}

printf(“%d “, pp->data);

sum = 0;

rr++;

m++;

pp->data = 0;

pp = pp->next;

}

else

{

while (pp->data == 0)

{

pp = pp->next;

}

pp = pp->next;

}

}

}

int main()

{

scanf(“%d %d”, &n, &m);

creat_lianbiao();

panduan();

return 0;

}

 

005.单链表基本操作(插入、删除)

2021年12月19日

20:11

请编写程序实现单链表插入、删除结点等基本算法。给定一个单链表和一系列插入、删除结点的操作序列,输出实施上述操作后的链表。单链表数据域值为整数。

输入格式:

输入第1行为1个正整数n,表示当前单链表长度;第2行为n个空格间隔的整数,为该链表n个元素的数据域值。第3行为1个正整数m,表示对该链表施加的操作数量;接下来m行,每行表示一个操作,为2个或3个整数,格式为0 k d或1 k。0 k d表示在链表第k个结点后插入一个数据域值为d的结点,若k=0则表示表头插入。1 k表示删除链表中第k个结点,此时k不能为0。注:操作序列中若含有不合法的操作(如在长度为5的链表中删除第8个结点、删除第0个结点等),则忽略该操作。n和m不超过100000。

输出格式:

输出为一行整数,表示实施上述m个操作后的链表,每个整数后一个空格。输入数据保证结果链表不空。

输入样例:

5
1 2 3 4 5
5
0 2 8
0 9 6
0 0 7
1 0
1 6

输出样例:

7 1 2 8 3 5

来自 <PTA | 程序设计类实验辅助教学平台>

/*本题思路:

首先创建一个单链表,然后对于插入与删除分别创建一个函数,然后再讨论特殊

情况。插入函数首先找到目标数,然后在目标数后面连接一个数据。

删除函数跳过被删除的数字,实现删除。*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

typedef struct FFF

 {

int data;

struct FFF *next;

} link;

link *p, *q, *r, *mw, *head, *temp, *ed;

int n, nn, sc, cr, crh;

int j = 1;

void creat()//……………………创建一个链表

 {

int i;

head = (link *)malloc(sizeof(link));

head->next = NULL;

p = head;

for (i = 0; i < n; i++)

{

r = (link *)malloc(sizeof(link));

r->next = NULL;

scanf(“%d”, &r->data);

p->next = r;

p = r;

}

}

void shangchu()//………………删除函数

 {

temp = head->next;//………………设置一个代替头指针的指针

while (j < sc – 1) //………………找到删除位前一个节点

{

temp = temp->next;

j++;

}

mw = (link *)malloc(sizeof(link));

mw = temp->next;

temp->next = mw->next;

//…………思路:定义一个新节点,新节点代替下一个节点的位置,再由下一个节点//指向新指针的下一个节点,即利用新节点架空被删除的节点,再跳过目标点连接链表

j = 1;

}

void charu()//………………插入函数

{

if (crh == 0) //………………特殊情况,插入到第一个节点位置

{

ed = (link *)malloc(sizeof(link));

ed->data = cr;

ed->next = head->next;

head->next = ed;

//………………定义一个新节点,让新节点的下一个节点等于头指针的下一个节点,//再令头指针下一个节点等于新节点,后面节点自动退后。

     j=1;

}

else

 {

temp = head->next;

while (j < crh) //……………………找到被插入数

{

temp = temp->next;

j++;

}

ed = (link *)malloc(sizeof(link));

ed->data = cr;

ed->next = temp->next;

temp->next = ed;

//…………上同义。

j = 1;

}

}

int main()

 {

int F;

scanf(“%d”, &n);

creat();

scanf(“%d”, &nn);

int sum = nn;//………………sum=n也行

for (int i = 0; i < nn; i++)

{

scanf(“%d”, &F);

if (F)

{

scanf(“%d”, &sc);

if (sc > 0 && sc <=sum)

{

shangchu();

sum–;

}

}

else

 {

scanf(“%d %d”, &crh, &cr);

if (crh <= sum)

{

charu();

sum++;

}

}

}

p = head->next;

int gg = 1;

while (p != NULL)

 {

q = p;

printf(“%d “, p->data);

p = p->next;

free(q);

}

free(head);

return 0;

}


版权声明:本文为m0_61497842原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/m0_61497842/article/details/122030442