链表的基本操作
任务一:单链表的生成和输出
任务描述:
从键盘输入数据,创建一个初始链表。通过调用定义的基本操作函数来实现单链表上的插入、删除元素等操作。调试程序并对相应的输出作出分析;修改输入数据,预期输出并验证输出的结果。加深对有关算法的理解。
相关知识:
为了完成本关任务,你需要掌握:
1.尾插法建立单链表
2.单链表的遍历(输出)
- 尾插法建立单链表
本关任务:尾插法是通过将新结点逐个插入到链表的尾部来创建链表。同前插法一样,每次申请一个新结点,读入相应的数据元素值。不同的是,为了使新结点能够插入到表尾,需要增加一个尾指针。(可参考教材22页,关于使用的教材:高等教育出版社唐策善、李龙澍、黄刘生编著的《数据结构——用C语言描述》)
注意:建立的单链表的数据域要求为整型(这一点跟书上不同),因此可设定
从键盘输入整型数据,当输入-1时表示输入结束。
用scanf语句代替getchar语句即可。
- 遍历单链表
设置一个扫描指针,从开始结点起,只要这个结点不为空,就依次输出结点的数据域。通过p=p->next往下扫描。
测试说明:
测试输入:1 3 5 7 9 10 -1
预期输出:1 3 5 7 9
- 示例代码如下:(温馨提示:本文全部代码只在 EduCoder 平台上通过测试,仅供参考,如有运行错误请自行改正)
#include "stdio.h"
#include "malloc.h" /*包含动态分配内存函数*/
#define TRUE 1
#define FALSE 0
typedef int elemtype;
typedef struct node /*链表结点类型定义*/
{
elemtype data; /*结点数据域*/
struct node *next; /*结点的指针域*/
}linklist;
/*请在下面补充代码,实现尾插法建立单链表函数*/
linklist *creatlist()
{
int a;
linklist *head,*s,*r;
head=(linklist*)malloc(sizeof(linklist));
r=head;
scanf("%d",&a);
while(a!=-1)
{
s=(linklist*)malloc(sizeof(linklist));
s->data=a;
r->next=s;
r=s;
scanf("%d",&a);
}
r->next=NULL;
return head;
}
/*请在下面补充代码,写出单链表遍历函数*/
void print(linklist *head) /*打印出链表head中各个结点的值*/
{
linklist *p;
p=head->next;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
int main() /*主函数*/
{
linklist *head; /*定义指向链表的指针head*/
head=creatlist();
print(head);
return 0;
}
任务二:单链表的插入操作
任务描述:
本关任务:在单链表的第i个位置插入一个元素x
相关知识:
为了完成本关任务,你需要掌握:
1.后插法
2.通过位序查找元素
后插法:
后插法:在一个给定结点p后面插入一个元素结点s语句:
s->next=p->next p->next=s
特点:算法简单、时间效率高。算法时间复杂度O(1).
前插法因为要涉及到找给定结点p的前驱,因此时间复杂度O(n),一般不建议
插入算法要尽量转化为后插算法
因此本关中,需要查找的是第i-1个元素结点(想想为什么?)
给定位序进行查找:
1.在单链表中,即使知道被访问结点的序号i也不能像顺序表那样直接按序号访问,
只能从第一个扫描结点p出发顺着next域逐个结点往下搜索。
当扫描指针p指向某结点时判断是否为第i个结点,若是则查找成功;
否则,将扫描指针p后移。对每个结点依次执行上述操作,直到p是NULL时查找失败,返回-1.
2.本关中,需要设置一个计数器j,当扫描指针不为空时计数。循环条件为:
p!= NULL && j<i
3.函数返回的是结点的指针。查找失败时,返回空指针。
测试说明:
测试输入:1 5 23 45 7 9 12 -1
3 100
预期输出:
please input the linklist and end by -1:
1 5 23 45 7 9 12
start insert operation,please input insert position:
after insertion:
1 5 100 23 45 7 9 12
- 示例代码如下:(温馨提示:本文全部代码只在 EduCoder 平台上通过测试,仅供参考,如有运行错误请自行改正)
#include "stdio.h"
#include "malloc.h" /*包含动态分配内存函数*/
#define TRUE 1
#define FALSE 0
typedef int elemtype;
typedef struct node /*链表结点类型定义*/
{
elemtype data; /*结点数据域*/
struct node *next; /*结点的指针域*/
}linklist;
linklist *creatlist()
{
int x;
linklist *head,*r,*p;
p=(linklist*)malloc(sizeof(linklist));
head=p;
p->next=NULL;
r=p;
scanf("%d",&x);
while(x!=-1)
{
p=(linklist*)malloc(sizeof(linklist));
p->data=x;
p->next=NULL;
r->next=p;
r=r->next;
scanf("%d",&x);