查找的概念
搜索引擎用的是静态查找
代码(静态查找and动态查找)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "SeqList.h"
#define SIZE 20
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
void print_array(int a[], int len)
{
int i = 0;
for(i=0; i<len; i++)
{
printf("%d, ", a[i]);
}
printf("\n");
}
int static_search(int a[], int len, int key)
{
int ret = -1;
int i = 0;
for(i=0; i<len; i++)
{
if( a[i] == key )
{
ret = i;
break;
}
}
return ret;
}
void print_list(SeqList* list)
{
int i = 0;
for(i=0; i<SeqList_Length(list); i++)
{
printf("%d, ", (int)SeqList_Get(list, i));
}
printf("\n");
}
int dynamic_search(SeqList* list, int key)
{
int ret = -1;
int i = 0;
for(i=0; i<SeqList_Length(list); i++)
{
if( (int)SeqList_Get(list, i) == key )
{
ret = i;
SeqList_Delete(list, i);
break;
}
}
return ret;
}
int main(int argc, char *argv[])
{
SeqList* list = SeqList_Create(SIZE);
int a[SIZE] = {0};
int i = 0;
int key = 0;
int index = 0;
srand((unsigned int)time(NULL));
for(i=0; i<SIZE; i++)
{
a[i] = rand() % 100;
SeqList_Insert(list, (SeqListNode*)(rand() % 100), i);
}
key = rand() % 100;
printf("Static Search Demo\n");
printf("Key: %d\n", key);
printf("Array: \n");
print_array(a, SIZE);
index = static_search(a, SIZE, key);
if( index >= 0 )
{
printf("Success: a[%d] = %d\n", index, a[index]);
}
else
{
printf("Failed!\n");
}
printf("Dynamic Search Demo\n");
printf("Key: %d\n", key);
printf("List: \n");
print_list(list);
index = dynamic_search(list, key);
if( index >= 0 )
{
printf("Success: list[%d] = %d\n", index, key);
}
else
{
printf("Failed!\n");
}
print_list(list);
return 0;
}
小结
顺序表和有序表查找
顺序表查找
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 20
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
void print_array(int a[], int begin, int end)
{
int i = 0;
for(i=begin; i<=end; i++)
{
printf("%d, ", a[i]);
}
printf("\n");
}
int another_search(int a[], int len, int key)
{
int ret = len;
a[0] = key;
while( a[ret] != key )
{
ret--;
}
return ret;
}
int main(int argc, char *argv[])
{
int a[SIZE + 1] = {0};
int i = 0;
int key = 0;
int index = 0;
srand((unsigned int)time(NULL));
for(i=1; i<=SIZE; i++)
{
a[i] = rand() % 100;
}
key = rand() % 100;
printf("Another Search Demo\n");
printf("Key: %d\n", key);
printf("Array: \n");
print_array(a, 1, SIZE);
index = another_search(a, SIZE, key);
if( index > 0 )
{
printf("Success: a[%d] = %d\n", index, a[index]);
}
else
{
printf("Failed!\n");
}
return 0;
}
二分查找(有序查找的一种)
插值查找
插值查找的速度比二分查找快,但是插值查找需要进行浮点数计算,因此,从稳定性上,插值不如二分查找
代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 20
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
void println(int array[],int len)
{
int i = 0;
for( i = 0;i < len; i++)
{
printf("%d ",array[i]);
}
printf("\n");
}
void swap(int array[],int i,int j)
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
void SelectionSort(int array[],int len)
{
int i = 0;
int j = 0;
int k = -1;
for(i = 0;i < len;i++)
{
k = i; //最小数值
for(j = i;j < len;j++) //最小值查找
{
if(array[j] < array[k])
{
k = j;
}
swap(array,i,k);
}
}
}
int binary_search(int a[], int low, int high, int key)
{
int ret = -1;
if(low <= high)
{
int mid = (low + high) / 2;
printf("%d\n",mid);
if(a[mid] == key)
{
ret = mid;
}
else if(key < a[mid])
{
ret = binary_search(a,low,mid-1,key);
}
else if(key > a[mid])
{
ret = binary_search(a,mid + 1,high,key);
}
}
return ret;
}
//使用循环代替了递归,
int binary_search_ex(int a[], int low, int high, int key)
{
int ret = -1;
while(low <= high)
{
int mid = (low + high) / 2;
printf("%d\n",mid);
if(a[mid] == key)
{
ret = mid;
break;
}
else if(key < a[mid])
{
//ret = binary_search(a,low,mid-1,key);
high = mid - 1;
}
else if(key > a[mid])
{
//ret = binary_search(a,mid + 1,high,key);
low = mid + 1;
}
}
return ret;
}
//插值查找法
int interpolation_search(int a[], int low, int high, int key)
{
int ret = -1;
while((low <= high)&&(a[low]<= key)&&(a[high]>=key))
{
float fx = 1.0f *(key - a[low]) / (a[high] - a[low]);
int mid = low + fx * (high - low);
printf("%d\n",mid);
if(a[mid] == key)
{
ret = mid;
break;
}
else if(key < a[mid])
{
//ret = binary_search(a,low,mid-1,key);
high = mid - 1;
}
else if(key > a[mid])
{
//ret = binary_search(a,mid + 1,high,key);
low = mid + 1;
}
}
return ret;
}
int main(int argc, char *argv[])
{
int a[SIZE] = {0};
int i = 0;
int key = 0;
int index = 0;
srand((unsigned int)time(NULL));
for(i=1; i<=SIZE; i++)
{
a[i] = rand() % 100;
}
key = rand() % 100;
printf("Binary Search Demo\n");
printf("Key: %d\n", key);
printf("Array: \n");
println(a, SIZE);
SelectionSort(a,SIZE);
//index = binary_search(a, 0, SIZE - 1, key);
//index = binary_search_ex(a, 0, SIZE - 1, key);
index = interpolation_search(a, 0, SIZE - 1, key);
if( index > 0 )
{
printf("Success: a[%d] = %d\n", index, a[index]);
}
else
{
printf("Failed!\n");
}
return 0;
}
小结
斐波那契数列
黄金比例又称黄金分割,是指事物各部分间一定的数学比例关系,即将整体一分为二,较大部分与较小部分之比等于整体与较大部分之比,其比值约为1:0.618或1.618:1。
0.618被公认为最具有审美意义的比例数字,这个数值的作用不仅仅体现在诸如绘画、雕塑、音乐、建筑等艺术领域,而且在管理、工程设计等方面也有着不可忽视的作用。因此被称为黄金分
割。
大家记不记得斐波那契数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…….(从第三个数开始,后边每一个数都是前两个数的和)
然后我们会发现,随着斐波那契数列的递增,前后两个数的比值会越来越接近0.618,利用这个特性,我们就可以将黄金比例运用到查找技术中。
代码
斐波那契查找的核心是:
1)当key=a[mid]时,查找成功;
2)当key<a[mid]时,新的查找范围是第low个到第mid-1个,此时范围个数为F[k-1] - 1个,即数组左边的长度,所以要在[low, F[k - 1] - 1]范围内查找;
3)当key>a[mid]时,新的查找范围是第mid+1个到第high个,此时范围个数为F[k-2] - 1个,即数组右边的长度,所以要在[F[k - 2] - 1]范围内查找。
线性索引查找
索引的概念
线性索引
小结
思考: