/**
* 冒泡排序
* 思路:1. 从0下标开始依次比较相邻两个元素大小,交换位置,最后最值出现在数组最后一位;
* 2. 遍历数组重复上述操作
* @param arr
* @return
*/
public static int[] bubbleSort(int[] arr) {
if (arr.length == 0 || arr.length == 1) {
return arr;
}
for (int j = 0; j < arr.length; j++) {
for (int i = 0; i < arr.length - 1; i++) {
int temp;
if(arr[i] > arr[i+1]){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
}
return arr;
}
/**
* 选择排序
* 思路:1. 引入游标记录当前索引的数值,拿后面所有数比较,就交换位置
* 2. 游标+1,历数组重复上述操作
* @param arr
* @return
*/
public static int[] selectionSort(int[] arr) {
if (arr.length == 0 || arr.length == 1) {
return arr;
}
for (int i = 0; i < arr.length; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
int temp;
if(arr[j] < arr[minIndex]){
temp = arr[j];
arr[j] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
return arr;
}
/**
* 插入排序
* 思路:1. 将数组分为有序子数组和无序子数组,有序子数组的尾是无序子数组的头
* 2. 无序子数组头部拿出一个数,在有序子数组中从后往前两两冒泡比较,找到对应的位置(数组依旧有序,或者说前面的数都小于这个数),交换位置
* 3. 遍历数组,重复以上操作
*
* @param arr
* @return arr
*/
public static int[] insertionSort(int[] arr) {
if (arr.length == 0 || arr.length == 1) {
return arr;
}
int temp;
for (int i = 1; i < arr.length ; i++) {
for (int j = i; j >1; j--) {
if(arr[j] < arr[j-1]){
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
}
}
return arr;
}
/**
* 希尔排序
* 思路:查入排序的优化;插入排序一个一个数增加拓展有序数组,希尔排序引进增量,对由增量构成的子数组进行插值排序,减小增量,重复上述操作,增量为1时结束
* 1. 构造增量--数组的一半长度,每次增速减小速率为1/2
* 2. 对子数组进行插值排序
* 3. 减小增量,重复上述操作
* 4. 增量为1时结束
* @param arr
* @return
*/
public static int[] shellSort(int[] arr) {
int gap = arr.length;
while (true){
gap = gap / 2;
for (int i = gap; i < arr.length; i++) {
//对子区间进行插值排序
//方式一
// int preIndex = i - 1;
// int current = arr[i];
// while(preIndex >= 0 && current < arr[preIndex]){
// arr[preIndex + 1] = arr[preIndex];
// preIndex -= 1;
// }
// arr[preIndex + 1] = current;
//方式二
for (int j = i; j > i - gap; j--){
if(arr[j] < arr[j-1]){
int temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
}
}
if(gap == 1){
break;
}
}
return arr;
}
/**
* 快速排序--"分而治之"的部分
* 思路:三个参数”1个位置两个游标“,左边游标从左出发找比位置参数的对应值大的数,右边游标从右出发找比位置参数的对应值小的数,交换;递归上面的操作,知道左右游标相遇
* 1. 确定位置,位置左边数组递归,位置右边数组递归
* 2. 确定位置的方法很多,这里将数组第一个数组作为位置,对应值为key,将大于key的放在右边,小于key放在左边,最后交换key到中间
* 3. ***注意***将数组第一个数做位置时,右游标先动,即找到比key小的数;反之亦然
* @param array
* @param left
* @param right
*/
public static void quickSort(int[] array, int left, int right) {
if(left >= right){
return;
}
final int key = partSort1(array, left, right);
quickSort(array, left, key - 1);
quickSort(array, key + 1 , right);
}
/**
* 返回调整后基准数的位置
* @param array
* @param left
* @param right
* @return
*/
private static int partSort1(int[] array, int left, int right){
int key = array[left];
int i = left;
int j = right;
while(i < j){
while(i < j && array[j] >= key){
j--;
}
while (i < j && array[i] <= key){
i++;
}
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
array[left] = array[i];
array[i] = key;
return i;
}
排序算法(一)
最新推荐文章于 2024-02-01 11:40:08 发布