scanf("%d",&(L->elem[i]));
L->last=L->last+n;
}
intLenList(SeqList*L)
{
intLen;
Len=L->last+1;
returnLen;
}
intPositionList(SeqList*L,intX)
{
intj;
for(j=0;j<=L->last;j++)
if(Xelem[j])
returnj+1;
return(L->last+1);
}
intInsList(SeqList*L,inti,inte)
{
intk;
if((i<1)||(i>L->last+2))
{
printf("thepositioniswrong");
return(ERROR);
}
if(L->last>=MAXSIZE-1)
{
printf("thelistisfull");
return(ERROR);
}
for(k=L->last;k>=i-1;k--)
L->elem[k+1]=L->elem[k];
L->elem[i-1]=e;
L->last++;
return(RIGHT);
}
intOutputSeqList(SeqList*L)
{
inti;
for(i=0;i<=L->last;i++)
printf("%d,",L->elem[i]);
return(L->elem[i]);
}
voidmain()
{
ints,c;
SeqListL;
Initlist(&L);
printf("pleaseinputthelength:
");
scanf("%d",&s);
printf("pleaseinputthelist:
");
putseqList(&L,s);
LenList(&L);
printf("Pleaseinputanelementtoinsert:
");
scanf("%d",&c);
InsList(&L,PositionList(&L,c),c);
OutputSeqList(&L);
printf("\n");
getch();
}
五、实验数据记录和处理
六、实验结果与分析
此程序的优点是算法简单,易于实现。
但是由于采用的是顺序存储的形式,导致算法的时间性能和空间性能不是很好,而且本程序的的健壮性不是很好,对空间不够的情况没有很人性化的提出解决方案。
七、讨论、心得
改进思想:
#defineLIST_INIT_SIZE100
typedefstruct{
int*elem;
intlength;
intlistsize;
}sqlist;
voidcreat_sqlist(sqlist*p){
inti,l;
p->elem=(int*)malloc(LIST_INIT_SIZE*sizeof(int));
if(!
p->elem)
{
printf("OVERFLOW");
exit
(1);
}
printf("Pleaseinputlength:
\n");
scanf("%d",&l);
p->length=l;
p->listsize=LIST_INIT_SIZE;
printf("Inputsqlist:
\n");
for(i=0;ilength;i++)
scanf("%d",&p->elem[i]);
for(i=0;ilength;i++)
printf("%d",p->elem[i]);
printf("\n");
}
这是对顺序表构造的部分改进,同时可以将数据的存储改成链表的形式。
心得体会:
通过本次试验让我对顺序表有了更深层次的了解,同时也对顺序表和链表的区别有了自己的见解。
树形结构
一、实验目的和要求
熟悉树的各种表示方法和各种遍历方式,掌握有关算法的实现,了解树在计算机科学及其它工程技术中的应用。
2、实验内容和原理
习题
[问题描述]
编写递归算法,计算二叉树中叶子结点的数目。
[输入]
一棵二叉树的结点若无子树,则可将其子树看作“.”,输入时,按照前序序列的顺序输入该结点的内容。
对下图,其输入序列为ABD..EH...CF.I..G..。
A
BC
DEFG
HI
[输出]
二叉树中叶子结点的个数
[存储结构]
采用二叉链表存储。
[算法的基本思想]
求二叉树中叶子结点个数,即求二叉树的所有结点中左、右子树均为空的结点个数之和。
可以将此问题转化为遍历问题,在遍历中“访问一个结点”时判断该结点是不是叶子,若是则将计数器累加。
三、主要仪器设备
使用的计算机惠普:
硬件配置Win7、软件环境win-TC
四、操作方法与实验步骤
[习题源程序]
#include
structBiTree{
chardata;
structBiTree*lchild;
structBiTree*rchild;
};
structBiTree*CreatBiTree(){
charx;
structBiTree*p;
scanf("%c",&x);
if(x!
='.'){
p=(structBiTree*)malloc(sizeof(structBiTree));
p->data=x;
p->lchild=CreatBiTree();
p->rchild=CreatBiTree();
}
else
p=NULL;
returnp;
}
intLeafNum(structBiTree*T){
if(!
T)
return0;
else
if(!
T->lchild&&!
T->rchild)
return1;
else
returnLeafNum(T->lchild)+LeafNum(T->rchild);
}
intmain(){
intnum;
structBiTree*T;
printf("Pleaseinputthetree(pre):
\n");
T=CreatBiTree();
while(T==NULL){
printf("empoty,again:
\n");
T=CreatBiTree();
}
num=LeafNum(T);
printf("\nthesumofleafis:
%d\n",num);
getch();
}
五、实验数据记录和处理
六、实验结果与分析
实验程序采用了二叉链表作为存储结构方便了递归函数的进行。
此外由于数的定义采用了递归的形式,所以关于数的构造、遍历、以及其他运算采用递归形式,使得程序的可阅读性增强。
7、讨论、心得
改进思想:
voidCountLeaf(BitreeT,int&cout)
{
if(T)
{
if((!
T->lchild)&&(!
T->rchild))count++;
}
CountLeaf(T->lchild,count);
CountLeaf(T->rchild,count);
}
采用C++的引用形式,可以对叶子结点的程序上进行修正,使其看起来更为简练。
心得体会:
通过实验操作,了解到了数的递归定义的优点,以及对于程序算法上的思想指导。
同时,也对数的不同存储形式有了了解。
图结构
一、实验目的和要求
熟悉图的存储结构,掌握有关算法的实现,了解图在计算机科学及其他工程技术中的应用。
二、实验内容和原理
习题
【问题描述】
试基于图的深度优先搜索策略编写一程序,判别以邻接表方式存储的有向图中是否存在有顶点Vi到Vj顶点的路径(i≠j)。
【输入】
图的顶点个数N,以及以V1、V2、V3、V4为弧尾的所有的弧,并以-1结束。
还有你要判断是否连通的两个顶点。
【输出】
若A到B无路径,则输出“不是连通的”,否则输出A到B路径上各顶点。
【存储结构】
图采用邻接矩阵的方式存储。
【算法的基本思想】
采用深度优先搜索的方法,从顶点A开始,依次访问与A邻接的顶点VA1,VA2,...,VAK,访问遍之后,若没有访问B,则继续访问与VA1邻接的顶点VA11,VA12,...,VA1M,再访问与VA2邻接顶点...,如此下去,直至找到B,最先到达B点的路径,一定是边数最少的路径。
实现时采用队列记录被访问过的顶点。
每次访问与队头顶点相邻接的顶点,然后将队头顶点从队列中删去。
若队空,则说明到不存在通路。
在访问顶点过程中,每次把当前顶点的序号作为与其邻接的未访问的顶点的前驱顶点记录下来,以便输出时回溯。
三、主要仪器设备
使用的计算机惠普:
硬件配置Win7、软件环境win-TC
四、操作方法与实验步骤
[习题源程序]
#include"stdio.h"
intn;
structVNode
{
intposition;
structVNode*next;
};
structArcNode
{
intmark;
structVNode*first;
};
voidDFS(structArcNode*v,structArcNode*w)
{
structVNode*L;
w->mark=1;
L=w->first;
while(L!
=NULL)
{
if((v+(L->position))->mark==0)
{
DFS(v,(v+L->position));
}
L=L->next;
}
}
intmain()
{
inti,j,k;
intkey1,key2;
intnum=0;
structArcNode*p;
structVNode*temp;
structVNode*flag;
printf("youxiangtudedingdian:
\n");
scanf("%d",&n);
while(n<1)
{
printf("shurucuowu,again:
\n");
scanf("%d",&n);
}
p=(structArcNode*)malloc(n*sizeof(structArcNode));
for(i=0;i{
printf("shuruV%d\n",i+1);
scanf("%d",&k);
if(k==-1)
{
p[i].mark=0;
p[i].first=NULL;
}
else
{
temp=(structVNode*)malloc(sizeof(structVNode));
temp->position=k;
temp->next=NULL;
p[i].first=temp;
p[i].mark=0;
flag=temp;
scanf("%d",&k);
while(k!
=-1)
{
temp=(structVNode*)malloc(sizeof(structVNode));
temp->position=k;
temp->next=NULL;
flag->next=temp;
flag=temp;
scanf("%d",&k);
}
}
}
printf("shuruliangdiandeweizi:
\n");
printf("\n");
scanf("%d%d",&key1,&key2);
DFS(p,(p+key1));
if(p[key2].mark==1)
{
printf("V%d\V%d\n",key1+1,key2+1);
}
else
{
p[key1].mark=0;
DFS(p,(p+key2));
if(p[key1].mark==1)
{
printf("V%dV%dliantong\n",key1+1,key2+1);
}
else
{
printf("V%dV%dbuliantong\n",key1+1,key2+1);
}
}
system("pause");
return0;
getch();
}
五、实验数据记录和处理
六、实验结果与分析
图结构是一个复杂的结构,在建立图和对图进行深度优先遍历是程序执行的关键步骤其时间复杂度为0(n²)
七、讨论、心得
这次试验的程序在输入上有很高的要求,比如例题的输入是要输入不带权值的图结构,也就是说有关系用1表示,没关系用0表示。
查找
一、实验目的和要求
通过本次实验,掌握查找表上的有关查找方法,并分析时间复杂度。
二、实验内容和原理
习题
【问题描述】
将折半查找算法改写成递归算法。
【输入】
输入有序表
【输出】
要查找元素的位置
【存储结构】
数组存储。
【算法的基本思想】
将n个元素分成个数大致相同的两半,取a[n/2]与欲查找的x作比较,如果x=a[n/2]则找到x,算法终止。
如果x如果x>a[n/2],则我们只要在数组a的右半部继续搜索x。
递归调用这个算法。
三、主要仪器设备
使用的计算机惠普:
硬件配置Win7、软件环境win-TC
四、操作方法与实验步骤
[习题源程序]
#include"stdio.h"
typedefstruct
{
inta[30];
intlength;
}sqtable;
sqtablest;
intb=0;
voidcreatest(intk)
{
inti;
printf("Pleaseinputdata:
");
st.a[0]=-100;
for(i=1;(!
b&&(i<=k));i++)
{
scanf("%d",&(st.a[i]));
if(st.a[i]{
printf("Inputdataerror.\n");
b=1;
}
}
if(!
b)
{
st.length=k;
printf("Thetableisbuilted.\n");
}
}
intstfind(sqtablest,intl,inth,inty)
{
intm;
while(l<=h)
{
m=(l+h)/2;
if(y==st.a[m])
returnm;
elseif(yelsereturnstfind(st,m+1,h,y);
}
}
main()
{
intn,x,l,h,s;
l=1;
h=st.length;
printf("\nPleaseinputn:
");
scanf("%d",&n);
createst(n);
h=st.length;
if(b==0)
{
printf("Pleaseinputyouwantfindvalue:
");
scanf("%d",&x);
s=stfind(st,l,h,x);
}
printf("Find%dinposition%d.\n",x,s);
getch();
}
五、实验数据记录和处理
六、实验结果与分析
程序体现了折半算法优越性,它比顺序查找的时间性能更为优越。
其平均查找长度为
ASL=[(n+1)/n*log(n+1)]-1
七、讨论、心得
改进思想:
#include"stdio.h"
#include"conio.h"
#include"alloc.h"
#definen14
intcount=0;
intbin_search(inta[],intlow,inthigh,intx)
{
intmid;
count++;
if(low>high)return-1;
else
{
mid=(low+high)/2;
if(x==a[mid])returnmid;
elseif(xreturnbin_search(a,low,mid-1,x);
else
returnbin_search(a,mid+1,high,x);
}
}
main()
{
ints,i,x;
inta[n];
printf("Input14numbers:
\n");
for(i=0;i{
scanf("%d",&a[i]);
}
printf("Inputanumberthatyouwanttosearch:
\n");
scanf("%d",&x);
s=bin_search(a,0,13,x);
if(s==-1)
{
printf("fail\n");
printf("chaxu%dci\n",count);
}
else
{
printf("chazhao%dci\n",count);
printf("chazhaoxiabiaoshi:
%d\n",s);
}
getch();
}
心得体会:
通过本次试验对查找有了深刻的了解,认识到不同查找方法的区别和不同的优势。
同时对折半查找算法的思想有了很深的认识。
排序
一、实验目的和要求
通过本次实验,掌握线性表的排序方法,并分析时间复杂度。
二、实验内容和原理
[问题描述]
对于N个关键字取整数的记录进行整序,以使所有关键字为非负数的记录排在关键字为负数的记录之前,要求使用最少的附加空间,且算法的时间复杂度为O(N)。
[输入]
一组数据。
[输出]
非负数排在负数之前。
[存储结构]
顺序存储。
[算法的基本思想]
由于问题仅要求非负数排在负数之前,所以提取非负数插在前面即可。
三、主要仪器设备
使用的计算机惠普:
硬件配置Win7、软件环境win-TC
4、操作方法与实验步骤
[习题源程序]
#include"stdio.h"
voidSort(int*a,intm)
{
inti=0;
intj=m-1;
intt;
while(i<=j)
{
while(i=0)
{
i++;
}
while(j>=0&&a[j]<0)
{
j--;
}
if(i{
t=a[i];
a[i]=a[j];
a[j]=t;
i++;
j--;
}
}
}
intmain()
{
intn,i;
int*p;
printf("youhavehowmanydatawanttoinput:
\n");
scanf("%d",&n);
while(n<2)
{
printf("youinputdataiswrong,pleaseinputagain:
\n");
scanf("%d",&n);
}
p=(int*)malloc(n*sizeof(int));
printf("inputdata:
\n");
for(i=0;i{
scanf("%d",&p[i]);
}
Sort(p,n);
printf("afterorderdatais:
\n");
for(i=0;i{
printf("%-4d",p[i]);
}
printf("\n");
system("pause");
return0;
getch();
}
5、实验数据记录和处理
六、实验结果与分析
此程序的优点是算法简单,便于操作和理解其缺点是空间复杂度不是很好。
时空性能都为O(N)。
七、讨论、心得
对于本次试验程序而言,采用链表形式更可以提高算法的性能,减少空间复杂度。
同时,通过本次试验,对查找思想有了更深刻的了解。