搜索算法实例C源码
玩转算法与数据结构之搜索算法
—HIT2000鲁天伟
搜索算法,是在计算机存储的数据中,如何高效的找到所需要的数据。下面我们要给出的就是搜索常用算法实例,供大家学习使用。
搜索算法如下:
线性搜索:整型数组int data[n],要搜索的数据是key。从左起第1个数据开始向右逐个比对,找到则返回位置值,查找游标(数组位置标识变量)越界则表示没有这个数据。线性搜索代码如下:
int linerSearch(int* data,int key,int len){
int index=0;
int counter=0;
for(index=0;index if(data[index]==key) break; } if(index printf("Found it,position in array is %d\n",index); return index; } else printf("Not found\n"); return-1; } 折半搜索:有序(按从小到大顺序排列)整型数组int data[n],要搜索的数据是key。取left游标表示数组左起始位置,取right游标表示数组的右终止位置。取mid=(left+right)/2,如果data[mid]==key返回mid值,如果data[mid]>key, right=mid-1;如果data[mid] 折半搜索代码如下: int zeBan(int*data,int key,int left,int right){ int middle; int position=-1; if(left<=right){ middle=(left+right)/2; if(key==data[middle]){ position=middle; printf("Found it,position in array is %d\n",position); } else{ if(key position=zeBan(data,key,left,middle-1); else position=zeBan(data,key,middle+1,right); } } else{ printf("Not found\n"); } return position; } 斐波那契搜索: 有序(按从小到大顺序排列)整型数组int dataF[n], 要搜索的数据是key。先根据斐波那契数列计算找出K,使FIB(K)-1>=n,K从3开始向上取值(数组中至少要有一个数据)。如果FIB(K)-1==n那么不用拓展数组,如果FIB(K)-1>n则拓展数组dataF 长度,至FIB(K)-1;多出来的位置都用原数组最后一个数据dataF[n-1]来填充。如此得到一个长为FIB(K-1)的新数组data,取游标left表示数组左起位置,取游标right表示数组右止位置。Mid=left+FIB(K-1)-1(即数组中左起第FIB(K-1)个元素,即在FIB(K)-1个元素的数组中,取左起第FIB(K-1)个数据来作为“中位数”), 除去这个Mid位置,新数组被分为两段,左面长度为FIB(K-1)-1, 因为FIB(K)=FIB(K-1)+FIB(K-2),所以右面长度为FIB(K-2)-1(这就是为什么原数组要扩展到FIB(K)-1个数,而不是其它值的原因,看下是不是形成了递归的样子FibSearch(int key,int K,int left,int right,int len)。如果data[Mid]==key,如果Mid 斐波那契搜索代码如下: #include #include #define MAX 28 int dataF[MAX]={1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41 ,43,45,47,49,51,53,55}; int*data; int Fib(int N){ if(N<=1) return N; else return Fib(N-1)+Fib(N-2); } int findK(int len){ int k=3; while(Fib(k)-1 k++; } return k; } int buildfibarray(int k,int len){ int i; int m=Fib(k); data=(int*)malloc(sizeof(int)*(m-1)); for(i=0;i data[i]=dataF[i]; while(i data[i++]=dataF[len-1]; } return m-2; } int FibSearch(int key,int left,int right,int k,int len){ int mid; int pos; if(k<3){ return-1; } else{ mid=left+Fib(k-1)-1; if(data[mid]==key){ if(mid return mid; else return len-1; } else if(data[mid]>key) return FibSearch(key,left,mid-1,k-1,len); else return FibSearch(key,mid+1,right,k-2,len); } } void main(){ int i,j,k,m,pos,right,size; k=findK(MAX); j=Fib(k); printf("k=%d Fibe(%d)=%d\n",k,k,j); right=buildfibarray(k,MAX); printf("Fib array which size=%d is:\n",MAX); for(i=0;i printf("%d ",dataF[i]); printf("\n"); size=j-1; printf("New Fib array which size=%d is:\n",size); for(i=0;i printf("%d ",data[i]); printf("\n"); for(m=1;m<=56;m++){ pos=FibSearch(m,0,right,k,MAX); if(pos==-1){ printf("%2d is not found\n",m); } else printf("%2d is found,the position in array is %d \n",m,pos); } } 插补搜索:有序(按从小到大顺序排列)整型数组int data[n],要搜索的数据是key。取游标left表示数组左起位置,取游标right表示数组右止位置。主要的思路在直角坐标系中,把数组的位置作为x值,数组位置对应的值作为y值,即根据数组的位置和值,形成(x,y)点阵,比如(0,data[0]),(1,data[1])……(n-1,data[n-1])。如此,画一条穿过(left,data[left]),(right,data[right])这两个点的直线。这条线的斜率是K=(data[right]-data[left])/(right-left),除了(left,data[left]),(right,data[right])这两个点,其它符合left 插补搜索代码如下: int chabuSearch(int* data,int key,int left,int right){ int middle; int i; int j; int p; if(left<=right){ if(left==right) middle=left; else{ middle=left+(key-data[left])*(right-left)/(data[right]-data[left]); if(middle middle=left; else if(middle>right) middle=right; } if(data[middle]==key){ printf("Found it,position in array is %d\n",middle); return middle; } else if(key p=chabuSearch(data,key,left,middle-1); else p=chabuSearch(data,key,middle+1,right); return p; } else{ printf("Not found\n"); return0; } } 增强插补搜索代码如下: int findRobust(int* data,int left,int right,int key){ int gap; int num1; int num2; int num3; gap=ceil(sqrt((float)right-(float)left+1)); num1=left+gap; num2=right-gap; num3=left+(key-data[left])*(right-left)/(data[right]-data[left]); if(num1>=num2){ if(num2>=num3) return num2; else if(num3>=num1) return num1; else if(num1>=num3 && num3>=num2) return num3; } else{ if(num3>=num2) return num2; else if(num1>=num3) return num1; else if(num2>=num3 && num3>=num1) return num3; } } int chabuRobustSearch(int*data,int key,int left,int right){ int middle; int i; int j; int p; if(left<=right){ if(left==right) middle=left; else{ middle=findRobust(data,left,right,key); if(middle middle=left; else if(middle>right) middle=right; } if(data[middle]==key){ printf("Found it,position in array is %d\n",middle); return middle; } else if(key p=chabuRobustSearch(data,key,left,middle-1); else p=chabuRobustSearch(data,key,middle+1,right); return p; } else{ printf("Not found\n"); return0; } } 二叉树搜索:整型数组int data[n],要搜索的数据是key。对数组先进行建立二叉树,二叉树根结点是data[0],左子结点数据小于等于父结点数据,右子结点数据大于父结点数据。然后二叉树中序遍历搜索这个key值。 二叉树搜索代码如下: struct tree{ struct tree * left; int data; struct tree * right; }; typedef struct tree treeNode; typedef treeNode * btree; btree insertTree(btree root,int data){ btree newNode=(btree)malloc(sizeof(treeNode)); newNode->data=data; newNode->left=NULL; newNode->right=NULL; if(root==NULL){ root=newNode; } else if(data<=root->data){ root->left=insertTree(root->left,data); } else{ root->right=insertTree(root->right,data); } return root; } btree createTree(btree root,int*nodelist,int len){ int i; for(i=0;i root=insertTree(root,nodelist[i]); } return root; } btree binarytreeSearch(btree root,int key){ btree p=NULL; if(root==NULL){ printf("Not found\n"); return NULL; } else{ if(root->data==key){ printf("Found it,address is %d\n",root); return root; } else if(key p=binarytreeSearch(root->left,key); else p=binarytreeSearch(root->right,key); return p; } } 我自己使用的环境是运用notepad++编辑,在notepad++里调用Dev-CPP里的编译和运行。具体网上有教程很简单,两个软件安装完成后,简单在计算机里配一下环境变量即可。使用graphviz软件进行数据结构图形的绘画,这个软件非常好,推荐大家使用。 当然程序在VC6.0,Tubo C,还有Win-TC中也都能正常运行。用C语言的编译运行工具都可以用上面的源代码。 源代码文件如下: search.c 2020-10-30 HIT2000 软件学院鲁天伟