·二分查找
在一个排好序的数组中,如果采用循环遍历查找,最多需要查找N次(N = 数组长度)。
这个问题有一个很好的优化算法:二分查找。
例如:
array = {11, 22, 33, 44, 55, 66, 77, 88, 99};
查找数字22,数组长度为9,下标从0到8。
(0 + 8) / 2 = 4,看array[4]是否等于22;
a.if array[4] == 22,查找结束,结果就是下标4;
b.else if array[4] > 22,那么继续查找前半部分,即array[0]到array[3]这部分;
c.else if array[4] < 22,那么继续查找后半部分,即array[5]到array[8]这部分。
利用二分查找在一个巨大的数组中查找元素会快很多倍。
二分查找一个元素最多查找logN次(N = 数组长度,log以2为底)。
对一个10000长度的数组来说,循环遍历查找最多要10000次,二分查找最多14次。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BinarySearch
{
class Program
{
static Random random = new Random();
static int[] RandArray(int len = 10)
{
int[] array = new int[len];
for (int i = 0; i < len; i++)
{
int r = random.Next(0, 10);
array[i] = r;
}
return array;
}
static void PrintArray(int[] array)
{
for (int i = 0; i < array.Length; i++)
{
Console.Write(array[i] + " ");
}
Console.WriteLine();
}
static void BubbleSort(int[] array)
{
for (int i = 0; i < array.Length - 1; i++)
{
bool swapped = false;
for (int j = 0; j < array.Length - i - 1; j++)
{
if (array[j] > array[j + 1])
{
int box;
box = array[j];
array[j] = array[j + 1];
array[j + 1] = box;
swapped = true;
}
}
if (!swapped)
{
break;
}
}
}
//若有重复数字返回的值是随机一个
static int BinarySearch(int[] array,int num)
{
int start = 0;
int end = array.Length;
while (start < end)
{
int n = (start + end) / 2;
if (array[n] == num)
{
return n + 1;
}
else if (array[n] > num)
{
end = n;
}
else
{
start = n + 1;
}
}
return -1;
}
static void Main(string[] args)
{
int[] array = RandArray();
PrintArray(array);
BubbleSort(array);
PrintArray(array);
int num = int.Parse(Console.ReadLine());
if (BinarySearch(array, num) == -1)
{
Console.WriteLine("数组中不存在数字{0}", num);
}
else
{
Console.WriteLine("查找的数字在数组中第{0}个", BinarySearch(array, num));
}
Console.ReadLine();
}
}
}
若查找的元素在数组中有若干个,返回的值为其中随机一个。