数据结构实验报告1

南京信息工程大学实验(实习)报告

实验(实习)名称实验(实习)日期得分指导老师

系专业班级姓名学号

1、需求分析

陈述程序设计的任务,强调程序要解决的问题是什么?

实现单链表的各种基本运算,解决链表的的输出,输入,链表的长度,判断链表是否为空,在链表中输出某个元素,插入元素,删除元素,释放链表的问题。

明确规定:输入的形式和输入值的范围;输出的形式;程序所能达到的功能;测试数据。

1.输入链表结点个数

2输入结点的值

输出的形式:

1输出单链表h

2单链表h长度

3单链表h为"空":非空"

4单链表h的第3个元素

5元素a的位置

6输出删除h的第3个元素单链表

测试数据;

结点数:4

结点值:abcd

2、设计

设计思路:写出存储结构,主要算法的基本思想.

设计表示:每个操作及模块的伪码算法。列出每个过程或函数所调用和被调用的过程或

函数,也可以通过调用关系(层次)图表达。

实现注释:各项功能的实现程度、在完成基本要求的基础上还实现了什么功能。

存储结构

单链表采用一个结点存放一个数据元素,

每个结点除了包括存放数据元素值的数据域(data)外,还包括指向下一个元素的存储位置的指针域(next)。最后一个结点的指针域为空。

主要算法的基本思想:

1判断单链表是否为空,空表返回1,否则返回0

int ListEmpty(LinkList L)

{

return(L->next==NULL);

}

2单链表的长度

int ListLength(LinkList L)

{

LinkList p=L;

int i=0;

while (p->next!=NULL)

{

i++;

p=p->next;

}

return(i);

}

3获取单链表L中第i元素,由参数e返回

int GetElem(LinkList L,int i,ElemType &e)

