一、 实验目的
(1) 掌握顺序查找、折半查找、索引查找的算法思想;
(2) 掌握折半查找算法的实现方法;
(3) 分析折半查找成功和失败的条件;
(4) 熟练应用折半查找。
二、 实验环境
Windows 7以上版本的操作系统,Visual Studio 2010版以上编程环境。
三、 实验内容和步骤(根据ListInArray项目完成实验,已整合折半查找)
- 下面所示是在序列{ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90 }中用折半的思想查找“15”的过程,请写出查找“80”的过程。
找“80”的过程如下表所示
- 修改二分查找方法以实现上述的输出效果。
修改listinarray.cpp里的BinarySearch函数如下:
int BinarySearch(SqList L, ElemType item)
{
int count = 1;
int low = 0, high = L.length - 1, mid;
printf("查找%d的过程:\n",item);
while (low <= high) {
mid = (low + high) / 2;
printf("第%d次:在[%d--%d]之间查找,与%d比较\n",count,low,high,L.data[mid]);
if (item == L.data[mid]) //查找成功。断点①,观察本次查找区间
return mid + 1;
else if (item < L.data[mid])
high = mid - 1; //在左半子区间查找
else
low = mid + 1; //在右半子区间查找
count++;
} //断点②,观察下次查找区间
return 0;
}
- 将在上述序列中查找数据“15”、“9”、“25”、“80”的过程分别记录在下面表格中。然后在int BinarySearch(SqList L, ElemType item) 函数中设置断点,分别在断点①处观察本次查找区间,在断点②处观察下次查找区间,用“F5”调试程序,根据观察得到的数据分析查找成功和失败的条件分别是什么,并考虑如果要将“15”、“9”、 “25”三个数插入到有序表中且保持有序性不变,则插入位置应如何表示。
- 应用:根据上题的结论,利用折半查找算法在有序表中插入一个新元素,并保持表的有序性。在ListInArray项目中添加以下接口实现该功能,并在main函数中利用此方法,在顺序表中存储20个100以内的随机数,进行验证:
bool ListInsert_Binary(SqList &L, ElemType item)
【提示1】插入位置的确定
ListInArray项目中已给出的ListInsert_order函数在确定插入位置时使用的是逐个比较的方法。由于本身已经是有序表,使用折半查找确定插入位置可以提高效率。
利用折半查找算法查找待插入元素:
查找成功时:插入位置为 mid + 1
查找失败时:插入位置为 low 或 high + 1
【提示2】随机数的产生
#include <ctime>
#include <iostream>
using namespace std;
int main()
{
srand(time(0));
for (int i = 0; i < 5; i++)
cout<< 1 + rand() % 10 <<" ";
return 0;
}
bool ListInsert_Binary(SqList &L, ElemType item)函数定义如下:
bool ListInsert_Binary(SqList &L, ElemType item)
{
int i;
if (L.length >= MaxSize) //若顺序表满,则无法插入新数据
{
cout << "顺序表满,插入失败!" << endl;
return false;
}
int low = 0, high = L.length - 1, mid;
while (low <= high) {
mid = (low + high) / 2;
if (item == L.data[mid])//若item的值与 L.data[mid]相等,则只需将mid后的数据后移
{
for (i = L.length - 1; i >= mid; i--) { //mid后的数据后移
L.data[i + 1] = L.data[i];
}
L.length++;
return 1;
}
else if (item < L.data[mid])
high = mid - 1;
else
low = mid + 1;
}
for (i = L.length - 1; i >= mid; i--) {//mid后的数据后移
L.data[i + 1] = L.data[i];
}
if (item < L.data[mid]) //若item小于L.data[mid],item赋值给L.data[mid]
{
L.data[mid] = item;
L.length++;
}
if (item > L.data[mid]) //若item大于L.data[mid],item赋值给L.data[mid+1]
{
L.data[mid + 1] = item;
L.length++;
}
}
进行验证:
int main()
{
srand(time(0));
ElemType Array[] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90};
SqList my_list;
InitList(my_list);
for (int i = 0; i < 10; i++)
ListInsert(my_list, i + 1, Array[i]);
TraverseList(my_list);
for (int i = 0; i < 20; i++)
ListInsert_Binary(my_list, 1 + rand() % 100);
cout << "插入20个100以内的随机数后:"<< endl;
TraverseList(my_list);
return 0;
}
结果如下:
5. 阅读IndexSearch项目中的程序并运行,理解索引查找的过程。
程序运行结果如下: