实验二:
经验总结与心得:今天完成了对数据结构实验二代码的完整书写,昨天晚上被两个基本问题困扰了很长时间:1.在InsertList_LA()函数中少写了一个j++,从而导致此函数无法执行它的功能。2.在DeleteList_LA()中参数e应该有取地址符号,因为在函数中改变了e值后,在主函数中还要运用e的值,因此必须加地址符才能改变主函数中的e的值。
实验目的
(1)掌握单链表的创建,插入、删除、查找和输出算法;
(2)运用线性表解决线性结构问题。
-
实验内容
基本要求:
创建一个带头结点的单链表、并完成插入、删除、查找和输出操作。
选作内容:
两个线性表合并算法的实现。已知顺序表LA和LB中的数据元素按值非递减有序排列,现要将LA和LB归并为一个新的顺序表LC,且LC中的数据元素仍按值非递减有序排序。例如:LA=(3,5,8,11) LB=(2,6,9,15,20)。 - 代码内容:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define OK 1
#define ERROR 0
typedef int Status;
typedef float ElemType;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
LinkList CreatList_LA(LinkList &LA,int n){ //可以返回结点 也可以返回Status (return OK)
int i;
LinkList p;
LA=(LinkList)malloc(sizeof(LNode));
LA->next=NULL;
for(i=n;i>0;--i)
{
p=(LinkList)malloc(sizeof(LNode));
scanf("%f",&p->data);
p->next=LA->next;
LA->next=p;
}
return LA;
}//创建链表LA 并将输入数据赋给每个结点的数据域
Status CreatList_LB(LinkList &LB,int n){//创建链表LB 并将输入数据赋给每个结点的数据域
int i;
LinkList p;
LB=(LinkList)malloc(sizeof(LNode));
LB->next=NULL;
for(i=n;i>0;--i)
{
p=(LinkList)malloc(sizeof(LNode));
scanf("%f",&p->data);
p->next=LB->next;
LB->next=p;
}
return OK;
}
Status CreatList_LC(LinkList &LC){//创建链表LC
int i;
LinkList p;
LC=(LinkList)malloc(sizeof(LNode));
LC->next=NULL;
return OK;
}
Status InsertList_LA(LinkList &LA,int i,ElemType e){//在第i个位置插入数据域为e的结点s
LinkList p,s;
Status j;
p=LA;j=0;
while(p&&j<i-1){
p=p->next;j++; //j++注意要写 否则执行结果(没有插入成功)总是错误
}
if(!p||j>i-1) return ERROR;
s=(LinkList)malloc(sizeof(LNode));
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
Status DeleteList_LA(LinkList &LA,int i,ElemType &e){//e要传地址,才能改变main函数里的值
Status j;
LinkList p,q;
p=LA;j=0;
while(p->next&&j<i-1)
{
p=p->next;j++;
}
if(!(p->next)||j>i-1) return ERROR;
q=p->next;
p->next=q->next;
e=q->data;
free(q);
return OK;
}//删除链表中的第i个结点,将所删除的数据赋值给e
Status GetElem_LA(LinkList &LA,int i,ElemType &e){//获得指定位置的元素值
LinkList p;
Status j;
p=LA->next;j=1;
while(p&&j<i){
p=p->next;j++;
}
if(!p||j>i) return ERROR;
e=p->data;
return OK;
}
Status LocateElem_LA(LinkList &LA,ElemType &e,Status &n){//查找链表中指定的元素位置
int j=1; //注意初始化赋值
LinkList p;
p=LA->next;
while(p->data!=e)
{p=p->next;j++;}
if(!p||j>n) return ERROR;
return j;
}
void PrintList_L(LinkList &L){ //输出链表数据
LinkList p;
p=L->next;
while(p)
{
printf("%.2f\t",p->data);
p=p->next;
}
}
void MergeList_L(LinkList &LA,LinkList &LB,LinkList &LC){//将LA和LB合并成LC
LinkList pa,pb,pc;
pa=LA->next;pb=LB->next;
LC=pc=LA;
while(pa&&pb)
{
if(pa->data<pb->data){
pc->next=pa;
pc=pa;
pa=pa->next;
}
else
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
while(pa!=NULL)
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
while(pb!=NULL)
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
pc->next=NULL;//注意这里pc的next域必须赋值NULL
free(LB);
}
int main(){
ElemType e,m;
LinkList LA,LB,LC;
Status i,n,a,b,c;
printf("请输入向所创建LA链表中插入几个结点:n为");
scanf("%d",&n);
printf("按非递增输入结点的数据:");
CreatList_LA(LA,n);
printf("请输入向所创建LB链表中插入几个结点:n为");
scanf("%d",&n);
printf("按非递增输入结点的数据:");
b=CreatList_LB(LB,n);
c=CreatList_LC(LC);
printf("输出链表LA为:");
PrintList_L(LA);
printf("\n输出链表LB为:");
PrintList_L(LB);
printf("\n请输入在链表第几个位置插入结点,i,e为:");
scanf("%d%f",&i,&e);
a=InsertList_LA(LA,i,e);
printf("\n插入后的链表LA为");
PrintList_L(LA);
printf("\n请输入在链表第几个位置删除结点,i为:");
scanf("%d",&i);
a=DeleteList_LA(LA,i,m);
printf("\n删除后的链表LA为");
PrintList_L(LA);
printf("\n删除的第%d个结点所存数据为:%f",i,m);
printf("\n想找第几个结点的元素,i为:");
scanf("%d",&i);
a=GetElem_LA(LA,i,e);
printf("\n第%d个结点所存数据为:%f",i,e);
printf("\n输入你想查找的值e:");
scanf("%f",&e);
a=LocateElem_LA(LA,e,n);
if(a==0) printf("没能查找到所需要查找的值。");
else printf("所查找的值e=%f在LA链表的第%d个结点位置。",e,a);
printf("\n将链表LA与LB合并成LC后,LC链表为:");
MergeList_L(LA,LB,LC);
PrintList_L(LC);
return OK;
}