{

int j=0;

LinkList p=L;

while (j

{

j++;

p=p->next;

}

if (p==NULL)

return 0;

else

{

e=p->data;

return 1;

}

}

4在单链表L中查找数据元素e的位置,如不存在返回0 int LocateElem(LinkList L,ElemType e)

{

LinkList p=L->next;

int n=1;

while (p!=NULL && p->data!=e)

{

p=p->next;

n++;

}

if (p==NULL) return(0);

else return(n);

}

5在单链表L中第i个位置上插入元素e

int ListInsert(LinkList &L,int i,ElemType e)

{

int j=0;

LinkList p=L,s;

while (j

{

j++;

p=p->next;

}

if (p==NULL) /*未找到第i-1个结点*/

return 0;

else /*找到第i-1个结点*p*/

{

s=(LinkList )malloc(sizeof(LNode)); /*创建新结点*s*/

s->data=e;

s->next=p->next; /*将*s插入到*p之后*/

p->next=s;

return 1;

}

}

6删除第i个元素

int ListDelete(LinkList &L,int i,ElemType &e)

{

int j=0;

LinkList p=L,q;

while (j

{

j++;

p=p->next;

}

if (p==NULL) /*未找到第i-1个结点*/

return 0;

else /*找到第i-1个结点*p*/

{

q=p->next; /*q指向要删除的结点*/

p->next=q->next; /*从单链表中删除*q结点*/

free(q); /*释放*q结点*/

return 1;

}

}

.

7其它函数::释放链表中的结点,考虑了链表是否为空相应的进行不同的操作。

3、调试分析

调试过程中遇到的主要问题,是如何解决的,对设计和编码的回顾讨论和分析;改进设想;经验和体会等。

调试过程中遇到了许多问题.

.编程过程中出现的题:

问题1:运行时出现了输入错误;

问题2:忘记#include "LinkList.h"问题

对问题的解决方案:对于问题

1:尽量注意,看清楚,不要输错;对于问题

2:把头文件#include "LinkList.h"添加上去;

比如,第一遍上机时只是将主要的函数写上去了,而没有主函数,

最后检查程序时就比较麻烦,从第一个函数看起,加上后错误才减少;其函数方面就单,我觉得做的过程中就是要先在纸上画出简单的流程图,使思路清晰,这样编程时才不至于无从下手,另外编写函数时首先要考虑

异常情况,然后才是一般情况的处理.

通过本次实验我对链表有了更深的了解,对链表的插删操作、遍历、查找等基本上掌握了。同时,通过自己数次的调试、修改也搞懂了许多以前比较模糊的知识点,比如

但这次实验也有很多不尽人意的地方,比还有就是本次实验电子报告中我原来打算加上各函数的简单流程图,但是由于我处理图形方面还比较不熟练,画了三四个小时也不太满意,所以索性将几个小时的努力通过del键结束了,所以这次报告不太令人满意,我将在以后的报告中加上示意图,多学习同学优秀的地方.也会在以后的学习过程中要尽量考虑周全,使

程序更有实用价值,提高编程能力。

4、测试结果

列出测试结果,包括输入和输出。这里的测试数据应该完整和严格,最好多于需求分析中所列。

5、附录

即带注释的源程序清单和结果。除原有注释外再加一些必要的注释和断言(关键语句或函数功能的注释)。对填空和改错题还要写出正确答案,如果题目规定了测试数据,则结果要包含这些测试数据和运行输出,当然还可以含其它测试数据及其运行输出。

头文件:

/*文件名:LinkList.h*/

typedef char ElemType; //定义数据元素的类型

typedef struct LNode /*定义单链表结点类型*/

{

ElemType data;

struct LNode *next;

}LNode,*LinkList;

//初始化单链表

void InitList(LinkList &L)

{

L=(LinkList)malloc(sizeof(LNode)); /*创建头结点*/

L->next=NULL;

}

//销毁单链表

void DestroyList(LinkList &L)

{

LinkList p=L,q=p->next;

while (q!=NULL)

{

free(p);

p=q;

q=p->next;

}

free(p);

}

//判断单链表是否为空,空表返回1,否则返回0 int ListEmpty(LinkList L)

{

return(L->next==NULL);

}

//返回单链表的长度

int ListLength(LinkList L)

{

LinkList p=L;

int i=0;

while (p->next!=NULL)

{

i++;

p=p->next;

}

return(i);

}

//打印输出单链表的每个元素

void DispList(LinkList L)

{

LinkList p=L->next;

while (p!=NULL)

{

printf("%c",p->data);

p=p->next;

}

printf("\n");

}

//获取单链表L中第i元素,由参数e返回

int GetElem(LinkList L,int i,ElemType &e)

{

int j=0;

LinkList p=L;

while (j

{

j++;

p=p->next;

}

if (p==NULL)

return 0;

else

{

e=p->data;

return 1;

}

}

//在单链表L中查找数据元素e的位置,如不存在返回0

int LocateElem(LinkList L,ElemType e)

{

LinkList p=L->next;

int n=1;

while (p!=NULL && p->data!=e)

{

p=p->next;

n++;

}

if (p==NULL) return(0);

else return(n);

}

//在单链表L中第i个位置上插入元素e

int ListInsert(LinkList &L,int i,ElemType e)

{

int j=0;

LinkList p=L,s;

while (j

{

j++;

p=p->next;

}

if (p==NULL) /*未找到第i-1个结点*/

return 0;

else /*找到第i-1个结点*p*/

{

s=(LinkList )malloc(sizeof(LNode)); /*创建新结点*s*/

s->data=e;

s->next=p->next; /*将*s插入到*p之后*/

p->next=s;

return 1;

}

}

//删除第i个元素

int ListDelete(LinkList &L,int i,ElemType &e)

{

int j=0;

LinkList p=L,q;

while (j

{

j++;

p=p->next;

}

if (p==NULL) /*未找到第i-1个结点*/ return 0;

else /*找到第i-1个结点*p*/

{

q=p->next; /*q指向要删除的结点*/

p->next=q->next; /*从单链表中删除*q结点*/

free(q); /*释放*q结点*/

return 1;

}

}

//逆位序输入n个元素的值,建立带表头结点的单链表L

void CreatList_L(LinkList &L,int n)

{

int i; LinkList p;

//先建立头结点

L=(LinkList) malloc(sizeof(LNode));

L->next = NULL;

printf("请输入结点的值:");

getchar();//吃掉上一次输入时的回车换行符

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

{

p=(LinkList)malloc(sizeof(LNode));//生产新结点

scanf("%c",&p->data ); //输入元素值

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

L->next =p;

}

}

主函数:

/*文件名:exp2-2.cpp*/

#include

#include

#include

#include "LinkList.h"

void main()

{

LinkList h;

ElemType e;

int n;

printf("(1)初始化单链表h\n");

InitList(h);

/*printf("(2)依次采用尾插法插入a,b,c,d,e元素\n");

ListInsert(h,1,'a');

ListInsert(h,2,'b');

ListInsert(h,3,'c');

ListInsert(h,4,'d');

ListInsert(h,5,'e');*/

printf("(2)采用头插法建立单链表:\n");

printf("请输入单链表结点的个数:");

scanf("%d",&n);

CreatList_L(h,n);

printf("(3)输出单链表h:");

DispList(h);

printf("(4)单链表h长度=%d\n",ListLength(h));

printf("(5)单链表h为%s\n",(ListEmpty(h)?"空":"非空"));

GetElem(h,3,e);

printf("(6)单链表h的第3个元素=%c\n",e);

printf("(7)元素a的位置=%d\n",LocateElem(h,'a'));

printf("(8)在第4个元素位置上插入f元素\n");

ListInsert(h,4,'f');

printf("(9)输出单链表h:");

DispList(h);

printf("(10)删除h的第3个元素\n");

ListDelete(h,3,e);

printf("(11)输出单链表h:");

DispList(h);

printf("(12)释放单链表h\n");

DestroyList(h); }