本章写的有点仓促,过一段时间会再次修改。
五、查找
(一)顺序查找发
/*
method:
顺序查找法
param:
data 待查找的序列
num 待查找的序列的长度
k 待查找的值
return:
返回查找到的下标,没有则返回-1
*/
int Order_Select(int data[], int num, int k)
{
for (int i = 0; i < num; ++i)
{
if (data[i] == k) //依次查找每一个元素
return i;
}
}
(二)折半查找发
/*
method:
折半查找法
param:
order_data 有序序列
low,high 查找low - high 范围内的值,low,high 有值
k 待查找的值
return:
返回查找到的下标,没有则返回-1
*/
int Bsearch(int order_data[], int low, int high, int k)
{
int mid = 0;
while (low <= high) //判断low<high
{
mid = (low + high) / 2; //mid为折半的中间下标
if (order_data[mid] == k) //将中间值与待查找值比较
return mid; //如果等于,则返回下标
else if (order_data[mid] < k) //如果待查找值大于中间值,缩小查找范围为右边一半
low = mid + 1;
else
high = mid - 1; //如果待查找值大于中间值,缩小查找范围为左边一半
}
return -1;
}
(三)分块查找法
/*
method:
分块查找之折半查找 块
param:
order_data 有序序列
low,high 查找low - high 范围内的值,low,high 有值
k 待查找的值
return:
返回查找到的下标,没有则返回-1
*/
int B_Block_Search(INDEXELEM index_elem[], int low, int high, int k)
{
int mid = 0;
while (low <= high)
{
mid = (low + high) / 2;
if (index_elem[mid].key == k) //如果与查找值相等,直接返回
return mid;
else if (high - low <= 1) //如果两个下标相差1,一定比左边块大
return high;
else if (index_elem[mid].key < k) //如果待查找值大于中间值,缩小查找范围为右边一半
low = mid;
else
high = mid; //如果待查找值大于中间值,缩小查找范围为左边一半
}
return -1;
}
/*
method:
分块查找之直接插入排序法
param:
disorder_sqc 无序序列
num 无序序列的长度
*/
int Insert_Direct(INDEXELEM index_elem[], int num)
{
int i = 0, j = 0;
INDEXELEM temp = {0}; //临时变量
for (i = 1; i < num; ++i) //i=1,默认前面已经有一个元素是有序的
{
temp = index_elem[i]; //获取当前值
j = i - 1; //获取当前下标
while (j >= 0 && temp.key < index_elem[j].key) //从当前下标往前依次判断
{
index_elem[j + 1] = index_elem[j]; //当前位置元素如果比待插入值大,往后移动一个元素,给插入值腾地方
--j;
}
index_elem[j + 1] = temp; //插入值
}
}
/*
method:
初始化块内元素
param:
index_elem 索引表结构体数组
disorder_data 无序序列
num 待查找的序列的长度
k 待查找的值
return:
返回查找到的下标,没有则返回-1
*/
int Base_Init(INDEXELEM index_elem[], int disorder_data[], int num)
{
int k = 0; //获取索引表个数,也就是分块的个数
int max = 0; //获取最大值
int block_data_num = DATA_NUM; //这里代表每块元素的个数
for (int i = 0; i < num; ++i)
{
if (max < disorder_data[i]) //实时获取最大值
max = disorder_data[i];
if (i != 0) //第一趟不判断
{
if (i % block_data_num == 0) //分隔多个块
{
index_elem[k].key = max; //获取块内最大值
index_elem[k].low = i - 4; //获取块内下标
index_elem[k].high = i - 1;
max = 0; //为了获取下一个块内的最大值
++k; //块数自增
}
else if (i == num - 1) //最后一个元素,不是每块元素个数的倍数
{
index_elem[k].key = max; //获取最值
index_elem[k].low = index_elem[k - 1].high + 1; //获取下标
index_elem[k].high = num - 1;
max = 0; //为了获取下一个块内的最大值
}
}
}
Insert_Direct(index_elem, k + 1); //快速排序,将其排成有序索引表
return k; //返回块的个数
}
/*
method:
折半查找法
param:
order_data 有序序列
low,high 查找low - high 范围内的值,low,high 有值
k 待查找的值
return:
返回查找到的下标,没有则返回-1
*/
int Block_Search(int disorder_data[],int num,int k)
{
int sub; //索引表的下标
int table_num = 0; //索引表的个数
INDEXELEM index_num[MAXSIZE] = { 0 }; //创建块
table_num = Base_Init(index_num, disorder_data,num); //创建块,并使其有序
sub = B_Block_Search(index_num, 0, table_num,k); //索引表的下标
for (int i = index_num[sub].low; i < index_num[sub].high + 1; ++i) //顺序查找
{
if (disorder_data[i] == k) //依次查找每一个元素
return i;
}
}