算法思想:
初始条件:
查找集合为整个有序表,通过查找不断缩小查找集合。
取有序表的中间记录作为比较对象,则
(1)若给定值与中间记录的关键码相等,则查找成功。
(2)若给定值小于中间记录的关键码,则在中间区域的左半区查找。
(3)若给定值大于中间记录的关键码,则在中间区域的的右半去查找。
不断重复上述过程,直到查找成功或查找失败(整个查找集合无记录)。
#include <stdio.h>
#include <string.h>
//折半查找递归算法
int BinSearchOne(char szChar[], int nLowerBound, int nUpperBound, char nSearchElement)
{
//int nIndex = (nUpperBound + nLowerBound - 1) / 2; (1 + 1 - 1) / 2 = 0 栈溢出
int nIndex = (nUpperBound + nLowerBound + 1) / 2;
char nMiddleElement = szChar[nIndex]; //取有序表的中间记录
//2.递归过程处理
if (nLowerBound > nUpperBound) //查找失败,最后结束递归(整个查找集合中没有该元素)
{
return -1;
}
else
{
//1.一个查找集合的处理过程
if (nSearchElement < nMiddleElement)
{
//缩小查找集合
nUpperBound = nIndex - 1;
return BinSearchOne(szChar, nLowerBound, nUpperBound, nSearchElement); //必须使用此种方式返回主调函数的栈帧
}
else if (nSearchElement > nMiddleElement)
{
//缩小查找集合
nLowerBound = nIndex + 1;
return BinSearchOne(szChar, nLowerBound, nUpperBound, nSearchElement);
}
else
{
return nIndex; //查找成功,提前结束递归
}
}
}
//折半查找非递归算法
int BinSearchTwo(char szChar[], int nLowerBound, int nUpperBound, char nSearchElement)
{
int nIndex = -1;
char nMiddleElement = -1; //取有序表的中间记录
//循环处理过程
while (nLowerBound <= nUpperBound) //查找过程无需回退,一往无前
{
//1.第一个查找集合的处理过程
nIndex = (nUpperBound + nLowerBound + 1) / 2;
nMiddleElement = szChar[nIndex];
if (nSearchElement < nMiddleElement)
{
//缩小查找集合
nUpperBound = nIndex - 1;
continue;
}
else if (nSearchElement > nMiddleElement)
{
//缩小查找集合
nLowerBound = nIndex + 1;
continue;
}
else
{
return nIndex; //查找成功
}
}
return -1;
}
int main()
{
char szChar[] = "abcdefg";
int nResult = -1;
printf("****折半查找递归算法****\n");
for (unsigned int i = 0; i <= strlen(szChar); i++)
{
nResult = BinSearchOne(szChar, 0, strlen(szChar) - 1, i + 'a');
if (nResult == -1)
{
printf("顺序表中不存在元素:%c.\n", i + 'a');
}
else
{
printf("元素:%c 在顺序表中的下标:%d.\n", i + 'a', nResult);
}
}
printf("\n****折半查找非递归算法****\n");
for (i = 0; i <= strlen(szChar); i++)
{
nResult = BinSearchTwo(szChar, 0, strlen(szChar) - 1, i + 'a');
if (nResult == -1)
{
printf("顺序表中不存在元素:%c.\n", i + 'a');
}
else
{
printf("元素:%c 在顺序表中的下标:%d.\n", i + 'a', nResult);
}
}
return 0;
}
运行结果: