单链表操作验证 验证型.docx

上传人:b****5 文档编号:6370576 上传时间:2023-01-05 格式:DOCX 页数:15 大小:39.74KB
下载 相关 举报
单链表操作验证 验证型.docx_第1页
第1页 / 共15页
单链表操作验证 验证型.docx_第2页
第2页 / 共15页
单链表操作验证 验证型.docx_第3页
第3页 / 共15页
单链表操作验证 验证型.docx_第4页
第4页 / 共15页
单链表操作验证 验证型.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

单链表操作验证 验证型.docx

《单链表操作验证 验证型.docx》由会员分享,可在线阅读,更多相关《单链表操作验证 验证型.docx(15页珍藏版)》请在冰豆网上搜索。

单链表操作验证 验证型.docx

单链表操作验证验证型

 

实验报告

 

课程名称数据结构

实验名称单链表实验验证

实验类型验证型

实验地点计405机房实验日期2017.4.28

指导教师魏海平

 

专业软件工程

班级软件1601

学号1611030102

姓名寇春雷

 

辽宁石油化工大学计算机与通信工程学院

数据结构实验报告评分表

项目

要求

分数

有无项目(√)

得分

预习报告

(30分)

实验目的明确

5

实验内容理解透彻

5

实验方案设计完整合理

程序总体框架设计完整

10

完成相关辅助代码

5

测试方案合理

5

实验过程

(30分)

发现问题

5

问题的分析

15

问题的解决方法

10

实验报告

(20分)

内容翔实无缺漏

5

如实记录实验过程

10

撰写规整

5

实验总结

(10分)

实验结果的分析

5

按照结果对原实验方案的改进意见

5

实验体会

(10分)

实验的收获

5

实验内容的发散考虑

5

总分

一.问题描述:

1.实验题目

单链表操作验证。

2.实验目的

(1)掌握线性表的链接存储结构。

(2)验证单链表及其基本操作的实现。

(3)进一步掌握数据结构及算法的程序实现的基本方法。

3.实验内容的理解

(1)用头插法(或尾插法)建立带头结点的单链表。

(2)对已建立的单链表实现按给定值和按序号对单链表进行插人、删除、查找和置逆等基本操作。

(3)对单链表进行初始化,建立带头节点的单链表,将单链表按其值非递归排序等操作。

4.实验要求

(1)采用标准C语言实现。

(2)对单链表操作前和操作后都要输出链表的内容。

(3)对要进行的操作有必要的提示信息。

(4)对实现的功能采用菜单的形式进行展示和选择。

二.设计

1.数据结构设计和核心算法设计描述。

2.主控及功能模块层次结构。

3.主要功能模块。

(1)主程序模块:

void main(){

初始化;

正序、逆序输出链表;

合并链表;

}

  

(2)集合单元模块——实现集合的抽象数据类型;

(3)单链表单元模块——实现单链表的抽象数据类型;

   (4)结点结构单元模块——定义链表的结点结构;

4.功能模块之间的调用与被调用关系:

             主程序模块

           

            集合单元模块

          

          单链表单元模块

           

          结点结构单元模块

 

三.测试

(1)程序运行截图

(2)程序源码

#include"stdafx.h"

/*第一部包括必要的头函数并定义状态值*/

#include

#include

#include/*malloc()等*/

#include/*INT_MAX等*/

#include/*EOF(=^Z或F6),NULL*/NULLscanf();printf();

#include

#include/*eof()*/

#include

#include/*exit()*/

/*函数结果状态代码*/

#defineTRUE1

#defineFALSE0

#defineOK1

#defineERROR0

#defineINFEASIBLE-1

/*#defineOVERFLOW-2因为在math.h中已定义OVERFLOW的值为3,故去掉此行*/

typedefintStatus;/*Status是函数的类型,其值是函数结果状态代码,如OK等*/

typedefintBoolean;/*Boolean是布尔类型,其值是TRUE或FALSE*/

typedefintElemType;

/*第二部定义线性表的单链表存储结构*/

typedefstructLNode

{

ElemTypedata;

structLNode*next;

}LNode;

typedefstructLNode*LinkList;/*另一种定义LinkList的方法*/

/*第三部带有头结点的单链表(存储结构如上定义)的基本操作(12个)*/

voidInitList(LinkListL)

{/*操作结果:

构造一个空的线性表L*/

L=(LinkList)malloc(sizeof(LNode));/*产生头结点,并使L指向此头结点*/

if(!

L)/*存储分配失败*/

exit(OVERFLOW);

L->next=NULL;/*指针域为空*/

}

voidDestroyList(LinkListL)

{/*初始条件:

线性表L已存在。

操作结果:

销毁线性表L*/

LinkListq;

while(L)

{

q=L->next;

free(L);

L=q;

}

}

voidClearList(LinkListL)/*不改变L*/

{/*初始条件:

线性表L已存在。

操作结果:

将L重置为空表*/

LinkListp,q;

p=L->next;/*p指向第一个结点*/

while(p)/*没到表尾*/

{

q=p->next;

free(p);

p=q;

}

L->next=NULL;/*头结点指针域为空*/

}

StatusListEmpty(LinkListL)

{/*初始条件:

线性表L已存在。

操作结果:

若L为空表,则返回TRUE,否则返回FALSE*/

if(L->next)/*非空*/

returnFALSE;

else

returnTRUE;

}

intListLength(LinkListL)

{/*初始条件:

线性表L已存在。

操作结果:

返回L中数据元素个数*/

inti=0;

LinkListp=L->next;/*p指向第一个结点*/

while(p)/*没到表尾*/

{

i++;

p=p->next;

}

returni;

}

StatusGetElem(LinkListL,inti,ElemType*e)/*算法2.8*/

{/*L为带头结点的单链表的头指针。

当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR*/

intj=1;/*j为计数器*/

LinkListp=L->next;/*p指向第一个结点*/

while(p&&j

{

p=p->next;

j++;

}

if(!

p||j>i)/*第i个元素不存在*/

returnERROR;

*e=p->data;/*取第i个元素*/

returnOK;

}

intLocateElem(LinkListL,ElemTypee,Status(*compare)(ElemType,ElemType)){/*初始条件:

线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0)*/

/*操作结果:

返回L中第1个与e满足关系compare()的数据元素的位序*/

/*若这样的数据元素不存在,则返回值为0*/

inti=1;

LinkListp=L->next;

while(p)

{

i++;

if(compare(p->data,e))/*找到这样的数据元素*/

returni;

p=p->next;

}

return0;

}

StatusPriorElem(LinkListL,ElemTypecur_e,ElemType*pre_e)

{/*初始条件:

线性表L已存在*/

/*操作结果:

若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,*/

/*返回OK;否则操作失败,pre_e无定义,返回INFEASIBLE*/

LinkListq,p=L->next;/*p指向第一个结点*/

while(p->next)/*p所指结点有后继*/

{

q=p->next;/*q为p的后继*/

if(q->data==cur_e){

*pre_e=p->data;

returnOK;

}

p=q;/*p向后移*/

}

returnINFEASIBLE;

}

StatusNextElem(LinkListL,ElemTypecur_e,ElemType*next_e)

{/*初始条件:

线性表L已存在*/

/*操作结果:

若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后*/

/*返回OK;否则操作失败,next_e无定义,返回INFEASIBLE*/

LinkListp=L->next;/*p指向第一个结点*/

while(p->next)/*p所指结点有后继*/

{

if(p->data==cur_e){

*next_e=p->next->data;

returnOK;

}

p=p->next;

}

returnINFEASIBLE;

}

StatusListInsert(LinkListL,inti,ElemTypee)/*算法2.9。

不改变L*/

{/*在带头结点的单链线性表L中第i个位置之前插入元素e*/

intj=0;

LinkListp=L,s;

while(p&&j

{

p=p->next;

j++;

}

if(!

p||j>i-1)/*i小于1或者大于表长*/

returnERROR;

s=(LinkList)malloc(sizeof(structLNode));/*生成新结点*/

s->data=e;/*插入L中*/

s->next=p->next;

p->next=s;

returnOK;

}

StatusListDelete(LinkListL,inti,ElemType*e)/*算法2.10。

不改变L*/

{/*在带头结点的单链线性表L中,删除第i个元素,并由e返回其值*/

intj=0;

LinkListp=L,q;

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;

}

voidListTraverse(LinkListL,void(*vi)(ElemType))

/*vi的形参类型为ElemType*/

{/*初始条件:

线性表L已存在。

操作结果:

依次对L的每个数据元素调用函数vi()*/

LinkListp=L->next;

while(p){

vi(p->data);

p=p->next;

}

printf("\n");

}

/*第四部定义了几个常用函数equal()、comp()、print()、print2()和print1()函数*/

Statusequal(ElemTypec1,ElemTypec2){/*判断是否相等的函数*/

if(c1==c2)returnTRUE;

elsereturnFALSE;

}

intcomp(ElemTypea,ElemTypeb){/*根据a<、=或>b,分别返回-1、0或1*/

if(a==b)return0;

elsereturn(a-b)/abs(a-b);

}

voidprint(ElemTypec){

printf("%d",c);

}

voidprint2(ElemTypec){

printf("%c",c);

}

voidprint1(ElemType*c){

printf("%d",*c);

}

voidCreateList(LinkList*L,intn)/*算法2.11*/

{/*逆位序(插在表头)输入n个元素的值,建立带表头结构的单链线性表L*/

inti;

LinkListp;

*L=(LinkList)malloc(sizeof(structLNode));

(*L)->next=NULL;/*先建立一个带头结点的单链表*/

printf("请输入%d个数据\n",n);

for(i=n;i>0;--i){

p=(LinkList)malloc(sizeof(structLNode));/*生成新结点*/

Scanf_s("%d",&p->data);/*输入元素值*/

p->next=(*L)->next;/*插入到表头*/

(*L)->next=p;

}

}

voidCreateList2(LinkList*L,intn)

{/*正位序(插在表尾)输入n个元素的值,建立带表头结构的单链线性表L*/

inti;

LinkListp,q;

*L=(LinkList)malloc(sizeof(structLNode));/*生成头结点*/

(*L)->next=NULL;

q=*L;

printf("请输入%d个数据\n",n);

for(i=1;i<=n;i++){

p=(LinkList)malloc(sizeof(structLNode));

Scanf_s("%d",&p->data);

q->next=p;

q=q->next;

}

p->next=NULL;

}

voidMergeList(LinkListLa,LinkList*Lb,LinkList*Lc)/*算法2.12*/

{/*已知单链线性表La和Lb的元素按值非递减排列。

*/

/*归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列*/

LinkListpa=La->next,pb=(*Lb)->next,pc;

*Lc=pc=La;/*用La的头结点作为Lc的头结点*/

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);/*释放Lb的头结点*/

Lb=NULL;

}

voidmain()

{

intn=5;

LinkListLa,Lb,Lc;

printf("按非递减顺序(正位序建立单链表括");

CreateList2(&La,n);/*正位序输入n个元素的值*/

printf("La=");/*输出链表的内容*/

ListTraverse(La,print);

printf("按非递增顺序(逆位序建立单链表");

CreateList(&Lb,n);/*逆位序输入n个元素的值*/

printf("Lb=");/*输出链表的内容*/

ListTraverse(Lb,print);

MergeList(La,&Lb,&Lc);/*按非递减顺序归并La和Lb,得到新表Lc*/

printf("Lc=");/*输出链表括Lc的容*/

printf("La和Lb非递减顺序为Lc:

\n");

ListTraverse(Lc,print);

printf("Lc单链表的长度为:

");

printf("%d\n",ListLength(Lc));

printf("在Lc单链表的第i个位置前插入元素e:

\n请输入元素e=");

inte;

scanf("%d",&e);

printf("请输入位置i=");

inti;

scanf("%d",&i);

ListInsert(Lc,i,e);

printf("Lc=");

ListTraverse(Lc,print);

printf("将Lc置为空表\n");

ClearList(Lc);

printf("Lc=");

ListTraverse(Lc,print);

}

(3)实验过程发现的问题

①.在voidCreateList2(LinkList*L,intn)函数中Scanf("%d",&p->data);输入方式不安全

②.在voidCreateList(LinkList*L,intn)函数中Scanf_s("%d",&p->data);输入方式不安全

③.在intLocateElem(LinkListL,ElemTypee,Status(*compare)(ElemType,ElemType))函数中

i=0;LinkListp=L->next;逻辑错误

(4)问题分析及解决方案

①.在voidCreateList2(LinkList*L,intn)函数中改为

Scanf_s("%d",&p->data);

②.在voidCreateList(LinkList*L,intn)函数中改为

Scanf_s("%d",&p->data);

③.在intLocateElem(LinkListL,ElemTypee,Status(*compare)(ElemType,ElemType))函数中

将i=0;改为i=1;或将LinkListp=L->next;改为LinkListp=L->next->next;

p指向第一节点。

四.实验结果分析

除了scanf();函数出错外,intLocateElem(LinkListL,ElemTypee,Status(*compare)(ElemType,ElemType))函数中有逻辑错误,其他函数测试正常。

五.作业小结

(1)StatusListInsert(LinkListL,inti,ElemTypee)中

①.插入新数据只该元素的地址

②.转移原指针

③.拼接新指针

(2)在StatusGetElem(LinkListL,inti,Elemtype*e)中

P=L->next;j=1;while();查找元素时,如果第i个元素不存在,则返回ERROR

(3)在voidCreateList(LinkList*L,intn)中

P->next=L->next;L->next=p;

①转移指针。

②连接指针。

(4)在MergeList(LinkListLa,LinkList*Lb,LinkList*Lc)中

La,Lb为非空表时,pa和pb分别指向表中的第一个结点。

第一个循环条件是Pa,pb都不为空。

六.对原方案的改进意见

intLocateElem(LinkListL,ElemTypee,Status(*compare)(ElemType,ElemType)){若这样的数据元素不存在,则返回值为0*/

inti=1;

LinkListp=L->next;

while(p)

{

i++;

if(compare(p->data,e))/*找到这样的数据元素*/

returni;

p=p->next;

}

return0;

}

或者i=0;LinkListp=L->next->next;

七.实验收获

(1)通过此实验我对单链表进行初始化,建立带头节点的单链表,将单链表按其值非递归排序等操作有了进一步的了解。

(2)再进行插入,删除等操作时,单链表由于顺序表。

(3)对验证实验有了进一步的了解。

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1