• C++ 二分查找 哈希查找 数据结构


    一.   二分查找

    首先我们了解一下二分查找的思想

    条件:

    在一个有序数组中 

    首先设置标记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;  

    1. if (target == arr[mid])
    2. {
    3. return mid;
    4. }
    5. else if (target < arr[mid])
    6. {
    7. end = mid - 1;
    8. mid = (end + begin) / 2;
    9. }
    10. else if (target > arr[mid])
    11. {
    12. begin = mid + 1;
    13. mid = (end + begin) / 2;
    14. }

    二分查找完整代码如下

    1. #include
    2. using namespace std;
    3. int BinarySerch(int arr[],int nLen,int target)
    4. {
    5. if (arr == NULL || nLen <= 1)
    6. return -1;
    7. int begin = 0;
    8. int end = nLen-1;
    9. int mid = (end + begin) / 2;
    10. while (begin <= end)
    11. {
    12. if (target == arr[mid])
    13. {
    14. return mid;
    15. }
    16. else if (target < arr[mid])
    17. {
    18. end = mid - 1;
    19. mid = (end + begin) / 2;
    20. }
    21. else if (target > arr[mid])
    22. {
    23. begin = mid + 1;
    24. mid = (end + begin) / 2;
    25. }
    26. }
    27. return -1;
    28. }
    29. int main()
    30. {
    31. int arr[10] = {1,2,3,4,5,6,7,8,9 };
    32. cout<<BinarySerch(arr, 9,5);
    33. return 0;
    34. }

    二.   哈希查找

    在编写哈希查找之前  我们先来了解哈希表

    哈希表会把所得到的元素分类   每一个种类的数据们构成一个元素  一个元素可以包含多个数据

    例如

    余数相同的数被存放在一个元素中 

    怎么实现多个数据存放在一个元素中呢?

    这里我们用到了链式存储法:

    可以视为哈希数组中每一个元素都是一个链表的头   这些链表共同组成了哈希数组

    哈希数组是一个指针数组

    首先定义哈希表结构体

    1. struct Hash
    2. {
    3. int nIndex;//元素下标
    4. int niD;//元素得值
    5. Hash* pNext;//元素的下一个
    6. };

    这里我们实现了一个函数用来将元素放入哈希表  然后返回该哈希表

    1. Hash** CreatHashTable(int arr[], int nLen)
    2. {
    3. if (arr == NULL || nLen <= 1)
    4. {
    5. return nullptr;
    6. }
    7. Hash** HashArr = new Hash * [nLen];//创建一个哈希数组
    8. ::memset(HashArr, 0, sizeof(Hash*)*nLen);//每一项都赋值为0
    9. for (int i = 0; i < nLen; i++)
    10. {
    11. 判断当前arr[i]元素在HashArr数组中的下表为几
    12. int nKey = arr[i] % nLen;
    13. //创建新节点
    14. Hash* pTemp = new Hash;
    15. pTemp->niD = arr[i];
    16. pTemp->nIndex = i;
    17. pTemp->pNext = NULL;
    18. //往当前元素的链表上放
    19. if (HashArr[nKey] == 0)
    20. {
    21. HashArr[nKey] = pTemp;
    22. }
    23. else
    24. {
    25. pTemp->pNext = HashArr[nKey];
    26. HashArr[nKey] =pTemp ;
    27. }
    28. }
    29. return HashArr;
    30. }

    然后开始编写我们的哈希查找

    1. int HashSerch(Hash**HashArr,int nLen,int Value)
    2. {
    3. //将哈希数组传进来
    4. //参数校验
    5. if (HashArr == NULL || nLen <= 1)
    6. {
    7. return -1;
    8. }
    9. //判断要找的Value在哪个下标的元素中
    10. int mark = Value % nLen;
    11. for (int i = 0; i < nLen; i ++ )
    12. {
    13. if (i == mark)
    14. {
    15. Hash* pMark= HashArr[i];
    16. //定义标记用来遍历链表
    17. while (pMark)
    18. {
    19. if (pMark->niD == Value)
    20. {
    21. //找到了 返回下标
    22. return pMark->nIndex;
    23. }
    24. pMark = pMark->pNext;
    25. }
    26. }
    27. }
    28. //遍历结束 没找到
    29. return -1;
    30. }

    哈希查找完整代码如下

    1. #include
    2. using namespace std;
    3. struct Hash
    4. {
    5. int nIndex;
    6. int niD;
    7. Hash* pNext;
    8. };
    9. Hash** CreatHashTable(int arr[], int nLen)
    10. {
    11. if (arr == NULL || nLen <= 1)
    12. {
    13. return nullptr;
    14. }
    15. Hash** HashArr = new Hash * [nLen];
    16. ::memset(HashArr, 0, sizeof(Hash*)*nLen);
    17. for (int i = 0; i < nLen; i++)
    18. {
    19. int nKey = arr[i] % nLen;
    20. Hash* pTemp = new Hash;
    21. pTemp->niD = arr[i];
    22. pTemp->nIndex = i;
    23. pTemp->pNext = NULL;
    24. if (HashArr[nKey] == 0)
    25. {
    26. HashArr[nKey] = pTemp;
    27. }
    28. else
    29. {
    30. pTemp->pNext = HashArr[nKey];
    31. HashArr[nKey] =pTemp ;
    32. }
    33. }
    34. return HashArr;
    35. }
    36. int HashSerch(Hash**HashArr,int nLen,int Value)
    37. {
    38. if (HashArr == NULL || nLen <= 1)
    39. {
    40. return -1;
    41. }
    42. int mark = Value % nLen;
    43. for (int i = 0; i < nLen; i ++ )
    44. {
    45. if (i == mark)
    46. {
    47. Hash* pMark= HashArr[i];
    48. while (pMark)
    49. {
    50. if (pMark->niD == Value)
    51. {
    52. return pMark->nIndex;
    53. }
    54. pMark = pMark->pNext;
    55. }
    56. }
    57. }
    58. return -1;
    59. }
    60. int main()
    61. {
    62. int arr[10] = { 0,10,2,30,4,5,6,1024,8,9 };
    63. Hash** pArr = CreatHashTable(arr, 10);
    64. cout<<HashSerch(pArr,10,1024);
    65. return 0;
    66. }

  • 相关阅读:
    【哲思与实战】计算机寓言
    Linux服务器(银河麒麟、CentOS 7+、CentOS 7+ 等)修改IP地址
    python使用技巧(三十):python保存本地npy与C++调用npy
    【百度地图】绘制扇形图层
    记一次生产频繁发生FullGC问题
    美SEC主席最新表态:PoS代币可能是证券
    短视频矩阵系统/pc、小程序版独立原发源码开发搭建上线
    torch.cuda.is_available() 解决方案
    期货开户加1分象征性收取
    动环监控设备维护与故障处理,动环监控系统调试
  • 原文地址:https://blog.csdn.net/van9527/article/details/126161087