采用顺序表单链表二种存储结构.docx
《采用顺序表单链表二种存储结构.docx》由会员分享,可在线阅读,更多相关《采用顺序表单链表二种存储结构.docx(14页珍藏版)》请在冰豆网上搜索。
采用顺序表单链表二种存储结构
南京信息工程大学数据结构实验(实习)报告
实验(实习)名称顺序表、单链表实验(实习)日期2015-10-11得分指导教师顾韵华系计软院专业计科年级2014级班次2姓名
一、实验目的
1、掌握采用顺序表、单链表二种存储结构实现线性表的归并运算。
二、实验内容
1、输入两个顺序表A和B的元素值(整数),元素递增有序,编写程序将A和B归并成一个按元素值递增有序的顺序表C。
分别输出顺序表A、B和C所有元素的值。
2、输入两个单链表A和B的元素值(整数),其表中元素递增有序,编写程序将A和B归并成一个按元素值递增有序的单链表C。
分别输出单链表A、B和C所有结点的值。
三、数据结构设计和实现
1、顺序表数据结构设计和实现
#include
#include
#include
#include
//常量定义
#defineLIST_INIT_SIZE100
#defineLISTINCREMENT10
#defineOK1
#defineERROR0
#defineOVERFLOW-2
#defineTrue1
#defineFalse0
//函数返回值类型定义
typedefintStatus;
//表节点数据类型定义
typedefintElemType;
//顺序表类型定义
typedefstruct{
ElemType*elem;
intlength;
intlistsize;
}SqList;
//顺序表各操作声明
StatusInitList_Sq(SqList&L);
StatusDetroyList_Sq(SqList&L);
StatusClearList_Sq(SqList&L);
intListEmpty_Sq(SqListL);
intListLength_Sq(SqListL);
StatusGetElem_Sq(SqListL,inti,ElemType&e);
StatusListInsert_Sq(SqList&L,inti,ElemTypee);
StatusListDelete_Sq(SqList&L,inti,ElemType&e);
voidPrintList_Sq(SqListL);
voidMergeList(SqListLa,SqListLb,SqList&Lc);
#include"link.h"
#include"iostream.h"
StatusInitList_Sq(SqList&L)
{
L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!
L.elem)exit(OVERFLOW);
L.length=0;
L.listsize=LIST_INIT_SIZE;
returnOK;
}
StatusDetroyList_Sq(SqList&L)
{if(L.elem)free(L.elem);
returnOK;
}
StatusClearList_Sq(SqList&L)
{if(L.elem)
{L.length=0;
L.listsize=0;
}
returnOK;
}
intListEmpty_Sq(SqListL)
{
return(L.length==0);
}
intListLength_Sq(SqListL)
{
cout<return0;
}
StatusGetElem_Sq(SqListL,inti,ElemType&e)
{
if(i<1||i>=L.length)
returnERROR;
e=L.elem[i-1];
returnOK;
}
StatusListInsert_Sq(SqList&L,inti,ElemTypee)
{
ElemType*newbase,*p,*q;
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;
}
StatusListDelete_Sq(SqList&L,inti,ElemType&e)
{
ElemType*p,*q;
if(i<1||i>L.length)
returnERROR;
p=&(L.elem[i-1]);
e=*p;
q=L.elem+L.length-1;
for(++p;p*(p-1)=*p;
L.length--;
returnOK;
}
voidPrintList_Sq(SqListL)
{
inti;
if(L.length==0)
cout<<"该表为空"<else
for(i=0;icout<}
#include"link.h"
#include"iostream.h"
voidMergeList(SqListLa,SqListLb,SqList&Lc)
{
int*pa;pa=La.elem;int*pb;pb=Lb.elem;
Lc.listsize=Lc.length=La.length+Lb.length;
int*pc;pc=Lc.elem=(ElemType*)malloc(Lc.listsize*sizeof(ElemType));
if(!
Lc.elem)exit(OVERFLOW);//存储分配失败
int*pa_last;pa_last=La.elem+La.length-1;
int*pb_last;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<=pa_last)*pc++=*pb++;
}//MergeList_L
intmain()
{
SqListL1,L2,L3;
ElemTypee;
inti;
InitList_Sq(L1);//构造空的单链表L1
InitList_Sq(L2);//构造空的单链表L2
printf("请输入表L1元素值,共5个\n");
for(i=0;i<5;i++)
{scanf("%d",&e);
ListInsert_Sq(L1,i+1,e);//向表中插入用户输入的元素值
}
printf("请输入表L2元素值,共3个\n");
for(i=0;i<3;i++)
{scanf("%d",&e);
ListInsert_Sq(L2,i+1,e);//向表中插入用户输入的元素值
}
//合并L1和L2
MergeList(L1,L2,L3);
//输出合并后表L3的各个元素值
printf("L1与L2合并后的表元素值为:
\n");
PrintList_Sq(L3);
printf("\n");
return0;
}
2、单链表数据结构设计和实现
typedefstructLNode
{
ElemTypedata;
structLNode*next;//next为指向LNode类型节点的指针
}LNode,*LinkList;//LNode为节点类型,LinkList为指向LNode类型节点的指针(即头指针)
单链表操作的函数原型包括:
StatusInitList(LinkList&L);//构造一个新的链表L
StatusDestroyList(LinkList&L);//销毁线性表L
StatusClearList(LinkList&L);//将线性表L重置为空表
intListEmpty(LinkListL);//判断L是否为空表
intListLength(LinkListL);//返回L中数据元素的个数
StatusGetElem(LinkListL,inti,ElemType&e);//用e返回L中第i个数据元素的值
intLocateElem(LinkListL,ElemTypee);//判断e是否存在于L中
StatusListInsert(LinkList&L,inti,ElemTypee);//在L中第i个位置之前插入数据元素e
StatusListDelete(LinkList&L,inti,ElemType&e);//删除L中第i个数据元素,并用e返回其值
voidPrintList(LinkListL);//输出顺序表中的数据元素
voidDeleteElem(LinkList&L,ElemTypee);//删除线性表中所有值为e的结点
voidMergeList(LinkList&La,LinkList&Lb,LinkList&Lc);//链表的二路归并
单链表各操作实现:
StatusInitList(LinkList&L)//构造一个新的有头节点的空链表L
{
L=(LinkList)malloc(sizeof(LNode));//生成新节点(此处为头节点)
L->next=NULL;//头节点的指针域指向NULL
if(!
L)returnERROR;
returnOK;
}//InitList
StatusDestroyList(LinkList&L)//销毁链表L
{
LinkListp,r;
p=L->next;r=p->next;
while(p!
=NULL)
{
free(p);
p=r;
r=p->next;
}
free(L);
returnOK;
}//DestroyList
StatusClearList(LinkList&L)//将链表L重置为空表
{
LinkListp,r;
p=L->next;r=p->next;
while(p!
=NULL)
{
free(p);
p=r;
r=p->next;
}
L->next=NULL;
returnOK;
}//ClearList
intListEmpty(LinkListL)//判断L是否为空表
{
return(L->next==NULL);
}//ListEmpty
intListLength(LinkListL)//返回L中元素结点个数
{
LinkListp;p=L;
inti=0;
while(p->next!
=NULL)
{
p=p->next;
i++;
}
returni;
}//ListLength
StatusGetElem(LinkListL,inti,ElemType&e)//用e返回L中第i个数据元素的值
{
LinkListp=L;
intj=0;
while(p!
=NULL&&j
{
p=p->next;
j++;
}
if(p==NULL||j>i-1)returnERROR;
e=p->data;
returnOK;
}//GetElem
intLocateElem(LinkListL,ElemTypee)//判断e是否存在于L中
{
LinkListp=L;
inti=0;
while(p->next!
=NULL)
{
p=p->next;
i++;
if(p->data==e)
returni;
}
return0;
}//LocateElem
StatusListInsert(LinkList&L,inti,ElemTypee)//在L中第i个位置之前插入数据元素e
{
LinkListp=L,s;
intj=0;
while(p!
=NULL&&j{
p=p->next;
j++;
}
if(p==NULL||j>i-1)returnERROR;
s=(LinkList)malloc(sizeof(LNode));
s->data=e;
s->next=p->next;
p->next=s;
returnOK;
}//ListInsert
StatusListDelete(LinkList&L,inti,ElemType&e)//删除L中第i个数据元素,并用e返回其值
{
LinkListp=L,q;
intj=0;
while(p->next!
=NULL&&j{
p=p->next;
j++;
}
if(p->next==NULL||j>i-1)returnERROR;
q=p->next;
p->next=q->next;
e=q->data;
free(q);
returnOK;
}//ListDelete
voidPrintList(LinkListL)
{
LinkListp=L->next;
while(p!
=NULL)
{
printf("%d",p->data);
p=p->next;
}
printf("\n");
}//PrintList
voidDeleteElem(LinkList&L,ElemTypee)//删除线性表中所有值为e的结点
{
LinkListp=L,q;
while(p->next!
=NULL)
{
q=p->next;
if(q->data==e)
{
p->next=q->next;
free(q);
}
else
p=p->next;
}
}//DeleteElem
voidMergeList(LinkList&La,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);
}//MergeList
四、程序调试
1、顺序表的实现:
采用多文件结构,创建程序的过程为:
(1)先创建一个工程
(2)再新建头文件
(3)最后写源程序
操作结果:
2、单链表的实现:
采用多文件结构,创建程序的过程为:
(1)先创建一个工程
(2)再新建头文件
(3)最后写源程序
操作结果:
调试过程中遇到的问题:
写顺序表的时候添加了排序的函数,多文件程序要注意头文件的添加。
五、实验总结
通过这次实验,我对算法有了更深入的理解,对每个算法的实现也更熟练了,也体会到了顺序表和单链表的区别。
我认识到熟悉一个程序的最好方法就是多使用多练习,还有就是调试程序一定要有耐心,要仔细,注意细节,比如符号。