/**
* 冒泡排序
* 定义:把相邻的元素两两比较,并按要求交换位置(升序/降序)
* 最好时间复杂度:O(n)
* 最坏时间复杂度:O(n2),n平方
* 优化:添加一个交换标识,当某一趟不发生交换时,说明当前数组已有序,可跳出遍历
* 稳定排序
*/
public void bubbleSort(int[] array) {
for (int i = 0; i < array.length; i++) {
boolean isChange = false;
for (int j = 0; j < array.length - i - 1; j++) {
if (array[j] < array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
isChange = true;
}
}
if(!isChange) {
break;
}
}
}
/**
* 选择排序
* 在未排序数列中找到最小(大)元素,放到数列起始位置,再从剩余元素中找到最小(大)元素
* 放到已排序数列末尾,继续上述操作直至所有元素排序完毕
* 最坏情况O(n2)
* 最好情况O(n2)
* 不稳定排序
*/
public void selectSort(int[] array) {
int len = array.length;
int index = 0;
int current = 0;
for (int i = 0; i < len; i++) {
current = array[i];
index = i;
for (int j = i + 1; j < len; j++) {
if (current > array[j]) {
index = j;
current = array[j];
}
}
int temp = array[i];
array[i] = array[index];
array[index] = temp;
}
}
/**
* 插入排序
* 将起始元素当作有序数列
* 取出下一个元素,在已排序的元素序列中从后向前查找,
*/
public void insertSort(int[] array) {
for (int i = 1; i < array.length; i++) {
int preIndex = i - 1;
int current = array[i];
while (preIndex >= 0 && array[preIndex] > current) {
array[preIndex + 1] = array[preIndex];
preIndex--;
}
array[preIndex + 1] = current;
}
}
/**
* 希尔排序
*
*/
public static int[] ShellSort(int[] array, int n) {
int current = 0, preIndex = 0;
int gap = 1;
while(gap < n/3){
gap = 3*n +1;
}
while (gap > 0) {
for (int i = gap; i < array.length; i+=gap) {
current = array[i];
preIndex = i - gap;
while (preIndex >= 0 && array[preIndex] > current) {
array[preIndex + gap] = array[preIndex];
preIndex -= gap;
}
array[preIndex + gap] = current;
}
gap /= 3;
}
return array;
}
/**
* 快速排序
*/
private static void quickSort(int[] array, int start, int end) {
if (start >= end) {
return;
}
int pivot = partition(array, start, end);
quickSort(array, start, pivot - 1);
quickSort(array, pivot + 1, end);
}
/**
*
* 快速排序分区方法:
* 将左指针所指元素作为基准元素;
* 右指针先开始移动,当右指针所指元素值大于或等于基准元素时,
* 右指针向左移动即 right --;当右指针所指元素值小于基准元素时,右指针停止移动;
* 此时,左指针开始移动,当左指针所指元素值小于或等于基准元素时,左指针向右移动
* 即left ++;当左指针所指元素值大于基准元素时,左指针停止移动;
* 将左右指针当前所值元素交换位置;
*
*/
private static int partition(int[] array, int start, int end) {
int pivot = array[start];
int left = start;
int right = end;
while (left != right) {
while (left < right && array[right] > pivot) {
right--;
}
while (left < right && array[left] <= pivot) {
left++;
}
if (left < right) {
int temp = array[left];
array[left] = array[right];
array[right] = temp;
}
}
array[start] = array[left];
array[left] = pivot;
return left;
}
/**
* 归并排序
*/
public static void sort(int[] array, int left, int right) {
if (left == right) {
return;
}
int mid = left + (right - left) / 2;
sort(array, left, mid);
sort(array, mid + 1, right);
merge(array, left, mid, right);
}
/**
*合并方法
*/
public static void merge(int[] array, int left, int mid, int right) {
int i = left;
int j = mid + 1;
int k = 0;
//临时数组,存放排序数列
int[] temp = new int[right - left + 1];
//比较左边第一个和右边第一个,然后把小的那一个放进到新数组;再将下标往后移动一位,继续比较;
while (i <= mid && j <= right) {
temp[k++] = array[i] <= array[j] ? array[i++] : array[j++];
}
//如果左边还有数据需要拷贝,把左边数组剩下的拷贝到新数组;
while (i <= mid) {
temp[k++] = array[i++];
}
//如果右边还有数据需要拷贝,就把右边数组剩下的拷贝到新数组;
while (j <= right) {
temp[k++] = array[j++];
}
for (int m = 0; m < temp.length; m++) {
array[left + m] = temp[m];
}
}
/**
* 二分查找
* */
public int binarySearch(int[] array, int left, int right, int key) {
if (left > right) {
return -1;
}
//int middle = (low + hight)/2; 等效下列公式
int middle = low + (high – low)/2 ;
if (key == array[middle]) {
return middle;
} else if (key > array[middle]) {
return binarySearch(array, middle + 1, right, key);
} else {
return binarySearch(array, left, middle - 1, key);
}
}
/**
* 插值查找:二分查找优化
*/
public int upgradeBinarySearch(int[] data, int left, int right, int target){
//必须添加,防止mid越界
if (left > right || target < data[left] || target > data[right]) {
return -1;
}
//公式推导过程我也不懂,b站韩顺平老师的数据结构看来的
int mid = left + (right - left) * (target - data[left]) / (data[right] - data[left]);
int midValue = data[mid];
if (midValue == target) {
return mid;
} else if (midValue > target) {
return binarySearch(data, left, mid - 1, target);
} else {
return binarySearch(data, mid + 1, right, target);
}
}
(Java实现)冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、二分查找、插值查找(二分查找优化版)
最新推荐文章于 2021-11-25 19:18:18 发布