1、冒泡排序
每一次选未排序的数组中最大的放到未排序数组的后面。
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {1, 3, 5, 3, 8, 4, 6, 2};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j]> arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
2、插入排序
每次加入一个数,插入到前面的有序数组中。
public class InsertSort {
public static void main(String[] args) {
int[] arr = new int[]{8,7,6,5,4,3,2,1,9};
int n = arr.length;
for (int i = 1; i < n; i++) {
int temp = arr[i];
int j = i;
while (j>0 && temp< arr[j-1]){
arr[j] = arr[j-1];
j--;
}
arr[j] = temp;
}
System.out.println(Arrays.toString(arr));
}
}
3、选择排序
每次选择未排序中最小的放到最终位置
public class SelectionSort {
public static void main(String[] args) {
int[] arr = new int[]{8,7,6,5,4,3,2,1,9};
int n = arr.length;
for (int i = 0; i < n; i++) {
int minIndex = i;
for (int j = i; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
swap(arr, i, minIndex);
}
System.out.println(Arrays.toString(arr));
}
public static void swap(int[] nums, int index1, int index2) {
int temp = nums[index1];
nums[index1] = nums[index2];
nums[index2] = temp;
}
}
4、快速排序
选取基准值,双指针交换两边的值,最后基准值左边的数都小于基准值,右边的数大于基准值。
然后左边和右边按此思路递归处理
private void quickSort(int[] nums, int lo, int hi) {
int left = lo,right = hi;
int mid = nums[left+(right-left)/2];
while (left < right){
while (nums[left] < mid){
left++;
}
while (nums[right] > mid){
right--;
}
if (left >= right) break;
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
if (nums[left] == mid) right--;
if (nums[right] == mid) left++;
}
if (left == right){
left++;
right--;
}
if (left <hi){
quickSort(nums,left,hi);
}
if (right>lo){
quickSort(nums,lo,right);
}
}
5、归并排序
分而治之,折半分,到最后只剩一个,再合并,合并的时候比较大小排序
private int[] temp;//辅助数组
void mSort1(int[] nums,int start,int end){
if (end <= start){
return;
}
int mid = start+(end-start)/2;
mSort1(nums,start,mid);
mSort1(nums,mid+1,end);
merge1(nums,start,mid,end);
}
private void merge1(int[] nums, int start, int mid, int end) {
for (int i = start; i <=end; i++) {
temp[i] = nums[i];
}
int i = start,j = mid+1;
for (int k = start; k <= end; k++) {
if (i == mid+1){//左边的数组排好序了
nums[k] = temp[j++];
} else if (j == end+1) {//右边的数组排好序了
nums[k] = temp[i++];
} else if (temp[i] > temp[j]) {
nums[k] = temp[j++];
}else {
nums[k] = temp[i++];
}
}
}
6、堆排序
主要是构建堆
public class HeapSort {
public int[] sortArray(int[] nums) {
int len = nums.length;
// 将数组整理成堆
heapify(nums);
// 循环不变量:区间 [0, i] 堆有序
for (int i = len - 1; i >= 1; ) {
// 把堆顶元素(当前最大)交换到数组末尾
swap(nums, 0, i);
// 逐步减少堆有序的部分
i--;
// 下标 0 位置下沉操作,使得区间 [0, i] 堆有序
siftDown(nums, 0, i);
}
return nums;
}
/**
* 将数组整理成堆(堆有序)
*
* @param nums
*/
private void heapify(int[] nums) {
int len = nums.length;
// 只需要从 i = (len - 1) / 2 这个位置开始逐层下移
for (int i = (len - 1) / 2; i >= 0; i--) {
siftDown(nums, i, len - 1);
}
}
/**
* @param nums
* @param k 当前下沉元素的下标
* @param end [0, end] 是 nums 的有效部分
*/
private void siftDown(int[] nums, int k, int end) {
while (2 * k + 1 <= end) {
int j = 2 * k + 1;
if (j + 1 <= end && nums[j + 1] > nums[j]) {
j++;
}
if (nums[j] > nums[k]) {
swap(nums, j, k);
} else {
break;
}
k = j;
}
}
private void swap(int[] nums, int index1, int index2) {
int temp = nums[index1];
nums[index1] = nums[index2];
nums[index2] = temp;
}
}
7、计数排序
适合数组个数很多但是数组的值在一定范围比如数组个数1万个,但是数组的值是1到100的正整数。
public class CountSort {
public static void main(String[] args) {
int[] arr = new int[]{4,2,2,2,2,3,2,1,4};
int[] temp = new int[5];
for (int i = 0; i < arr.length; i++) {
temp[arr[i]]++;
}
int j = 0;
for (int i = 0; i < 5; i++) {
while (temp[i] >0){
arr[j] = i;
j++;
temp[i]--;
}
}
System.out.println(Arrays.toString(arr));
}
}