数据结构第八次实验报告文档格式.docx
《数据结构第八次实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构第八次实验报告文档格式.docx(19页珍藏版)》请在冰豆网上搜索。
KeyTypekey;
}BSTNode,*BSTree;
BSTreeinsertBST(BSTreetptr,KeyTypekey)//
{BSTreef,p=tptr;
//p的初值指向根结点
while(p)//查找插入位置,循环结束时,p是空指针,f指向待插入结点的双亲
{
if(p->
key==key)//树中已有key,无须插入
returntptr;
f=p;
//f保存当前查找的结点,即f是p的双亲
p=(key<
p->
key)?
left:
right;
}
p=(BSTree)malloc(sizeof(BSTNode));
//生成新结点
p->
key=key;
left=p->
right=NULL;
if(tptr==NULL)//原树为空,新插入的结点为新的根
tptr=p;
else
if(key<
f->
key)
f->
left=p;
else
right=p;
returntptr;
}
BSTreecreateBST()//建立二叉树
{
BSTreet=NULL;
//根结点
cin>
>
key;
while(key!
=-1)
t=insertBST(t,key);
cin>
returnt;
voidinorder_btree(BSTreeroot)//中序遍历打印二叉排序树
BSTreep=root;
if(p!
=NULL){
inorder_btree(p->
left);
cout<
<
"
"
key<
;
right);
intsearchBST(BSTreet,KeyTypekey)//查找
if(key==t->
return1;
if(t==NULL)
return0;
if(key<
t->
returnsearchBST(t->
left,key);
right,key);
BSTreedeleteBST(BSTreetptr,KeyTypekey)//删除
BSTreep,tmp,parent=NULL;
p=tptr;
while(p)
if(p->
key==key)
break;
parent=p;
p=(key<
if(!
p)returnNULL;
tmp=p;
right&
&
!
left)/*p的左右子树都为空*/
parent)//要删根,须修改根指针
tptr=NULL;
elseif(p==parent->
right)
parent->
left=NULL;
free(p);
elseif(!
right)//p的右子树为空,则重接p的左子树
p=p->
left;
tptr=p;
elseif(tmp==parent->
left)
free(tmp);
left)//的左子树为空,则重接p的左子树
elseif(p->
left)//p有左子树和右子树,用p的后继覆盖p然后删去后继
{//另有方法:
用p的前驱覆盖p然后删去前驱||合并p的左右子树
//由于用覆盖法删根,则不必特殊考虑删根
while(p->
tmp->
key=p->
if(p==parent->
returntptr;
intmain()
intflag,test;
charcmd;
BSTreeroot;
do
\n\n"
endl;
\t\t*******请选择你要执行的操作:
********"
\n"
\t\tC.创建一棵二叉排序树\n"
\t\tE.结束本程序\n"
\n\n\t\t************************************"
flag=0;
do
{
if(flag!
=0)
cout<
选择操作错误!
请重新选择!
fflush(stdin);
cin>
cmd;
flag++;
}while(cmd!
='
c'
cmd!
C'
a'
A'
);
if(cmd=='
||cmd=='
)
cout<
请输入你所要创建的二叉树的结点的值,以-1结束:
root=createBST();
do
{
flag=0;
\n\n中序遍历二叉树:
inorder_btree(root);
\t\t************请选择你要对这棵二叉树所做的操作:
**************"
\t\t****"
\t\t**S......查找你想要寻找的结点**"
\t\t**I......插入你想要插入的结点**"
\t\t**D......删除你想要删除的结点**"
\t\t**Q......结束对这棵二叉树的操作**"
\t\t***********************************************************"
do{
if(flag!
cout<
fflush(stdin);
scanf("
%c"
&
cmd);
flag++;
}while(cmd!
s'
S'
i'
I'
d'
D'
q'
Q'
switch(cmd)
{
case'
:
cout<
请输入你要查找结点的关键字:
cin>
test=searchBST(root,key);
if(test==0)
\n对不起,你所查找的结点"
不存在!
else
\n成功找到结点\n"
break;
请输入你要插入结点的关键字:
root=insertBST(root,key);
//注意必须将值传回根
请输入你要删除结点的关键字:
root=deleteBST(root,key);
if(root==NULL)
\n对不起,你所删除的结点"
不存在!
\n成功删除结点"
}
}while(cmd!
}
}while(cmd!
e'
E'
return0;
2、实现哈希表的相关运算
malloc.h>
stdio.h>
math.h>
#defineOK1
#defineERROR0
typedefintStatus;
/*Status是函数的类型,其值是函数结果状态代码,如OK等*/
#defineNULLKEY0/*0为无记录标志*/
#defineN10/*数据元素个数*/
/*设关键字域为整型*/
typedefstruct
intord;
}ElemType;
/*数据元素类型*/
#defineEQ(a,b)((a)==(b))
inthashsize[]={11,19,29,37};
/*哈希表容量递增表,一个合适的素数序列*/
intm=0;
/*哈希表表长,全局变量*/
ElemType*elem;
/*数据元素存储基址,动态分配数组*/
intcount;
/*当前数据元素个数*/
intsizeindex;
/*hashsize[sizeindex]为当前容量*/
}HashTable;
#defineSUCCESS1
#defineUNSUCCESS0
#defineDUPLICATE-1
StatusInitHashTable(HashTable*H)
{/*操作结果:
构造一个空的哈希表*/
inti;
(*H).count=0;
/*当前元素个数为0*/
(*H).sizeindex=0;
/*初始存储容量为hashsize[0]*/
m=hashsize[0];
(*H).elem=(ElemType*)malloc(m*sizeof(ElemType));
(*H).elem)
exit(OVERFLOW);
/*存储分配失败*/
for(i=0;
i<
m;
i++)
(*H).elem[i].key=NULLKEY;
/*未填记录的标志*/
returnOK;
voidDestroyHashTable(HashTable*H)
{/*初始条件:
哈希表H存在。
操作结果:
销毁哈希表H*/
free((*H).elem);
(*H).elem=NULL;
unsignedHash(KeyTypeK)
{/*一个简单的哈希函数(m为表长,全局变量)*/
returnK%m;
voidcollision(int*p,intd)/*线性探测再散列*/
{/*开放定址法处理冲突*/
*p=(*p+d)%m;
StatusSearchHash(HashTableH,KeyTypeK,int*p,int*c)
{/*在开放定址哈希表H中查找关键码为K的元素,若查找成功,以p指示待查数据*/
/*元素在表中位置,并返回SUCCESS;
否则,以p指示插入位置,并返回UNSUCCESS*/
/*c用以计冲突次数,其初值置零,供建表插入时参考。
*/
*p=Hash(K);
/*求得哈希地址*/
while(H.elem[*p].key!
=NULLKEY&
EQ(K,H.elem[*p].key))
{/*该位置中填有记录.并且关键字不相等*/
(*c)++;
if(*c<
m)
collision(p,*c);
/*求得下一探查地址p*/
ifEQ(K,H.elem[*p].key)
returnSUCCESS;
/*查找成功,p返回待查数据元素位置*/
returnUNSUCCESS;
/*查找不成功(H.elem[p].key==NULLKEY),p返回的是插入位置*/
StatusInsertHash(HashTable*,ElemType);
/*对函数的声明*/
voidRecreateHashTable(HashTable*H)/*重建哈希表*/
{/*重建哈希表*/
inti,count=(*H).count;
ElemType*p,*elem=(ElemType*)malloc(count*sizeof(ElemType));
p=elem;
printf("
重建哈希表\n"
i++)/*保存原有的数据到elem中*/
if(((*H).elem+i)->
key!
=NULLKEY)/*该单元有数据*/
*p++=*((*H).elem+i);
(*H).sizeindex++;
/*增大存储容量*/
m=hashsize[(*H).sizeindex];
p=(ElemType*)realloc((*H).elem,m*sizeof(ElemType));
p)
(*H).elem=p;
/*未填记录的标志(初始化)*/
for(p=elem;
p<
elem+count;
p++)/*将原有的数据按照新的表长插入到重建的哈希表中*/
InsertHash(H,*p);
StatusInsertHash(HashTable*H,ElemTypee)
{/*查找不成功时插入数据元素e到开放定址哈希表H中,并返回OK;
*/
/*若冲突次数过大,则重建哈希表。
intc,p;
c=0;
if(SearchHash(*H,e.key,&
p,&
c))/*表中已有与e有相同关键字的元素*/
returnDUPLICATE;
elseif(c<
hashsize[(*H).sizeindex]/2)/*冲突次数c未达到上限,(c的阀值可调)*/
{/*插入e*/
(*H).elem[p]=e;
++(*H).count;
RecreateHashTable(H);
/*重建哈希表*/
returnERROR;
voidTraverseHash(HashTableH,void(*Vi)(int,ElemType))
{/*按哈希地址的顺序遍历哈希表*/
哈希地址0~%d\n"
m-1);
if(H.elem[i].key!
=NULLKEY)/*有数据*/
Vi(i,H.elem[i]);
StatusFind(HashTableH,KeyTypeK,int*p)
否则,返回UNSUCCESS*/
intc=0;
c++;
if(c<
collision(p,c);
/*查找不成功(H.elem[p].key==NULLKEY)*/
voidprint(intp,ElemTyper)
address=%d(%d,%d)\n"
p,r.key,r.ord);
voidmain()
ElemTyper[N]={{17,1},{60,2},{29,3},{38,4},{1,5},{2,6},{3,7},{4,8},{60,9},{13,10}};
HashTableh;
inti,p;
Statusj;
KeyTypek;
InitHashTable(&
h);
N-1;
{/*插入前N-1个记录*/
j=InsertHash(&
h,r[i]);
if(j==DUPLICATE)
表中已有关键字为%d的记录,无法再插入记录(%d,%d)\n"
r[i].key,r[i].key,r[i].ord);
按哈希地址的顺序遍历哈希表:
TraverseHash(h,print);
请输入待查找记录的关键字:
scanf("
%d"
k);
j=Find(h,k,&
p);
if(j==SUCCESS)
print(p,h.elem[p]);
没找到\n"
/*插入第N个记录*/
if(j==ERROR)/*重建哈希表*/
/*重建哈希表后重新插入第N个记录*/
按哈希地址的顺序遍历重建后的哈希表:
DestroyHashTable(&
3、折半查找
stdlib.h>
intSearch_Bin(intscore[],intlength,intkey)
intlow,high,mid;
low=1;
high=length;
while(low<
=high)
mid=(low+high)/2;
if(score[mid]==key)
returnmid;
elseif(key<
score[mid])
high=mid-1;
elseif(key>
low=mid+1;
intscore[11];
intlength=10;
intkey,index;
创建查找表:
for(inti=1;
=length;
scanf("
score[i]);
\n输入要查找的关键字\n"
key);
i