折半查找2.docx
《折半查找2.docx》由会员分享,可在线阅读,更多相关《折半查找2.docx(13页珍藏版)》请在冰豆网上搜索。
折半查找2
【C代码】折半查找二叉排序树及哈希表(数据结构)
(2009-03-0412:
04:
22)
转载
标签:
c语言
代码
数据结构
折半查找
二分查找
二叉排序树
哈希表
it
分类:
数据结构
需求分析
本演示程序用VC++编写,完成有序表的创建、遍历、折半查找元素。
二叉排序树插入式建立、查找、删除。
线性探测法建立散列表,遍历,查找关键字。
拉链式法建立散列表,遍历,查找关键字。
P.S.本程序代码只适用于初学者,这是我的小作业,所以可读性不好,只为应付一下而已,基本功能可以实现,但是比较偏僻的数据可能会运行错误。
【代码】
#include
#include
#include
#definem10//哈希表长度
#defineLIST_INIT_SIZE100
#defineNULLKEY0
typedefintKeyType;//整型
typedefstruct{
KeyTypekey;
}Elemtype;
typedefstruct{
Elemtype*elem;
intlength;
}Sstable;
typedefstructBSTNode{
KeyTypekey;
structBSTNode*lc,*rc;
}*BSTree;
typedefstructnode{
KeyTypekey;
structnode*next;
}NODE;
NODE*HashTable1[m];
typedefstruct{
KeyTypekey;
}RecordType;
typedefRecordTypeHashTable2[m];
boolInitList_Ss(Sstable&st)
{//构造一个空的线性表st
printf("创建一个空的线性表:
\n");
st.elem=(Elemtype*)malloc(LIST_INIT_SIZE*sizeof(Elemtype));
if(!
st.elem)returnfalse;
st.length=0;
returntrue;
}//InitList_Ss
Sstable&Init_Ss(Sstable&st)
{//建立有序表
printf("建立有序表:
\n");
inti=0;
intt;
do
{
printf("请输入一个小于1000的数:
\n");
scanf("%d",&st.elem[i].key);
st.length++;
t=st.elem[i].key;
if(i>0)
{
for(intj=0;j{
if(st.elem[i].key{
for(intk=st.length-2;k>=j;k--)
{
st.elem[k+1].key=st.elem[k].key;
}
st.elem[j].key=t;
}
}
}
i++;
}while(t<1000);
st.length--;
returnst;
}//Init_Ss
voidShow(Sstable&st)
{//遍历有序表
printf("遍历有序表:
\n");
if(st.length==0)
printf("有序表为空\n");
for(inti=0;i{
printf("%5d",st.elem[i].key);
}
printf("\n");
}//Show
intbin_search(Sstablest,KeyTypek)
{//折半查找
intlow=0,hig=st.length,mid;
while(low<=hig)
{
mid=(low+hig)/2;//取区间中点
if(st.elem[mid].key==k)
return(mid+1);//查找成功
if(st.elem[mid].key>k)
hig=mid-1;//在左子区间查找
else
low=mid+1;//在右子区间查找
}
return0;
}//bin_search
voidInsertBST(BSTree*bst,KeyTypekey)
//若在二叉排序树中不存在关键字等于key的元素,插入该元素
{
BSTrees;
if(*bst==NULL)//递归结束条件
{
s=(BSTree)malloc(sizeof(BSTNode));//申请新的结点s
s->key=key;
s->lc=NULL;
s->rc=NULL;
*bst=s;
}
elseif(key<(*bst)->key)
InsertBST(&((*bst)->lc),key);//将s插入左子树
elseif(key>(*bst)->key)
InsertBST(&((*bst)->rc),key);//将s插入右子树
}//InsertBST
voidCreateBST(BSTree*bst)
//从键盘输入元素的值,创建相应的二叉排序树
{
printf("建立二叉排序树:
\n");
KeyTypekey;
*bst=NULL;
scanf("%d",&key);
while(key<10000)
{
InsertBST(bst,key);
scanf("%d",&key);
}
printf("二叉排序树建立成功\n");
}//CreateBST
BSTreesearch(KeyTypek,BSTreeroot)
{
BSTreep=root;
while(p!
=NULL)
{
if(p->key==k)returnp;//查找成功
elseif(p->key>k)p=p->lc;//进入左子树查找
elseif(p->keyrc;//进入右子树查找
}
returnNULL;
}//search
BSTNode*DelBST(BSTreet,KeyTypek)//在二叉排序树t中删去关键字为k的结点
{
BSTNode*p,*f,*s,*q;
p=t;
f=NULL;
while(p)//查找关键字为k的待删结点p
{
if(p->key==k)break;//找到,则跳出查找循环
f=p;//f指向p结点的双亲结点
if(p->key>k)p=p->lc;
elsep=p->rc;
}
if(p==NULL)
{
printf("结点不存在,删除失败\n");
returnt;//若找不到,返回原来的二叉排序树
}
if(p->lc==NULL)//p无左子树
{
if(f==NULL)t=p->rc;//p是原二叉排序树的根
elseif(f->lc==p)//p是f的左孩子
f->lc=p->rc;//将p的右子树链到f的左链上
else//p是f的右孩子
f->rc=p->rc;//将p的右子树链到f的右链上
free(p);//释放被删除的结点p
}
else//p有左子树
{
q=p;
s=p->lc;
while(s->rc)//在p的左子树中查找最右下结点
{
q=s;
s=s->rc;
}
if(q==p)q->lc=s->lc;//将s的左子树链到q上
elseq->rc=s->lc;
p->key=s->key;//将s的值赋给p
free(s);
}
printf("删除成功\n");
returnt;
}//DelBST
intHash(KeyTypek)
{
return(k%m);
}
voidCreateHash1()
{
inta,p;
NODE*q,*q1;
for(inti=0;i{
HashTable1[i]=NULL;
}
for(i=0;i{
s1:
printf("请输入一个大于零的整数:
\n");
scanf("%d",&a);
if(a<=0)
{
printf("输入错误。
\n");
gotos1;
}
p=Hash(a);
if(HashTable1[p]==NULL)//不冲突
{
HashTable1[p]=(NODE*)malloc(sizeof(NODE));
HashTable1[p]->key=a;
HashTable1[p]->next=NULL;
}
else
{
q=HashTable1[p];
while(q->next!
=NULL)
{
q=q->next;
}
q1=(NODE*)malloc(sizeof(NODE));
q1->key=a;
q1->next=NULL;
q->next=q1;
}
}
printf("散列表为:
\n");
for(i=0;i{
q=HashTable1[i];
while(q!
=NULL)
{
printf("%5d",q->key);
q=q->next;
}
printf("\n");
}
}
intHashSearch1(KeyTypeK)
{
intp0;
NODE*q;
p0=Hash(K);
if(HashTable1[p0]==NULL)return(-1);
elseif(HashTable1[p0]->key==K)return(p0);
else
{
q=HashTable1[p0];
while(q->key!
=K&&q!
=NULL)
{
q=q->next;
}
if(q==NULL)return(-1);
elseif(q->key==K)
return(p0);
}
}
intHashSearch2(HashTable2ht,KeyTypeK)
{
intp0,pi;
p0=Hash(K);
if(ht[p0].key==NULLKEY)return(-1);
elseif(ht[p0].key==K)return(p0);
else//用线性探测再散列解决冲突
{
for(inti=1;i<=m-1;i++)
{
pi=(p0+i)%m;
if(ht[pi].key==NULLKEY)return(-1);
elseif(ht[pi].key==K)return(pi);
}
return(-1);
}
}
voidCreateHash2(HashTable2ht)
{
inta,p;
for(inti=0;i{
ht[i].key=0;
}
for(i=0;i{
s2:
printf("请输入一个大于零的整数:
\n");
scanf("%d",&a);
if(a<=0)
{
printf("输入错误。
\n");
gotos2;
}
p=Hash(a);
if(ht[p].key==0)//不冲突
{
ht[p].key=a;
}
else//冲突
{
for(intj=1;j{
if(ht[p+j].key==0)
{
ht[p+j].key=a;
break;
}
}
if(j==m-p)
{
for(j=0;j
{
if(ht[j].key==0)
{
ht[j].key=a;
break;
}
}
}
}
}
printf("散列表为:
\n");
for(i=0;i{
printf("%5d",ht[i].key);
}
printf("\n");
}
voidMenu()
{
printf("*****************************************\n");
printf("1————————————建立有序表\n");
printf("2————————————折半查找\n");
printf("3————————————建立二叉排序树\n");
printf("4————————————二叉排序树查找\n");
printf("5————————————二叉排序树删除\n");
printf("6————————————查找关键字(线性探测)\n");
printf("7————————————查找散列表(链式)\n");
printf("0————————————退出\n");
printf("*****************************************\n");
}
voidmain()
{
Sstablest;//有序表
KeyTypek;//查找关键字
BSTreeT;//二叉排序树
HashTable2ht;//线性探测散列表
intx,a,b,n;//x为折半查找的返回位置,a为线性探测查找返回的位置,b为链式查找返回的位置,n为菜单选择
boolf1=false,f2=false;//f1判断有序表是否创建,f2判断二叉排序树是否创建
Menu();
scanf("%d",&n);
while(n!
=0)
{
switch(n)
{
case1:
{
if(InitList_Ss(st))
{
f1=true;
st=Init_Ss(st);
Show(st);
}
else
printf("创建失败\n");
break;
}
case2:
{
printf("折半查找:
\n");
if(f1==true)
{
scanf("%d",&k);
x=bin_search(st,k);
if(x!
=0)
printf("查找成功,位置为%d\n",x);
else
printf("查找失败\n");
}
else
printf("有序表不存在\n");
break;
}
case3:
{
printf("建立二叉排序树,输入大于等于10000则退出输入:
\n");
CreateBST(&T);
f2=true;
break;
}
case4:
{
if(f2==true)
{
printf("请输入查找的关键字:
\n");
scanf("%d",&k);
if(search(k,T)!
=NULL)
printf("查找成功。
\n");
else
printf("查找失败。
\n");
}
else
printf("二叉排序树不存在\n");
break;
}
case5:
{
if(f2==true)
{
printf("请输入删除的关键字:
\n");
scanf("%d",&k);
T=DelBST(T,k);
}
else
printf("二叉排序树不存在\n");
break;
}
case6:
{
CreateHash2(ht);
printf("输入查找的数字:
\n");
scanf("%d",&k);
a=HashSearch2(ht,k);
printf("找到位置:
%d\n",a+1);
break;
}
case7:
{
CreateHash1();
printf("输入查找的数字:
\n");
scanf("%d",&k);
b=HashSearch1(k);
printf("找到位置:
%d\n",b);
break;
}
default:
printf("输入错误\n");
}
Menu();
scanf("%d",&n);
}
}