一. 二分查找
首先我们了解一下二分查找的思想
条件:
在一个有序数组中
首先设置标记begin和end
分别记录数组的首元素和最后元素的下标
标记mid为中间值 mid的左边的元素都小于mid mid右边的元素都大于mid
判断我们要找的值Target和arr[mid]相比
1:等于 直接返回下标mid
2.小于: 在mid的左边继续寻找 end被赋予mid-1; mid重新变成(end + begin) / 2; 成为新的中间值
继续循环
3.大于: 在mid的右边继续寻找 begin被赋予mid+1; mid重新变成(end + begin) / 2; 成为新的中间值
继续循环
知道begin>end 所有元素都找完了 还没找到 返回-1;
if (target == arr[mid])
{
return mid;
}
else if (target < arr[mid])
{
end = mid - 1;
mid = (end + begin) / 2;
}
else if (target > arr[mid])
{
begin = mid + 1;
mid = (end + begin) / 2;
}
二分查找完整代码如下
#include
using namespace std;
int BinarySerch(int arr[],int nLen,int target)
{
if (arr == NULL || nLen <= 1)
return -1;
int begin = 0;
int end = nLen-1;
int mid = (end + begin) / 2;
while (begin <= end)
{
if (target == arr[mid])
{
return mid;
}
else if (target < arr[mid])
{
end = mid - 1;
mid = (end + begin) / 2;
}
else if (target > arr[mid])
{
begin = mid + 1;
mid = (end + begin) / 2;
}
}
return -1;
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9 };
cout<
二. 哈希查找
在编写哈希查找之前 我们先来了解哈希表
哈希表会把所得到的元素分类 每一个种类的数据们构成一个元素 一个元素可以包含多个数据
例如
余数相同的数被存放在一个元素中
怎么实现多个数据存放在一个元素中呢?
这里我们用到了链式存储法:
可以视为哈希数组中每一个元素都是一个链表的头 这些链表共同组成了哈希数组
哈希数组是一个指针数组
首先定义哈希表结构体
struct Hash
{
int nIndex;//元素下标
int niD;//元素得值
Hash* pNext;//元素的下一个
};
这里我们实现了一个函数用来将元素放入哈希表 然后返回该哈希表
Hash** CreatHashTable(int arr[], int nLen)
{
if (arr == NULL || nLen <= 1)
{
return nullptr;
}
Hash** HashArr = new Hash * [nLen];//创建一个哈希数组
::memset(HashArr, 0, sizeof(Hash*)*nLen);//每一项都赋值为0
for (int i = 0; i < nLen; i++)
{
判断当前arr[i]元素在HashArr数组中的下表为几
int nKey = arr[i] % nLen;
//创建新节点
Hash* pTemp = new Hash;
pTemp->niD = arr[i];
pTemp->nIndex = i;
pTemp->pNext = NULL;
//往当前元素的链表上放
if (HashArr[nKey] == 0)
{
HashArr[nKey] = pTemp;
}
else
{
pTemp->pNext = HashArr[nKey];
HashArr[nKey] =pTemp ;
}
}
return HashArr;
}
然后开始编写我们的哈希查找
int HashSerch(Hash**HashArr,int nLen,int Value)
{
//将哈希数组传进来
//参数校验
if (HashArr == NULL || nLen <= 1)
{
return -1;
}
//判断要找的Value在哪个下标的元素中
int mark = Value % nLen;
for (int i = 0; i < nLen; i ++ )
{
if (i == mark)
{
Hash* pMark= HashArr[i];
//定义标记用来遍历链表
while (pMark)
{
if (pMark->niD == Value)
{
//找到了 返回下标
return pMark->nIndex;
}
pMark = pMark->pNext;
}
}
}
//遍历结束 没找到
return -1;
}
哈希查找完整代码如下
#include
using namespace std;
struct Hash
{
int nIndex;
int niD;
Hash* pNext;
};
Hash** CreatHashTable(int arr[], int nLen)
{
if (arr == NULL || nLen <= 1)
{
return nullptr;
}
Hash** HashArr = new Hash * [nLen];
::memset(HashArr, 0, sizeof(Hash*)*nLen);
for (int i = 0; i < nLen; i++)
{
int nKey = arr[i] % nLen;
Hash* pTemp = new Hash;
pTemp->niD = arr[i];
pTemp->nIndex = i;
pTemp->pNext = NULL;
if (HashArr[nKey] == 0)
{
HashArr[nKey] = pTemp;
}
else
{
pTemp->pNext = HashArr[nKey];
HashArr[nKey] =pTemp ;
}
}
return HashArr;
}
int HashSerch(Hash**HashArr,int nLen,int Value)
{
if (HashArr == NULL || nLen <= 1)
{
return -1;
}
int mark = Value % nLen;
for (int i = 0; i < nLen; i ++ )
{
if (i == mark)
{
Hash* pMark= HashArr[i];
while (pMark)
{
if (pMark->niD == Value)
{
return pMark->nIndex;
}
pMark = pMark->pNext;
}
}
}
return -1;
}
int main()
{
int arr[10] = { 0,10,2,30,4,5,6,1024,8,9 };
Hash** pArr = CreatHashTable(arr, 10);
cout<