二分查找法:

首先有三个变量,数组的头部索引(l),数组的尾部索引(r),数组的中间比较值(mid),也是索引。 现在要查找的值(targat),然后比较 mid ,小,就在 l mid减1的区间在进行比较,然后一直推到找到为止,或者 r 右边的索引比 l 左边的索引小,那查找的条件就不成立了。大的话,同样的道理。 详情如下图:

image.png

顺序查找法与二分查找法之间的性能对比

二分查找虽然比顺序查找的效率高数倍,但它,仅仅只是对于有序数组的高效查找法。 这也是为什么执行 Array.Sort(); //将传进来的数组元素进行排序

  1. class TestSearch
  2. {
  3. //读取名为filename的文件并将数据存储到数组中返回
  4. public static int[] ReadFile(string filename)
  5. {
  6. //通过某种方式打开 filename 文件
  7. FileStream fs = new FileStream(filename, FileMode.Open);
  8. //打开文件后,通过某种方式,进行读写
  9. StreamReader sr = new StreamReader(fs);
  10. //实例话一个整数类型的泛型对象
  11. List<int> list = new List<int>();
  12. //判断是否读写结束
  13. while (!sr.EndOfStream)
  14. {
  15. //由于读写的数据类型是 string ,所以需要转换为 int 类型
  16. int num = int.Parse(sr.ReadLine());
  17. //然后,添加在整数类型的泛型数组
  18. list.Add(num);
  19. }
  20. //关闭 filename 文件
  21. fs.Close();
  22. //不在读写文件
  23. sr.Close();
  24. //toArray():将 list 数组 复制到新的数组
  25. //返回值的就是,list 的数组元素
  26. return list.ToArray();
  27. }
  28. //顺序查找法
  29. public static int OrderSearch(int[] arr, int target)
  30. {
  31. for (int i = 0; i < arr.Length; i++)
  32. if (arr[i] == target)
  33. return i;
  34. return -1;
  35. }
  36. /// <summary>
  37. /// 二分查找,在有序数组arr中,查找target
  38. ///如果找到target,返回相应的索引index
  39. ///如果没有找到target,返回-1
  40. /// </summary>
  41. /// <param name="arr">数组</param>
  42. /// <param name="target">想查找的值</param>
  43. public static int BinarySearch(int[] arr, int target)
  44. {
  45. int l = 0; //代表数组头部的索引
  46. int r = arr.Length - 1; //代表数组尾部的索引
  47. while (l <= r)
  48. {
  49. //中间值
  50. //用于比较 target《查找的值》是中间值的左边还是右边
  51. int mid = l + (r - l) / 2;
  52. if (target < arr[mid])
  53. r = mid - 1;
  54. else if (target > arr[mid])
  55. l = mid + 1;
  56. else
  57. return mid;
  58. }
  59. return -1;
  60. }
  61. }
  62. //===================================================================//
  63. class Program
  64. {
  65. private static void Main(string[] args)
  66. {
  67. string filename3 = "测试文件2/游戏会员表.txt";
  68. string filename4 = "测试文件2/游戏用户表.txt";
  69. int[] arr3 = TestSearch.ReadFile(filename3);
  70. int[] arr4 = TestSearch.ReadFile(filename4);
  71. Console.WriteLine("游戏会员数量 :" + arr3.Length);
  72. Console.WriteLine("调查用户数量 :" + arr4.Length);
  73. Console.WriteLine();
  74. Stopwatch t3 = new Stopwatch();
  75. Stopwatch t4 = new Stopwatch();
  76. Console.WriteLine("顺序查找法");
  77. t3.Start();
  78. int sum3 = 0;
  79. for (int i = 0; i < arr4.Length; i++)
  80. {
  81. int target = arr4[i];
  82. if (TestSearch.OrderSearch(arr3, target) == -1)
  83. {
  84. //Console.WriteLine(target);
  85. sum3++;
  86. }
  87. }
  88. t3.Stop();
  89. Console.WriteLine("查找到 :" + sum3 + "个零充玩家");
  90. Console.WriteLine("运行时间: " + t3.ElapsedMilliseconds + "ms");
  91. Console.WriteLine();
  92. Console.WriteLine("二分查找法");
  93. t4.Start();
  94. Array.Sort(arr3);
  95. int sum4 = 0;
  96. for (int i = 0; i < arr4.Length; i++)
  97. {
  98. int target = arr4[i];
  99. if (TestSearch.BinarySearch(arr3, target) == -1)
  100. {
  101. //Console.WriteLine(target);
  102. sum4++;
  103. }
  104. }
  105. t4.Stop();
  106. Console.WriteLine("查找到 :" + sum4 + "个零充玩家");
  107. Console.WriteLine("运行时间: " + t4.ElapsedMilliseconds + "ms");
  108. Console.ReadKey();
  109. }
  110. }

运行结果:

image.png