本章寫的有點倉促,過一段時間會再次修改。
五、查找
(一)順序查找發
/*
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;
}
}