数据结构实验报告之静态查找表Word格式.docx
《数据结构实验报告之静态查找表Word格式.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告之静态查找表Word格式.docx(13页珍藏版)》请在冰豆网上搜索。
Search(ST,key);
静态查找表ST存在,key为和关键字类型相同的
给定值。
若ST中存在其关键字等于key的数据元素,则
函数值为其值或在表中的位置,否则为“空”。
Traverse(ST,Visit());
静态查找表ST存在,Visit是对元素操作的应用
函数。
按某种次序对ST的每个元素调用函数Visit()一
次且仅一次。
一旦Visit()失败,则操作失败。
}ADTStaticSearchTable
2.存储结构定义
*公用头文件DS0.h:
#include<
stdio.h>
malloc.h>
math.h>
*预定义常量和类型
//函数结果状态代码
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
typedefintStatus;
typedefintKeyType;
typedeffloatKeyType;
typedefcharKeyType;
typedefintElemType;
typedefElemTypeTElemType;
1)顺序存储结构
typedefstruct{
ElemType*elem;
//数据元素存储空间基址,0号单元留空
intlength;
//表长
}SSTable;
2)二叉链表存储结构
typedefstructBiTNode{
TElemTypedata;
structBiTNode*lchild,*rchild;
//左右孩子指针
}BiTNode,*BiTree;
3.算法设计
1)顺序表的查找
voidCreat_Seq(SSTable*ST,ElemTyper[],intn){
inti;
(*ST).elem=(ElemType*)calloc(n+1,sizeof(ElemType));
//动态生成n+1个数据元素空间(0号单元不用)
if(!
(*ST).elem)exit(0);
for(i=1;
i<
=n;
i++)
(*ST).elem[i]=r[i-1];
//将数组r的值依次赋给ST
(*ST).length=n;
}
StatusDestroy_Seq(SSTable&
ST){
free(ST.elem);
ST.elem=NULL;
ST.length=0;
returnOK;
}
intSearch_Seq(SSTableST,KeyTypekey){
ST.elem[0].key=key;
//哨兵
for(i=ST.length;
!
(ST.elem[i].key==key);
--i);
//从后往前找
returni;
//找不到时,i为0
voidTraverse(SSTableST,void(*Visit)(ElemType)){
ElemType*p;
p=++ST.elem;
//p指向第一个元素
=ST.length;
Visit(*p++);
2)有序表的查找
intSearch_Bin(SSTableST,KeyTypekey){
intlow,high,mid;
low=1;
high=ST.length;
//置区间初值
while(low<
=high){
mid=(low+high)/2;
if(key==ST.elem[mid])returnmid;
//找到待查元素
elseif(key<
ST.elem[mid])high=mid-1;
/*继续在前半区间查找*/
elselow=mid+1;
//继续在后半区间查找
return0;
//查找失败
3)静态树表的查找
StatusCreat_Seq(SSTable*ST,intn){
voidAscend(SSTable*ST)
{//重建静态查找表为按关键字非降序排序
inti,j,k;
(*ST).length;
{
k=i;
(*ST).elem[0]=(*ST).elem[i];
//待比较值存[0]单元
for(j=i+1;
j<
=(*ST).length;
j++)
if((*ST).elem[j].key<
(*ST).elem[0].key)
k=j;
(*ST).elem[0]=(*ST).elem[j];
}
if(k!
=i)//有更小的值则交换
(*ST).elem[k]=(*ST).elem[i];
(*ST).elem[i]=(*ST).elem[0];
StatusCreat_Ord(SSTable*ST,intn)
{
Statusf;
f=Creat_Seq(ST,n);
if(f)
Ascend(ST);
returnf;
StatusSecondOptimal(BiTree*T,ElemTypeR[],intsw[],intlow,inthigh){
inti,j;
doublemin,dw;
i=low;
min=fabs(sw[high]-sw[low]);
dw=sw[high]+sw[low-1];
for(j=low+1;
=high;
++j)//选择最小值
if(fabs(dw-sw[j]-sw[j-1])<
min)
i=j;
min=fabs(dw-sw[j]-sw[j-1]);
*T=(BiTree)malloc(sizeof(BiTNode));
*T)
returnERROR;
(*T)->
data=R[i];
//生成结点
if(i==low)
lchild=NULL;
//左子树空
else
SecondOptimal(&
(*T)->
lchild,R,sw,low,i-1);
//构造左子树
if(i==high)
rchild=NULL;
rchild,R,sw,i+1,high);
StatusTraverse(SSTableST,void(*Visit)(ElemType)){
//p指向第一个元素
voidFindSW(intsw[],SSTableST){
sw[0]=0;
sw[i]=sw[i-1]+ST.elem[i].weight;
typedefBiTreeSOSTree;
StatusCreateSOSTree(SOSTree*T,SSTableST)
if(ST.length==0)
*T=NULL;
FindSW(sw,ST);
SecondOptimal(T,ST.elem,sw,1,ST.length);
StatusSearch_SOSTree(SOSTree*T,KeyTypekey)
while(*T)
if((*T)->
data.key==key)
elseif((*T)->
data.key>
key)
*T=(*T)->
lchild;
rchild;
returnFALSE;
4.测试:
1)顺序表的查找
typedefstruct{//数据元素
longnumber;
//准考证号
charname[9];
intpolitics;
intChinese;
intEnglish;
intmath;
intphysics;
intchemistry;
intbiology;
inttotal;
//总分
}ElemType;
//以教科书图9.1高考成绩为例
voidprint(ElemTypec){
printf("
%-8ld%-8s%4d%5d%5d%5d%5d%5d%5d%5d\n"
c.number,c.name,c.politics,c.Chinese,c.English,c.math,c.physics,c.chemistry,c.biology,c.total);
SSTablehead;
intmain(){
ElemTyper[N]={{179325,"
陈红"
85,86,88,100,92,90,45},
{179326,"
陆华"
78,75,90,80,95,88,37},
{179327,"
张平"
82,80,78,98,84,96,40}};
SSTablest;
longs;
for(i=0;
N;
i++)//计算总分
r[i].total=r[i].politics+r[i].Chinese+r[i].English+r[i].math+r[i].physics+r[i].chemistry+r[i].biology;
Creat_Seq(&
st,r,N);
printf("
准考证号姓名政治语文外语数学物理化学生物总分\n"
);
Traverse(st,print);
请输入待查找人的考号:
"
scanf("
%ld"
&
s);
i=Search_Seq(st,s);
if(i)
print(st.elem[i]);
查找失败\n"
结果截图如下:
<
1>
查找成功:
2>
查找失败:
SSTbalehead;
intj,k,t,w;
SSTableST;
ST.length=LENGTH;
请按大小顺序输入一个顺序表共%d个元素!
\n"
ST.length);
ST.elem=(ElemType*)malloc((ST.length+1)*sizeof(ElemType));
scanf("
%d"
ST.elem[i]);
请输入要查找的元素:
"
k);
w=Search_Bin(ST,k);
if(w)printf("
您要查找的%d是第%d个元素\n"
k,w);
elseprintf("
3)静态树链表的查找
typedefstruct{//数据元素类型
KeyTypekey;
intweight;
ElemTyper[M]={{'
A'
1},{'
B'
C'
2},{'
D'
5},{'
E'
3},
{'
F'
4},{'
G'
H'
3},{'
I'
5}};
//以教科书例9-1为例
voidprint(ElemTypec)/*Traverse()调用的函数*/
{
(%c%d)"
c.key,c.weight);
intmain()
SOSTreet;
Statusi;
KeyTypes;
Creat_Ord(&
st,M);
/*由全局数组产生非降序静态查找表st*/
CreateSOSTree(&
t,st);
/*由有序表构造一棵次优查找树*/
\n请输入待查找的字符:
%c"
i=Search_SOSTree(&
t,s);
%c的权值是%d\n"
s,t->
data.weight);
表中不存在此字符\n"
三、实验总结和体会
1.几种存储结构的比较
1)顺序查找:
优点:
算法简单且适应面广;
缺点:
平均查找长度较大,特别是当n很大时,查找效率较低。
2)有序表的查找:
优点:
查找效率比顺序查找快;
适应面小,只能用于顺序存储结构的有序表(以等概率为前提)。
3)静态树表的查找:
优缺点与有序表的查找类似,但用于不等概率的有序表。
2.思考与小结
1)编程是需要大量练习的。
平常写anyview不用写头文件,调试的机会也少,这次实验要用的时候只能再去翻C语言课本。
2)理论跟实践是有差别的。
课本上的东西也不一定全都是正确的,只有自己写代码调试一下才知道对错。
3)不同的查找方法适用于不同的情况,应地制宜地选择适当的查找方法可以使我们的代码更加高效。