二分查找
必须有前提,数组中的元素要有序
public static int halfSeach_2(int[] arr, int key) {
int min, max, mid;
min = 0;
max = arr.length - 1;
mid = (max + min) >> 1; //(max+min)/2;
while (arr[mid] != key) {
if (key > arr[mid]) {
min = mid + 1;
} else if (key < arr[mid])
max = mid - 1;
if (max < min)
return -1;
mid = (max + min) >> 1;
}
return mid;
}
冒泡排序
从小到大排序:比较相邻的元素。如果第一个比第二个大,就交换他们两个。每次遍历大的值都会沉入最后。
public static int[] bubbleSort(int[] nums) {
int temp = 0;
for (int i = 0; i < nums.length - 1; i++) {
for (int j = 0; j < nums.length - 1 - i; j++) {
if (nums[j] > nums[j + 1]) {
temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
return nums;
}
快速排序
- 基本原理
快速排序的根本可以说就是通过分治法来实现,简单举一个例子来理解一下快速排序的过程。
我们现在对(56,28,45,93,10,32,44,95,60,58)进行排序
首先我们定义三个量,i,j,flag。i是数组第一个值的下表即i=0。j是数组最后一个值的下表即j=9,flag就是数组的第一个值即flag=56,现在我们要做的就是讲这个数组中所有比flag小的数放到他的前面,把所有比flag大的数放到他的后面。
第一步从j开始向左(前)找,找到第一个比flag小的数,是下标为6的数44,我们就将44与flag56进行交换从而使数组变成(44,28,45,93,10,32,56,95,60,58),此时的j=6
第二步从i开始向右(后)找,找到第一个比flag大的数,是下标为3的数93,我们就将93与flag56进行交换从而使数组变成(44,28,45,56,10,32,93,95,60,58),此时的i=3
第三步继续从j(此时j=6)开始向左找,找到比flag小的数,是下标为5的数32,我们将32与flag进行交换,得到数组(44,28,45,32,10,56,93,95,60,58),此时j=5
第四步从i(此时i=3)开始向右找,找到比flag大的数,直到i=j,我们发现在j之前已经找不到比flag更大的数,此时快速排序的第一轮就已经结束,这个时候在flag之前的数都是比他小的,在他之后都是比他大的,我们再将flag前后两片区域重新定义成新的无序的数组,分别对他们重复刚才的过程,直到分解到每个重新划分的区域内只有一个值,排序就算完成了。我们直接将过程贴在下面
(44,28,45,32,10)(56)(93,95,60,58)
(10,28,45,32,44)(56)(58,95,60,93)
(10,28,44,32,45)(56)(58,93,60,95)
(10,28,32,44,45)(56)(58,60,93,95)
(10,28,32)(44)(45)(56)(58)(60)(93)(95)
(10)(28)(32)(44)(45)(56)(58)(60)(93)(95)
排序结束
- 稳定性问题
首先大家应该都知道快速排序是一个不稳定排序算法,那么到底什么才是排序的稳定性呢,我认为通俗的讲有两个相同的数A和B,在排序之前A在B的前面,而经过排序之后,B跑到了A的前面,对于这种情况的发生,我们管他叫做排序的不稳定性,而快速排序在对存在相同数进行排序时就有可能发生这种情况。
例如(5,3A,6,3B)对这个进行排序,排序之前相同的数3A与3B,A在B的前面,经过排序之后会变成
3B,3A,5,6),所以说快速排序是一个不稳定的排序
/**
* 快速排序
* 取第一个元素为基数,循环比较最小位置值与最大位置值,较大的往后排,较小的往前排,
* 然后并较小的位数加一,较大的位数减一,循环结果就是中间位数,
* 最后就是以中间两部分分开做递归运算再次比较排列,直到正确排序为止
*/
public static void quickSort(int[] nums, int low, int high) {
if (low < high) {
int temp = nums[low]; // 选定的基准值(第一个数值作为基准值)
int middle; // 记录临时中间值
int i = low, j = high;
do {
while ((nums[i] < temp) && (i < high)) {
i++;
}
while ((nums[j] > temp) && (j > low)) {
j--;
}
if (i <= j) {
middle = nums[i];
nums[i] = nums[j];
nums[j] = middle;
i++;
j--;
}
} while (i <= j);
if (low < j) {
quickSort(nums, low, j);
}
if (high > i) {
quickSort(nums, i, high);
}
}
}
选择排序
选择排序,每次寻找序列中的最小值,然后放在最首位的位置
/**
* 选择排序
* 从后往前排,设默认最小元素与较大位置比较,如果比最小元素大,
* 则将该位置记为最小元素,并且循环比较最小元素,找到最小元素,
* 最后将最小元素赋值最前方,
*/
public static void selectSort(int[] nums) {
int size = nums.length, temp;
for (int i = 0; i < size; i++) {
int k = i; //临时最小元素位数
for (int j = size - 1; j > i; j--) {
if (nums[j] < nums[k]) {
k = j;
}
}
temp = nums[i];
nums[i] = nums[k];
nums[k] = temp;
}
}
插入排序
基准元素相邻元素比较,较大的往后排,然后从较大的位置开始往后与基准元素比较排列
/**
* 插入排序
* 基准元素相邻元素比较,较大的往后排,然后从较大的位置开始往后与基准元素比较排列,
* 最后把最小的插入较小位
*/
public static void insertSort(int[] nums) {
int size = nums.length, temp, j;
for(int i=1; i<size; i++) {
temp = nums[i];//基准元素
for(j = i; j > 0 && temp < nums[j-1];j--) {
nums[j] = nums[j-1];
}
nums[j] = temp;
}
}