冒泡
// 每轮冒泡的过程都可以确定一个元素放在正确的位置上,而这个元素就是剩余元素中最大的元素,正确的位置就是剩余位置中的最右侧的位置
// 最好情况 完全有序,只需要遍历一次, 最坏情况,完全逆序,需要全部遍历
public int[] bubbleSort(int[] arr) {
if (arr.length <= 1) {
return arr;
}
int len = arr.length;
// 每个数都要比,所以外层循环次数为 len
for (int i = 0; i < len; i++) {
// 每个数都跟它之后的数字比 len - i - 1
for (int j = 0; j < len - 1 - i; j++) {
if (arr[j + 1] < arr[j]){
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
冒泡的改进
public static int[] bubbleSort(int[] arr) {
if (arr.length <= 1) return arr;
int len = arr.length;
for (int i = 0; i < len - 1; i++) {
boolean isComplete = true;
for (int j = 0; j < len - 1 - i; j++) {
if (arr[j] < arr[i]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
isComplete = false;
}
}
if (isComplete) {
break;
}
}
return arr;
}
插入
public static int[] insertSort(int[] arr){
if (arr.length <= 1) return arr;
int len = arr.length;
for (int i = 0; i < len - 1; i++) {
int insertValue = arr[i + 1];
int insertIndex = i;
while (insertIndex >= 0 && insertValue < arr[insertIndex]){
arr[insertIndex + 1] = arr[insertIndex];
insertIndex--;
}
arr[insertIndex + 1] = insertValue;
}
return arr;
}
希尔排序
public static int[] shellSort(int[] arr){
if (arr.length <= 1) return arr;
int len = arr.length;
int gap = len / 2;
while (gap > 0){
for (int i = gap; i < len; i++) {
int insertValue = arr[i];
int insertIndex = i - gap;
while (insertIndex >= 0 && insertValue < arr[insertIndex]){
arr[insertIndex + gap] = arr[insertIndex];
insertIndex -= gap;
}
arr[insertIndex + gap] = insertValue;
}
gap /= 2;
}
return arr;
}
归并
public static int[] mergeSort(int[] arr){
if (arr.length <= 1) return arr;
int mid = arr.length / 2;
int[] left = Arrays.copyOfRange(arr, 0, mid);
int[] right = Arrays.copyOfRange(arr, mid, arr.length);
// 左边分 ---- 右边分 ---- 整个数组合
return merge(mergeSort(left), mergeSort(right));
}
public static int[] merge(int[] left,int[] right){
int[] res = new int[left.length + right.length];
int l1 = 0, l2 = 0, index = 0;
while (l1 < left.length && l2 < right.length){
if (left[l1] <= right[l2]){
res[index++] = left[l1];
l1++;
}else {
res[index++] = right[l2];
l2++;
}
}
while (l1 < left.length){
res[index++] = left[l1++];
}
while (l2 < right.length){
res[index++] = left[l2++];
}
return res;
}
选择
public static int[] selectSort(int[] arr){
if (arr.length <= 1) return arr;
int len = arr.length;
for (int i = 0; i < len - 1; i++) {
int minIndex = i;
// 有序区R[1..i-1] 无序区R(i..n) 从剩余未排序元素中继续寻找最小元素
for (int j = i; j < len; j++) {
if (arr[j] < arr[minIndex]){
minIndex = j;
}
}
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
return arr;
}
快排
class Solution {
public int[] sortArray(int[] nums) {
if(nums.length == 1 || nums.length == 0) return nums;
quickSort(nums, 0, nums.length - 1);
return nums;
}
public void quickSort(int[] arr, int low, int high){
if(low < high){
// 找寻基准数据的正确索引
int index = partition(arr, low, high);
// index左半边排序
quickSort(arr, low, index - 1);
// index右半边排序
quickSort(arr, index + 1, high);
}
}
public int partition(int[] arr, int low, int high){
// 基准数据
int temp = arr[low];
while(low < high){
// 当队尾的元素大于等于基准数据时,high--
while(low < high && arr[high] >= temp){
high--;
}
// 如果队尾元素小于tmp了,需要将其赋值给low
arr[low] = arr[high];
// 当队首元素小于等于tmp时,low++
while(low < high && arr[low] <= temp){
low++;
}
// 当队首元素大于tmp时,需要将其赋值给high
arr[high] = arr[low];
}
// 跳出循环时low和high相等,此时的low或high就是tmp的正确索引位置
// 由原理部分可以很清楚的知道low位置的值并不是tmp,所以需要将tmp赋值给arr[low]
arr[low] = temp;
// 返回tmp的正确位置
return low;
}
}
堆排序
public class Solution {
public static void main(String[] args) {
int[] arr = {1,2,5,9,4,3};
heapSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void heapSort(int[] arr){
if (arr == null || arr.length == 0) return;
int heapSize = arr.length;
// 建堆
buildMaxHeap(arr, heapSize);
// 交换堆顶和当前末尾的节点,重置大顶堆
for (int i = heapSize - 1; i > 0; i--) {
// 交换堆顶和当前末尾的节点
swap(arr, 0, i);
// 把末尾结点从树中切断
heapSize--;
// 对堆顶元素也就是下标为0的元素做heapify操作
heapify(arr, 0, heapSize);
}
}
public static void buildMaxHeap(int[] arr, int heapSize){
// 从最后一个非叶子结点开始,从右到左从下到上heapify
for (int i = heapSize / 2; i >= 0; i--) {
heapify(arr, i, heapSize);
}
}
// 表示对哪个结点做heapify操作
private static void heapify(int[] arr, int i, int heapSize) {
int l = 2 * i + 1, r = 2 * i + 2, largestIndex = i;
if (l < heapSize && arr[l] > arr[largestIndex]){
largestIndex = l;
}
if (r < heapSize && arr[r] > arr[largestIndex]){
largestIndex = r;
}
if (largestIndex != i){
swap(arr, i, largestIndex);
heapify(arr, largestIndex, heapSize);
}
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}