数据结构实验指导书02Word文档格式.docx

上传人:b****3 文档编号:16656013 上传时间:2022-11-25 格式:DOCX 页数:29 大小:87.13KB
下载 相关 举报
数据结构实验指导书02Word文档格式.docx_第1页
第1页 / 共29页
数据结构实验指导书02Word文档格式.docx_第2页
第2页 / 共29页
数据结构实验指导书02Word文档格式.docx_第3页
第3页 / 共29页
数据结构实验指导书02Word文档格式.docx_第4页
第4页 / 共29页
数据结构实验指导书02Word文档格式.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

数据结构实验指导书02Word文档格式.docx

《数据结构实验指导书02Word文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构实验指导书02Word文档格式.docx(29页珍藏版)》请在冰豆网上搜索。

数据结构实验指导书02Word文档格式.docx

参考程序:

//头文件SqList.h的内容如下:

#include<

stdio.h>

malloc.h>

#defineTRUE1

#defineFALSE0

#defineOK1

#defineERROR0

#defineINFEASIBLE-1

#defineOVERFLOW-2

typedefintStatus;

typedefstruct{

ElemType*elem;

StatusInitList_Sq(SqList*L)

L->

elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));

if(!

L->

elem)return(OVERFLOW);

length=0;

listsize=LIST_INIT_SIZE;

returnOK;

}

StatusCreatList_Sq(SqList*L,intn)

inti;

printf("

输入%d个整数:

\n"

n);

for(i=0;

i<

n;

i++)

scanf("

\n%d"

&

elem[i]);

//以下是整个源程序(保存在shiyan2_1_1.c文件中):

#include"

SqList.h"

voidmain()

inti,n;

SqLista;

SqList*l=&

a;

if(InitList_Sq(l)=-2)printf("

分配失败\n"

);

\n输入要建立的线性表l的长度n:

"

);

//输入线性表的长度

%d"

n);

l->

length=n;

线性表的长度是:

%d\n"

l->

length);

CreatList_Sq(l,n);

//生成线性表

输出线性表l中的元素值:

"

//输出线性表中的元素

l->

length;

%7d"

getch();

}

[实验2]顺序表的插入

实验内容与要求:

利用前面的实验先建立一个顺序表L={21,23,14,5,56,17,31},然后在第i个位置插入元素68,通过对比插入元素前后的线性表发生的变化,判断插入操作是否正确。

分析:

从插入位置到最后位置的所有元素都要后移一位,使空出的位置插入元素值e。

一般在第i个元素之前(1<

=i<

=n)插入一个新元素时,需要有n-i+1个元素进行移动。

但是,插入的位置是不固定的,当插入位置i=1时,全部元素都得移动,需n次移动,当i=2时,移动n-1个元素,依次类似,当i=n时,仅需移动元素一次。

如图2-2所示。

注意如何取到第i个元素,在插入过程中注意溢出情况以及数组的下标与位序(顺序表中元素的次序)的区别。

参考程序:

//保存在shiyan2_1_2.c文件中

StatusListInsert_Sq(SqList*L,inti,ElemTypee){

//在线性表L中的第i个位置前插入一个值为e的元素

//i的取值范围:

1<

=ListLength_Sq(L)

ElemType*newbase,*q,*p;

if(i<

1||i>

length+1)returnERROR;

//i值不合法

if(L->

length>

=L->

listsize){//当前存储空间已满,增加分配量

newbase=(ElemType*)realloc(L->

elem,

(L->

listsize+LISTINCREMENT)*sizeof(ElemType));

newbase)return(OVERFLOW);

//存储分配失败

elem=newbase;

//新基址

length=+LISTINCREMENT;

//增加存储容量

}//if

q=&

(L->

elem[i-1]);

//q为插入位置

for(p=&

elem[L->

length-1]);

p>

=q;

--p)*(p+1)=*p;

//插入位置及以后的元素右移

*q=e;

//插入e

++L->

//表长增1

}//ListInsert_Sq

