一、实验目的
1.熟练掌握单向链表和单项循环链表基本操作的C语言实现。
2.掌握链表的应用,逐步培养解决实际问题的能力。
3.能够从时间和空间复杂度的角度综合比较线性表两种存储结构的不同特点及适用场景。
4.培养学生程序设计能力,要求编写的程序结构清楚和正确易读,符合软件工程的规范。
4.培养学生利用链表解决实际问题的能力。
二、实验题目
1.设计并验证以下算法:判定带头结点的单向链表L的数据元素是否为非递增有序。如果是非递增有序的,删除值相同的多余元素,并就地逆置删除后的链表L;如果不是非递增有序的,输出相应的提示信息。
2.设线性表L=(a1,a2,…,an-1,an)采用带头结点的单链表保存,设计并实现一个空间复杂度为O(1)且时间上尽可能高效的算法,重新排列L中的各结点,得到线性表L’=(a1,an,a2,an-1,a3,an-2,……)。
三、程序清单
1.
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR -1
typedef int Elemtype;
typedef int Status;
typedef struct Node{
Elemtype data;
struct Node *next;
}Node, *LinkList;
//尾插法创建链表(带头结点)
Status TailCreatList(LinkList &L,int n){
LinkList p,r;
int i;
L=(LinkList)malloc(sizeof(Node));
r=L;
L->next=NULL;
printf("请输入%d个需要放入的元素:",n);
for(i=0;i<n;i++){
p=(LinkList)malloc(sizeof(Node));
scanf("%d", &p->data);
r->next=p;
r=p;
}
p->next=NULL;
}
//头插法创建链表(带头结点)
//Status HeadCreatList(LinkList &L,int n){
// LinkList p,r;
// L=(LinkList)malloc(sizeof(Node));
// r=L;
// L->next=NULL;
// printf("请输入%d个需要放入的元素:",n);
// for(int i=0;i<n;i++){
// p=(LinkList)malloc(sizeof(Node));
// scanf("%d", &p->data);
// p->next=L->next;
// L->next=p;
// }
//}
//判断单向链表是否为非递增有序
Status CheckList(LinkList &L){
LinkList p;
p=L->next;
while(p->next!=NULL){
if(p->data<p->next->data){
return ERROR;
}
else{
p=p->next;
}
}
return OK;
}
//删除非递增有序链表中的相同元素
Status DeleteSame(LinkList &L){
LinkList p,r;
p=L->next;
while(p->next!=NULL){
r=p->next;
if(p->data==r->data){
p->next=r->next;
free(r);
}
else{
p=p->next;
}
}
}
//就地逆置单向链表
Status InverseList(LinkList &L){
LinkList p,q;
p=L->next;
L->next=NULL;
while(p){
q=p->next;
p->next=L->next;
L->next=p;
p=q;
}
}
int main(){
int n,i;
LinkList L,p;
printf("请输入需要创建链表的长度:");
scanf("%d", &n);
TailCreatList(L,n);
i=CheckList(L);
if(i==-1){
printf("您输入的不是非递增有序单向链表!");
}
else{
printf("您输入的非递增有序单向链表为:\n");
for(p=L->next;p!=NULL;p=p->next) {
printf("%d ",p->data);
}
DeleteSame(L);
printf("\n删除相同元素后的单向链表为:\n");
for(p=L->next;p!=NULL;p=p->next){
printf("%d ",p->data );
}
InverseList(L);
printf("\n就地逆置后的单向链表为:\n");
for(p=L->next;p!=NULL;p=p->next){
printf("%d ",p->data);
}
}
}
2.
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR -1
typedef int Elemtype;
typedef int Status;
typedef struct Node{
Elemtype data;
struct Node *next;
}Node, *LinkList;
//尾插法创建链表(带头结点)
Status TailCreatList(LinkList &L,int n){
LinkList p,r;
int i;
L=(LinkList)malloc(sizeof(Node));
r=L;
L->next=NULL;
printf("请输入%d个需要放入的元素:",n);
for(i=0;i<n;i++){
p=(LinkList)malloc(sizeof(Node));
scanf("%d", &p->data);
r->next=p;
r=p;
}
p->next=NULL;
}
Status ChangeList(LinkList &L){
LinkList p,q,s,r;
p=q=L;
//寻找链表的中点
while(p->next!=NULL){
p=p->next;
q=q->next;
if(p->next!=NULL){
p=p->next;
}
}
//中点之后的第一个元素
p=q->next;
q->next=NULL;
//将后半段的链表逆置
while(p!=NULL){
r=p->next;
p->next=q->next;
q->next=p;
p=r;
}
//将后半部分已逆置的链表插入前半部分中,指针q指向中点元素
s=L->next;
p=q->next;
q->next=NULL;
while(p!=NULL){
r=p->next;
p->next=s->next;
s->next=p;
s=p->next;
p=r;
}
}
int main(){
LinkList L,p;
int i,n;
printf("请输入需要创建链表的长度:");
scanf("%d",&n);
TailCreatList(L,n);
printf("您输入的链表为:\n");
for(p=L->next;p!=NULL;p=p->next){
printf("%d ", p->data);
}
ChangeList(L);
// printf("%d",q->data);
printf("\n改变后的链表为:\n");
for(p=L->next;p!=NULL;p=p->next){
printf("%d ", p->data);
}
}
四、实验结果
1.
2.