1.实验目的
了解线性表的链式存储存储结构和顺序存取特性,熟练掌握线性表的链式存储结构的C语言描述方法,熟练掌握动态链表的基本操作,查找、插入、定位等,能在实际应用中选择适当的链式结构。掌握用链表表示特定形式的数据的方法,并能编写出有关运算的算法。
2.实验内容
(1)已知线性表中的元素以递增有序排列,并以单链表作为存储结构,试写出一个高效算法,删除表中所有值大于mink且小于maxk的元素(若表中存在这样的元素)同时释放被删除结点的空间,并分析你的算法的时间复杂度。
(2)完成单链表上的如下操作:
<1>逆序建立单链表
<2>遍历单链表(输出单链表中每一个元素的位置)
<3>在单链表第5个元素前插入一个值为999的元素
<4>删除单链表的第5个元素
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OVERFLOW 0
#define OK 1
typedef int ElemType;
typedef int Status;
typedef struct LNode {
ElemType data;//数据域
struct LNode *next;//指针域
}LNode, *LinkList;
LinkList CreateList_L_Tail(int n)
{//尾插法建立单链表
LinkList L;
LNode *p, *r;
L = (LinkList)malloc(sizeof(LNode));//创建头结点
r = L;//r始终指向尾节点,开始时指向头结点
for (int i = n; i > 0; i--)
{//循环建立数据节点
p = (LinkList)malloc(sizeof(LNode));//生成新结点
scanf_s("%d", &p->data);//创建数据节点*p,输入元素的值
r->next = p;//将*p插入到*r之后
r = p;
}
r->next = NULL;
return L;
}
void PrintList(LinkList L)
{
LNode* p;
p = L->next;
while (p != NULL)
{
printf("%5d", p->data);
p = p->next;
}
printf("\n");
}
LinkList DeleteBetween(LinkList L, int mink, int maxk)
{//删除大于mink小于maxk的元素并释放空间
if (mink > maxk)//判断输入的边界值是否合法
{
printf("the llue is wrong");
exit(OVERFLOW);
}
LNode*p, *q;
q = L->next;
p = L;
while (q->data<= mink)
{//寻找要删除的结点所在下边界的位置
p = q;
q = p->next;
}
while (q&&q->data < maxk)
{//寻找要删除的结点所在的下边界的位置
p->next = p->next->next;
free(q);
q = p->next;
}
return L;
}
int main()
{
int n, mink, maxk;
LinkList L;
printf("输入要建立顺序链表的元素个数:");
scanf_s("%d", &n);
printf("输入顺序链表的元素(尾插法创建单链表):");
L = CreateList_L_Tail(n);
printf("顺序表中元素是:");
PrintList(L);
printf("输入上、下界(空格间隔开):");
scanf_s("%d%d", &mink, &maxk);
L=DeleteBetween(L, mink, maxk);
printf("删除后顺序表中元素是:");
PrintList(L);
system("pause");
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OVERFLOW 0
#define OK 1
typedef int ElemType;
typedef int Status;
typedef struct LNode {
ElemType data;//数据域
struct LNode *next;//指针域
}LNode, *LinkList;
LinkList CreateList_L(int n)
{//逆位序输入n个元素的值,建立带表头结点的单链线性表L
LNode *p;
LinkList L;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;//创建头结点,其数据域置为NULL
for (int i = n; i > 0; --i)
{
p = (LinkList)malloc(sizeof(LNode));//生成新结点
scanf_s("%d", &p->data);//输入元素的值
p->next = L->next;
L->next = p;//插入到表头
}
return L;
}
Status ListInsert_L(LinkList L, int i, ElemType e)
{//在带头结点的单链线性表L的第i个位置之前插入元素e
LNode *p, *s;//结构体变量p,s
int j;
p = L;
j = 0;
while (p&&j < i - 1)
{//寻找第i-1个结点
p = p->next;
++j;
}
if (!p || j > i - 1)return ERROR;//i小于1或者大于表长加1
s = (LinkList)malloc(sizeof(LNode));//生成新节点
s->data = e;
s->next = p->next;
p->next = s;//插入L中
return OK;
}
Status ListDelete_L(LinkList L, int i)
{//再带头结点的单链线性表L中,删除第i个元素
LNode *p, *q;
int j = 0;
p = L;
while (p->next&&j < i - 1)
{//寻找第i个结点,并另p指向其前驱
p = p->next;
++j;
}
if (!(p->next) || j > i - 1)return ERROR;//删除位置不合理
q = p->next;
p->next = q->next;//删除并释放结点
free(q);
return OK;
}
void PrintList(LinkList L)
{
LNode* p;
p = L->next;
while (p != NULL)
{
printf("%5d", p->data);
p = p->next;
}
printf("\n");
}
int main()
{
int n, i, j;
LinkList L;
ElemType e;
printf("输入要建立顺序链表的元素个数:");
scanf_s("%d", &n);
printf("输入顺序链表的元素(逆序创建单链表):");
L = CreateList_L(n);
printf("顺序表中元素是:");
PrintList(L);
printf("输入要插入的元素的位置:");
scanf_s("%d", &i);
printf("输入要插入的元素的值:");
scanf_s("%d", &e);
ListInsert_L(L, i, e);
printf("插入后的顺序链表是:");
PrintList(L);
printf("输入要删除的元素的位置:");
scanf_s("%d", &j);
ListDelete_L(L, j);
printf("删除后的顺序链表是:");
PrintList(L);
system("pause");
return 0;
}