printf("%4d",L.elem[i]);
printf("\n");
returnOK;}
//取线性表的第i个元素,其结果保存在e中
StatusGetElem(sqlistl,inti,ElemType&e)
{
if(i<1||i>l.length+1)returnERROR;
e=l.elem[i-1];
returnOK;
}
//定义两个数据元素相等的比较函数
Statusequal(ElemTypee1,ElemTypee2)
{if(e1==e2)
returnOK;
else
returnERROR;
}
//根据compare()函数在线性表中定位元素e的位置
intLocateElem_sq(sqlistL,ElemTypee,Status(*compare)(ElemType,ElemType))//成功返回位序,否则返回0
{inti=1;
ElemType*p;
p=L.elem;
while(i<=L.length&&!
(*compare)(*p++,e))++i;
if(i<=L.length)returni;
elsereturn0;
}//locateElem_sq
//在线性表中求某元素的前趋结点,如存在则返回其前趋结点pre_e的值,否则返回出错信息
StatusPriorElem(sqlistL,ElemTypecur_e,ElemType&pre_e)
{intpos;
pos=LocateElem_sq(L,cur_e,equal);
if(pos==0)returnERROR;
elseif(pos==1)returnOVERFLOW;//overflow表示位于第一个
else{
GetElem(L,pos-1,pre_e);
returnOK;
}
}
//在线性表中求某元素的后继结点
StatusNextElem(sqlistL,ElemTypecur_e,ElemType&next_e)
{intpos;
pos=LocateElem_sq(L,cur_e,equal);
if(pos==0)returnERROR;
elseif(pos==L.length)returnOVERFLOW;//overflow表示最后一个
else{
GetElem(L,pos+1,next_e);
returnOK;
}
}
//在线性表中插入一个元素
StatusListinsert_sq(sqlist&L,inti,ElemTypee){
ElemType*p,*q,*newbase;
if(i<1||i>L.length+1)returnERROR;
if(L.length>=L.listsize){
newbase=(ElemType*)realloc(L.elem,(L.listsize+Listincrement)*sizeof(ElemType));
if(!
newbase)exit(OVERFLOW);
L.elem=newbase;L.listsize+=Listincrement;}
q=&(L.elem[i-1]);
for(p=&(L.elem[L.length-1]);p>=q;--p)*(p+1)=*p;
*q=e;++L.length;
returnOK;
}//listinsert_sq;
//在线性表中删除第i个元素,其结果保留在e中
StatusListdelete_sq(sqlist&l,inti,ElemType&e)
{
ElemType*p,*q;
if(i<1||i>l.length+1)returnERROR;
p=&(l.elem[i-1]);
e=*p;
q=l.elem+l.length-1;
for(++p;p<=q;++p)*(p-1)=*p;
--l.length;
returnOK;
}//listdelete_sq;
//将la和lb线性表归并到lc
voidmergelist_sq(sqlistla,sqlistlb,sqlist&lc)
{ElemType*pa,*pb,*pc,*pa_last,*pb_last;
pa=la.elem;
pb=lb.elem;
lc.listsize=lc.length=la.length+lb.length;
pc=lc.elem=(ElemType*)malloc(lc.listsize*sizeof(ElemType));
if(!
lc.elem)exit(OVERFLOW);
pa_last=la.elem+la.length-1;pb_last=lb.elem+lb.length-1;
while((pa<=pa_last)&&(pb<=pb_last))
if(*pa<=*pb)*pc++=*pa++;else*pc++=*pb++;
while(pa<=pa_last)*pc++=*pa++;
while(pb<=pb_last)*pc++=*pb++;
}//mergelist_sq;
//对线性表的元素进行排序
Statussortsqlist(sqlist&L)
{//冒泡排序
inti,j,len;
ElemTypet;
len=ListLength(L);
for(i=len-1;i>=1;i--)
for(j=0;j
{if(L.elem[j]>L.elem[j+1])
{t=L.elem[j];
L.elem[j]=L.elem[j+1];
L.elem[j+1]=t;
}
}
returnOK;
}
voidmain()
{sqlistla,lb,lc;
intn,m,i,e,k,cur_e,pre_e,next_e;
//建立线性表,并输入输出线性表的数据
InitList(la);InitList(lb);
printf("pleaseinputla'snumbers:
n(请输入线性表la的元素个数n)\n");
scanf("%d",&n);
printf("pleaseinputlannumbers:
(请输入线性表la的n个元素)\n");
sqlistinput(la,n);
sqlistoutput(la);
printf("\n");
//调用插入函数,对线性表进行插入操作
printf("请输入要插入的元素的位置和插入的值\n");
scanf("%d%d",&i,&e);
Listinsert_sq(la,i,e);
sqlistoutput(la);
//调用删除函数,对线性表进除删操作
printf("请输入要删除的元素的位置\n");
scanf("%d",&i);
Listdelete_sq(la,i,e);
printf("thedeledatais%d\n",e);
sqlistoutput(la);
printf("pleaseinputthegetdata'slocate\n");
scanf("%d",&i);
//调用GetElem()函数,取第I个位置的元素的值。
GetElem(la,i,e);
printf("thegetdatais%d\n",e);
printf("pleaseinputthelocateelem'sdata:
cur_e\n");
//调用LocateElem_sq()函数,求元素cur_e的位置。
scanf("%d",&cur_e);
k=LocateElem_sq(la,cur_e,equal);
printf("thelocateis%d\n",k);
//调用PriorElem()函数,求元素cur_e的前驱。
printf("pleaseinputthecur_edata\n");
scanf("%d",&cur_e);
PriorElem(la,cur_e,pre_e);
printf("thepre_eis%d\n",pre_e);
//调用NextElem()函数,求元素cur_e的后继。
printf("pleaseinputthecur_edata\n");
scanf("%d",&cur_e);
NextElem(la,cur_e,next_e);
printf("thenext_eis%d\n",next_e);
//建立两个线性表并排序然后归并
printf("pleaseinputlb'snumbers:
m\n");
scanf("%d",&m);
printf("pleaseinputlbmnumbers:
\n");
sqlistinput(lb,m);
printf("\n");
sqlistoutput(lb);
sortsqlist(la);
printf("thesortlistlais:
\n");
sqlistoutput(la);
sortsqlist(lb);
printf("thesortlistlbis:
\n");
sqlistoutput(lb);
mergelist_sq(la,lb,lc);
printf("laandlb'smergelistis:
\n");
sqlistoutput(lc);
}
四、思考题
1.如何实现顺序表的逆置
2.每次删除操作时,都会使得大量的数据元素移动,删除多个数据元素时,就需多次移动数据元素。
能否一次进行删除多个数据元素的操作,使得数据元素的移动只进行一次。
实验二:
单链表的基本操作
实验学时:
2
实验类型:
验证
实验要求:
必修
一、实验目的
1.定义单链表的结点类型。
2.熟悉对单链表的一些基本操作和具体的函数定义。
3.通过单链表的定义掌握线性表的链式存储结构的特点。
4.掌握循环链表和双链表的定义和构造方法
二、实验内容
链表的创建、插入与删除操作
三、程序清单
1、运行环境
装有Visualc++6.0的微机一台
2、程序清单
//链表的创建及插入、删除操作
#include"stdio.h"
#include"stdlib.h"
#defineNULL0
#defineerror0
#defineok1
#defineoverflow-2
#defineinfeasible-1
//类型定义
typedefintStatus;
typedefintElemType;
//定义链表的存储结构
typedefstructLNode
{intdata;//数据域
structLNode*next;//指针域
}LNode,*LinkList;//链表的类型
StatusGetElem_l(LinkListL,inti,ElemType&e)
//L为带头结点的单链表,当第i个元素存在时,其值赋给e.
{intj;
LinkListp;
p=L->next;j=1;
while(p&&j
{p=p->next;++j;}
if(!
p||j>i)returnerror;
e=p->data;
returnok;
}
//逆序创建链表
voidCreatList_L1(LinkList&L,intn)//n为元素个数,L为头结点
{inti;
LinkListp;
L=(LinkList)malloc(sizeof(LNode));//生成头结点
L->next=NULL;
for(i=n;i>0;i--)//链头插入法
{p=(LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);
p->next=L->next;
L->next=p;
}
}
//正序创建单链表
voidCreatList_L2(LinkList&L,intn)///n为元素个数,L为头结点
{inti;
LinkListp,q;
L=(LinkList)malloc(sizeof(LNode));
q=L;
for(i=0;i{p=(LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);
q->next=p;
q=p;
}
q->next=NULL;
}
//输出链表
voidprint(LinkListL)
{LinkListp;
p=L->next;
while(p)
{printf("%d",p->data);
p=p->next;
}
}
//链表的插入操作
intListInsert(LinkList&L,inti,inte)
{LinkListp,s;
intj;
p=L;j=0;
while(p&&j{p=p->next;++j;}
if(!
p||j>i-1)returnerror;
s=(LinkList)malloc(sizeof(LNode));
s->data=e;s->next=p->next;
p->next=s;
returnok;
}
//链表的删除操作
intListDelete(LinkList&L,inti,int&e)
{LinkListp,q;
intj;
p=L;j=0;
while(p->next&&j{p=p->next;++j;}
if(!
(p->next)||j>i-1)returnerror;
q=p->next;p->next=q->next;
e=q->data;free(q);
returnok;
}
//对链表的元素进行排序
Statussortlinklist(LinkList&L)
{LinkListp,q,r;
ElemTypet;
p=L->next;//p指向链表第一个元素结点
while(p->next!
=NULL)
{q=L->next;//q指向链表第一个元素结点
while(q->next!
=NULL)
{r=q->next;
if(q->data>r->data)//相邻两个元素比较、交换
{t=q->data;q->data=r->data;r->data=t;}
q=q->next;
}
p=p->next;
}
returnok;
}
voidmergelist_l(LinkListla,LinkList&lb,LinkList&lc)
{LinkListpa,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;}
pc->next=pa?
pa:
pb;
free(lb);
}
//主函数通过调用创建、插入、删除用输出函数完成链表的基本操作
voidmain()
{LinkListL1,L2,L3;
intn,ins,del,i;
//创建一个先进先出单链表
printf("pleaseinputfifolinklist'snodenumbern:
\n");
scanf("%d",&n);
printf("pleaseinputthelinklist%dnodesdata\n",n);
CreatList_L2(L2,n);
print(L2);
printf("\n");
//创建一个后进先出单链表
printf("pleaseinputlifolinklist'snodenumbern:
\n");
scanf("%d",&n);
printf("pleaseinputthelinklist%dnodesdata\n",n);
CreatList_L1(L1,n);
print(L1);
printf("\n");
//对链表进行插入操作
printf("pleaseinputtheinsertnode'slocateiandvaluee\n");
scanf("%d%d",&i,&ins);
ListInsert(L1,i,ins);
print(L1);
printf("\n");
//对链表进行删除操作
printf("pleaseinputthedeletenode'slocatei\n");
scanf("%d",&i);
ListDelete(L1,i,del);
print(L1);
printf("\n%d\n",del);
//对链表进行排序
sortlinklist(L1);
printf("\ntheL1list'ssortis:
\n");
print(L1);
printf("\ntheL2list'ssortis:
\n");