{

intn,i,x;

SqList*L,a;

L=&

InitList_Sq(L);

\n输入要建立的线性表L的长度:

CreatList_Sq(L,n);

printf("

\n插入元素之前线性表L的长度是:

%d"

L->

printf("

\n插入元素之前线性表L中的元素是:

%5d"

L->

\n输入要插入元素的位置:

scanf("

i);

\n输入要插入的元素的值:

\n%d"

x);

if(ListInsert_Sq(L,i,x)>

0)

\n插入元素之后线性表L的长度是:

printf("

\n插入元素之后线性表L的元素是:

}//if

else

can'

tinsertthedata!

getch();

[实验3]单链表的建立

建立一个带头结点的单链表,结点的值域为整型数据。

要求将用户输入的数据按尾插入法来建立相应单链表。

为了便于实现各种运算,通常在单链表的第一个结点前增设一个附加结点,称为头结点,它的结构与表结点相同,其数据域可不存储信息,也可存储表长等附加信息,具体见图2_3。

(a)不带头结点

(b)带头结点的单链表

单链表的结点结构除数据域外,还含有一个指针域。

用C语言描述结点结构如下:

typedefstructLNode

ElemTypedata;

//数据域

structLNode*next;

//指针域

}Lnode,*Linklist;

注意结点的建立方法及构造新结点时指针的变化。

构造一个结点需用到C语言的标准函数malloc(),如给指针变量p分配一个结点的地址:

p=(Linklist)malloc(sizeof(LNode));

该语句的功能是申请分配一个LNode类型结点的地址空间,并将首地址存入指针变量p中。

当结点不需要时可以用标准函数free(p)释放结点存储空间,这时p为空值(NULL)。

//保存在头文件LinkList.h

#defineNULL0

typedefstructLNode{

}LNode,*LinkList;

voidCreatList_L(LinkListL,intn)

LinkListp,q;

q=L;

for(i=1;

=n;

{

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

输入线性表的第%d个元素:

i);

p->

data);

p->

next=q->

next;

q->

next=p;

q=q->

}

//以下程序保存在文件shiyan2_1_3.c中:

LinkList.h"

LinkListhead,p;

intn;

\n输入要建立链表的长度:

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

head->

next=NULL;

CreatList_L(head,n);

\n以head为头指针的链表中的元素:

p=head->

while(p)

%5d"

p->

p=p->

[实验4]单链表的合并

建立两个带头结点的有序单链表La,Lb(单调递增),利用La,Lb的结点空间,将La和Lb合并成一个按元素值递增的有序单链表Lc。

对于单链表的操作必须清楚如何将结点插入到链表中,比如将新结点x插入到结点a和b之间,插入结点的指针变化如图2-4所示。

程序需要3个指针:

pa,pb,pc,其中pa,pb分别指向La表、Lb表的首结点,用pa遍历La表,pb遍历Lb表,pc指向合并后的新表的最后一个结点(即尾结点),pc的初值指向La表的头结点。

合并的思想是:

先利用实验3的内容建立好两个链表La表和Lb表,然后依次扫描La和Lb中的元素,比较当前元素的值,将较小者链到*pc之后,如此重复直到La或Lb结束为止,再将另一个链表余下的内容链到pc所指的结点之后。

//以下是程序保存在shiyan2_1_4.c文件中

LinkList.h"

voidMergeList_L(LinkListLa,LinkListLb,LinkListLc)

LinkListpa,pb,pc;

pa=La->

pb=Lb->

pc=Lc;

while(pa&

&

pb)

if(pa->

data>

pb->

data)

pc->

next=pb;

pc=pb;

pb=pb->

else

next=pa;

pc=pa;

pa=pa->

next=pa?

pa:

pb;

free(Lb);

LinkListLa,Lb,Lc,p;

intn1,n2;

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

La->

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

Lb->

Lc=NULL;

\n请输入要建立的链表La的长度:

n1);

CreatList_L(La,n1);

\n请输入要建立的链表Lb的长度"

n2);

CreatList_L(Lb,n2);

p=La->

\n链表La中的元素:

while(p)

p=Lb->

\n链表Lb中的元素:

MergeList_L(La,Lb,Lc);

p=Lc->

\n输出由链表La和Lb归并得到的链表Lc中的元素:

%d"

[实验5]删除单链表中的重复值

编写算法实现将单链表L中值重复的结点删除,使所得结果表中各结点值均不相同。

本题涉及到单链表中关于值的查找算法,从头结点开始,活动指针p沿着单链表向后扫描,寻找某个给定值。

首先建立一个单链表,令p指针指向所建单链表的第一个结点,令q指向p的后继结点,q沿着链表向右(向后)扫描,若找到与p所指结点值相同的结点,则将其删除,继续处理,直到q为空;

然后令p移到下一个结点(即直接后继结点),q依然指向p的后继结点,重复同样的处理。

显然此题需要用到双重循环。

//以下程序保存在shiyan2_1_5.c

//DeleteSameNode函数用来删除链表中重复的结点

voidDeleteSameNode(LinkListh)

LinkListp,q,s

 p=h->

 s=p;

 while(p!

=NULL)

q=p->

 while(q!

if(q->

data!

=p->

{

s=q;

//s为q的直接前趋指针,即s紧跟着q向右移动。

q=q->

}//if

s->

//此时q所指向的结点为待删除结点

 free(q);

 q=s->

//q指向后继结点,继续寻找与p所指结点值相同的结点。

 }//else

 }//while(q!

 p=p->

s=p;

}//while(p!

//OutPut函数用来输出单链表的内容

voidOutPut(LinkListh)

LinkListp;

p=h->

%5"

p=p->

}//while

LinkListhead;

intn;

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

head->

请输入要建立的链表的长度:

\n"

CreatList(head,n);

链表中的元素是:

output(head);

删除链表中结点的重复值!

DeleteSameNode(head);

OutPut(head);

//输出经过处理后的单链表,此时单链表中的值应该唯一。

[实验6]单循环链表的逆置

将一个已知的单循环链表进行逆置运算,如(a1,a2,a3,…,an)变为(an,an-1,…,a2,a1)。

对于单链表而言,最后一个结点的指针域是空指针,如果将该链表头指针置入该指针域,则使得链表头尾结点相连,就构成了单循环链表。

对于单链表只能从头结点开始遍历整个链表,而对于单循环链表则可以从表中任意结点开始遍历整个链表。

所谓链表的逆置运算(或称为逆转运算)是指在不增加新结点的前提下,依次改变数据元素的逻辑关系,使得线性表(a1,a2,a3,…,an)成为(an,an-1,…,a2,a1)。

本题采用的算法是:

先建立一个带头结点的单循环链表,从头到尾扫描单链表L,把p作为活动指针,沿着链表向前移动,q作为p前趋结点,r作为q的前趋结点。

其中,q的next值为r,r的初值置为head。

//头文件LNode.h的内容:

#include<

ElemTypedata;

structLNode*next;

}LNode,*LinkList;

//以下是主程序保存在shiyan2_1_6.c中

#include“LNode.h”

//输出循环链表的信息

voidOutPut(LinkListhead)

p=head->

while(p!

=head)

//建立单循环链表

voidCreat(LinkListh,intn)

intk;

LNode*r,*p;

r=h;

for(k=1;

k<

k++)

printf(“输入第%d个结点的数值:

”,k);

p=(LNode*)malloc(sizeof(LNode));

scanf(“%d”,&

next=h;

r->

r=p;

//逆置函数

voidInvert(LinkListh)

LinkListp,q,r;

q=h;

=h)

r=q;

q=p;

q->

next=r;

h->

next=q;

\n输入所建立的循环链表的结点个数:

head=(LNode*)malloc(sizeof(LNode));

next=head;

Creat(head,n);

输出建立的单循环链表:

\n现在进行逆置!

Invert(head);

\n输出进行逆置运算后的单循环链表的结点信息:

2.4提高实验

[实验1]学生成绩管理

学生成绩管理是学校教务管理的重要组成部分,其处理信息量很大,本实验是对学生的成绩管理作一个简单的模拟,用菜单选择操作方式完成下列功能:

①登录学生成绩;

②查询学生成绩;

③插入学生成绩;

④删除学生成绩

本实验涉及单链表的各种操作,包括单链表的建立、结点的查找、插入、删除等基本运算。

链表中插入结点的指针变化见图2-4所示,删除p所指结点的指针变化见图2-5所示。

首先建立学生成绩单链表,每条记录由学号、姓名与成绩组成,即链表中每个结点由4个域组成,分别为:

学号、姓名、成绩、存放下一个结点地址的next域。

然后将要求完成的四项功能写成四个函数,登记学生成绩对应建立学生单链表的功能,后三个功能分别对应单链表的查询、插入与删除三大基本操作。

该系统中的数据采用线性表中的链式存储结构即单链表来存储,用结构体类型定义每个学生记录,这样单链表中每个结点的结构可描述为:

#defineMAXLEN100

typedefstructNode

intnum;

//学号

charname[MAXLEN];

//姓名

floatscore;

//成绩

structNode*next;

}Node;

参考程序

//头文件hh.h的内容

stdlib.h>

#defineMAXLEN100

intnum;

charn

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

当前位置:首页 > 表格模板 > 合同协议

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

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