本意是整理和复习,理解不深或者有错误的评论区提出即可。
只有第一关的代码里面有结构体的定义,其余我只放了功能函数。
初始代码
#include <stdio.h>
#include <stdlib.h>
//第一关代码
struct node
{//此处填写代码,定义链表结点类型,包含一个存放整型数据的 data 成员,和一个指向下一个结点的next成员
};
struct node *mycreateList()
{//此处填写代码,创建一个只有一个头结点的空链表,头节点的数据域赋值为0,并将表头结点的地址返回
}
//第二关代码
void myinsertHead(struct node * head, int insData )
{
/*在此处完成任务,实现在head为表头d 链表的头插数据元素insData的功能*/
//begin
//end
}
void myinsertTail(struct node * head , int insData )
{
/*在此处完成任务,在head为表头的单链表表尾插入数据元素insData*/
//begin
//end
}
void myprintList(struct node *L)
{
/*在此处完成任务,输出head为表头链表中的数据,每输出一个数据换一行*/
//begin
//end
}
//第三关代码
void reverseList_link( struct node *L)
{
//请在此处填入代码,实现链表逆置功能
//begin
//end
}
//第四关代码
int locateAndChange( struct node *L, int data)
{
//请在此处填入代码,在头结点为L的链表中查找 与data值相等的第一个结点,若能找到该结点,则将该结点的值与前驱结点的值交换
//若未找到与data值相等的结点,则返回值为-1,若找到的结点无前驱结点,则返回值为0,否则返回值为前驱结点的值
//begin
//end
}
//第五关代码
int destroyList(struct node *L)
{
//请在此处填写代码,实现将链表L的结点空间回收
//返回值为回收结点的个数,含头结点在内
}
第1关:链表数据结构定义及初始化链表
题目
任务描述
本关任务:完成创建一个带表头的空链表的操作。
编程要求
根据提示,在右侧编辑器补充代码,完成链表结点定义,创建带表头的空链表并返回表头的函数。
开始你的任务吧,祝你成功!
测试
输出:success to create 0
代码
功能函数
#include <stdio.h>
#include <stdlib.h>
//第一关代码
struct node
{//此处填写代码,定义链表结点类型,包含一个存放整型数据的 data 成员,和一个指向下一个结点的next成员
int data;
struct node* next;
};
struct node *mycreateList()
{//此处填写代码,创建一个只有一个头结点的空链表,头节点的数据域赋值为0,并将表头结点的地址返回
struct node* list = (struct node*)malloc(sizeof(struct node));
list->next = NULL;
list->data = 0;
return list;
}
主函数
int main(void)
{
struct node *L = mycreateList();
if(L==NULL)
printf("fail to create");
else
{ printf("success to create");
printf(" %d ",L->data);
}
return 1;
}
突然发现老师的代码给错了,这个是文件里面的第二关的代码,但是应该是第一关地方的哈哈
第2关:链表插入和遍历链表输出链表的操作
题目
任务描述
本关任务: 1.编写一个能向表尾插入结点的函数; 2.编写一个能在表头插入结点的函数; 3.编写一个能遍历链表并输出链表各结点数据元素的函数;
相关知识
本关使用的链表结点结构定义为:
struct node
{
int data ; //存放结点的数据元素
struct node *next ; //指向下一个结点的指针,尾结点该域值为NULL
};
开始你的任务吧,祝你成功!
测试
输出:
5
3
1
2
4
6
代码
功能函数
//第二关代码
void myinsertHead(struct node * head, int insData )
{
/*在此处完成任务,实现在head为表头的链表的头插数据元素insData的功能*/
//begin
struct node* list = (struct node*)malloc(sizeof(struct node));
list->next = NULL;//存放新结点
list->data = insData;
list->next = head->next;
head->next = list;
//end
}
void myinsertTail(struct node * head , int insData )
{
/*在此处完成任务,在head为表头的单链表表尾插入数据元素insData*/
//begin
struct node* list = (struct node*)malloc(sizeof(struct node));
list->next = NULL;//存放新结点
struct node* p = (struct node*)malloc(sizeof(struct node));
p->next = NULL;//指向链表当前结点
p = head;
list->data = insData;//给指针赋值
while(p->next){//找到尾部结点
p = p->next;
}
p->next = list;
//end
}
void myprintList(struct node *L)
{
/*在此处完成任务,输出head为表头链表中的数据,每输出一个数据换一行*/
//begin
struct node* p = L->next;
while(p){
printf("%d\n", p->data);
p = p->next;
}
//end
}
主函数
int main(void)
{
struct node *L = mycreateList();
int a[]={1,2,3,4,5,6};
for(int i=0;i<6;i++)
if(i%2) myinsertTail(L,a[i]);
else myinsertHead(L,a[i]);
myprintList(L);
}
第3关:链表逆置
题目
任务描述
本关任务:完成算法,能实现将链表中的数据元素逆置。
问题描述:有一链表里面存放的是某公司销售人员的月销售数量,目前链表中存放的销售数量是按从小到大排序的,请编写一个算法,将销售数量从大到小排序。 结点类型定义如下:
typedef struct node
{
int saleAmount ;//销售数量
struct node *next;//指向下一产品的指针
}NODE ;
typedef struct node *pNode ;
开始你的任务吧,祝你成功!
测试
输入:
5 4 12 51 82 132
输出:
132 82 51 12 4
输入:
6 5 11 151 192 212 500
输出:
500 212 192 151 11 5
代码
功能函数
//第三关代码
void reverseList_link(struct node *L)
{
//请在此处填入代码,实现链表逆置功能
//begin
struct node* list =(struct node*)malloc(sizeof(struct node));
list->next = NULL;//指向头结点
struct node* p =(struct node*)malloc(sizeof(struct node));
p->next = NULL;//指向当前链表结点
struct node* tList =(struct node*)malloc(sizeof(struct node));
tList->next = NULL;//暂时的链表结点
list = L;
p = L->next;
L->next = NULL;//头结点置空
while(p){
tList = p;
p = p->next;//先把指向当前链表的指针指向下一个元素(关键)
//头结点插入元素
tList->next = L->next;
L->next = tList;
}
//end
}
主函数
int main(void)
{
struct node *pllist = mycreateList() ;
int num ;
int data;
scanf("%d",&num);
for(int i = 0;i < num; i++)
{
scanf("%d",&data);
myinsertTail(pllist, data);
}
reverseList_link(pllist);
myprintList(pllist);
}
第4关:查找和交换
题目
任务描述
本关任务:查找符合条件的结点,并将该结点的值与前驱结点的值交换。
开始你的任务吧,祝你成功!
测试
输入:5 -12 34 23 6 7 34
输出:-12
代码
功能函数
//第四关代码
int locateAndChange( struct node *L, int data)
{
//请在此处填入代码,在头结点为L的链表中查找 与data值相等的第一个结点,若能找到该结点,则将该结点的值与前驱结点的值交换
//若未找到与data值相等的结点,则返回值为-1,若找到的结点无前驱结点,则返回值为0,否则返回值为前驱结点的值
//begin
struct node* p =(struct node*)malloc(sizeof(struct node));
p->next = NULL;//指向当前链表结点
p = L;
//情况一:与data相等的结点的前驱节点是头结点
if(p->next->data == data){
return 0;
}
//情况二:找到该节点,与其前驱节点的值交换,输出前驱节点的值
struct node* list =(struct node*)malloc(sizeof(struct node));
list->next = NULL;//存放当前判断的结点
struct node* t =(struct node*)malloc(sizeof(struct node));
t->next = NULL;//存放当前判断的前驱结点
p = p->next;
while(p->next){
if(p->next->data == data){
int temp;
list = p->next;
t = p;
//交换两个结点的值
temp = t->data;
t->data = list->data;
list->data = temp;
return list->data; //输出交换后的当前结点的值(前驱节点的值)
}
p = p->next;
}
return -1;
//end
}
主函数
int main(void)
{
struct node *pllist = mycreateList() ;
int num ;
int data;
int pos ;
scanf("%d",&num);
for(int i = 0;i < num; i++)
{
scanf("%d",&data);
myinsertTail(pllist, data);
}
scanf("%d",&data);
printf("%d",locateAndChange(pllist,data));
}
第5关:链表销毁
题目
任务描述
链表的结点所占空间是动态分配的堆空间,程序员应在退出程序时释放动态分配的空间。
本关任务: 完成destroyLinklist函数,实现链表结点空间的回收
开始你的任务吧,祝你成功!
测试
输入:5 1 2 3 4 5
输出:6
输入:1 1
输出:2
代码
功能函数
//第五关代码
int destroyList(struct node *L)
{
//请在此处填写代码,实现将链表L的结点空间回收
//返回值为回收结点的个数,含头结点在内
struct node* p =(struct node*)malloc(sizeof(struct node));
p->next = NULL;//循环
struct node* list =(struct node*)malloc(sizeof(struct node));
list->next = NULL;//暂存
int n = 1;//个数
p = L->next;
while(p){
list = p;
free(list);
p = p->next;
n++;
}
free(L);
return n;
}
主函数
int main(void)
{
struct node *pllist = mycreateList() ;
int num ;
int data;
int pos ;
scanf("%d",&num);
for(int i = 0;i < num; i++)
{
scanf("%d",&data);
myinsertHead(pllist, data);
}
printf("%d",destroyList(pllist));
}