不管我们做什么开发,了解一些常用的算法和数据结构能够增强我们对程序设计的理解,对我们的开发大有裨益的。今天我来总结一下我们在日常开发过程中比较常用的算法。
1.二分查找法:
假设存在一个数组存储了由小到大的100个数,我们想要找到我们的存在的那个数。怎么办呢?有些人想到的第一种方法应该循环遍历,如果相等就找到,跳出循环。如果是1万,甚至1亿个数呢,而我们恰巧找到的那个数,正好在最后一个,我们岂不是要遍历1万次,1亿次,显然是不可取的。
下面我们就来介绍二分查找法的实现,每次取序列的中间数,如果与我们要查找的数相等就返回,如果中间数大于我们的数,我们就从前半段开始查找,如果中间数大于我们的数我们就从后半段查找。直到我们找到为止。
二分查找的Java实现:
public int binarySearch(int key, int[] array) {
int low = 0;
int high = array.length - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (key < array[mid]) {
high = mid - 1;
} else if (key > array[mid]) {
low = mid + 1;
} else {
return mid;
}
}
return -1;
}
2.选择排序
选择排序是一种简单直观的排序算法。每一次从待排序的序列中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。
例如一个无序数列:8,6,19,10,15我们想要给它按从小到大排序。
第一次我们从头往后遍历选择最小的6,放在序列的第一个位置。
然后我们从剩余8,19,10,15中选择最小的8放在第二个位置,以此类推。
直到排序完成。
选择排序的Java实现:
public void selectSort(int[] array) {
int N = array.length;
for (int i = 0; i < N; i++) {
//最小元素的索引
int min = i;
for (int j = i + 1; j < N; j++) {
if (array[j] < array[min]) {
min = j;
}
}
if (min != i) {
int temp = array[i];
array[i] = array[min];
array[min] = temp;
}
}
}
3.插入排序
假设有一组无序数列 8,6,4,10,3 。我们从左往右看先看第一个数8,当只有1个8时,它就是一个有序数列,下面我们在拿第二个数,拿它和8比较,发现它比8小,我们就把他放在8的前面这样我们就得出一个有序的6,8。然后我们在拿4从后往前一次与有序数列的值作比较,直到找到比他小的数(找不到就把它作为最小的数放在有序数列的第一位)。以此类推,每经过一轮的比较插入,有序数列的值就多一位,无序数列的值就少一位。
下面我们来看看插入排序的Java实现:
public void insertSort(int[] array) {
//数组的大小
int N = array.length;
//从1开始,因为数组的第一个数,肯定是有序的。
for (int i = 1; i < N; i++) {
int temp = array[i];
int leftIndex = i - 1;
//从右往左依次比较直到找到比他小的数
while (leftIndex >= 0 && array[leftIndex] > temp) {
array[leftIndex + 1] = array[leftIndex];
leftIndex--;
}
array[leftIndex + 1] = temp;
}
}
4.冒泡排序
假设一组无序数列 8,6,19,10,15。我们从头开始依次比较相邻的两个数,发现8比6大我们交换两个数的位置。数列变成6,8,19,10,15。我们在比较8和19,19比8大位置不动,我们在拿10根19比较,10比19小,交换位置,序列变成8,6,10,19,15,我们在拿15和19比较,15小于19,交换位置。第一轮排序结束,序列中最大的数19被排在了数列的最后。每轮排序结束剔除最后的数,重复上面的步骤,每结束一轮排序,都会在现有数列中找出最大的放在最后。直到没有任何一对数需要比较,排序完成。
Java中冒泡排序的实现:
//冒泡排序
public void bubbleSort(int[] array) {
int N = array.length;
for (int k = N - 1; k >= 0; k--) {
for (int i = 0; i < k; i++) {
if (array[i] > array[i + 1]) {
int temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
}
}
}
}
5.快速排序
假设有一个无序数列。快速排序是找出一个元素作为基准,然后对数列进行
分区操作,是基准左边元素的值都小于基准元素,基准元素右边的值都大于基准元素。然后在对基准元素左边的元素,和右边的元素重复上面的分区操作。直到序列不能再分区为止。
快速排序的代码实现:
public void sort(int[] a, int low, int high) {
int start = low;
int end = high;
int key = a[low];
while (end > start) {
//从后往前比较
while (end > start && a[end] >= key) {
//如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置
end--;
}
int temp = a[end];
a[end] = a[start];
a[start] = temp;
//从前往后比较
while (end > start && a[start] <= key) {
//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置;
start++;
}
int temp1 = a[start];
a[start] = a[end];
a[end] = temp1;
}
//递归
if (start > low) sort(a, low, start - 1);//基准数的左边序列。
if (end < high) sort(a, end + 1, high);/基准数的右边序列。
}