public class NetherlandsFlag {
public static void netherlandsFlag(int[] arr,int L,int R,int num){
int min = L-1;
int max = R+1;
while(L < max){
if(arr[L]<num){
swap(arr,L++,++min);
}else if(arr[L]>num){
swap(arr,L,--max);
}else{
L++;
}
}
}
// public static int[] netherlandsFlag(int[] arr, int l, int r, int p) {
// int less = l - 1;
// int more = r + 1;
// while (l < more) {
// if (arr[l] < p) {
// swap(arr, ++less, l++);
// } else if (arr[l] > p) {
// swap(arr, --more, l);
// } else {
// l++;
// }
// }
// return new int[] { less + 1, more - 1 }; //返回等于num的部分的位置
// }
public static void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int[] arr = {2,4,5,1,9,7,6,7,0};
int num = 5;
netherlandsFlag(arr,0,arr.length-1,num);
System.out.println(Arrays.toString(arr));
}
}
package com.godzuo.java;
import java.util.Arrays;
/**
* @author quanquan
* @create 2020-04-19-22:39
*/
public class QuickSort {
public static void quickSort(int[] arr){
if(arr == null || arr.length < 2) return;
quickSort(arr,0,arr.length-1);
}
public static void quickSort(int[] arr,int L,int R){
if(L < R) {
int[] p = partition(arr, L, R);
quickSort(arr, L, p[0] - 1);
quickSort(arr, p[1] + 1, R);
}
}
//数组的第最后一个数作为标准进行划分,再把最后一个数放到正确的位置
//空间复杂度O(1),时间复杂度O(N),做不到稳定性
public static int[] partition(int[] arr,int L,int R){
int min = L-1;
int max = R;
int num = arr[R];
while(L < max){
if(arr[L]<num){
swap(arr,L++,++min);
}else if(arr[L]>num){
swap(arr,L,--max);
}else{
L++;
}
}
swap(arr, max, R);
return new int[] {min+1,max};
}
public static void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
int[] arr = {2, 4, 5, 1, 9, 7, 6, 7, 0,3,7};
quickSort(arr);
System.out.println(Arrays.toString(arr));
}
}
时间复杂度O(N*logN),额外空间复杂度O(logN)(记下断点位置)
//加人一行代码,交换位置
public static void quickSort(int[] arr,int L,int R){
if(L < R) {
swap(arr,R,L+(int)Math.random()*(R-L+1));
int[] p = partition(arr, L, R);
quickSort(arr, L, p[0] - 1);
quickSort(arr, p[1] + 1, R);
}
}
package com.godzuo.java;
import java.util.Arrays;
/**
* @author quanquan
* @create 2020-04-20-15:36
*/
public class HeapSort {
public static void heapSort(int[] arr){
if(arr == null || arr.length < 2) return;
for(int i=0;i<arr.length;i++){
heapInsert(arr,i);
}
// int size = arr.length;
// swap(arr, 0, --size);
// while (size > 0) {
// heapify(arr, 0, size);
// swap(arr, 0, --size);
// }
int heapSize = arr.length-1;
while (heapSize>0){
swap(arr,0, heapSize);
heapify(arr,0,heapSize--);
}
}
//建立大根堆
public static void heapInsert(int[] arr,int i){
while (arr[i]>arr[(i-1)/2]){
swap(arr,i,(i-1)/2);
i = (i-1)/2;
}
}
public static void swap(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//修改大根堆
public static void heapify(int[] arr,int index,int heapSize){
int left = index*2+1;
while (left < heapSize){
int largest = left+1 < heapSize && arr[left+1] > arr[left] ? left+1 : left;
largest = arr[largest] > arr[index] ? largest : index;
if (largest == index){
break;
}
swap(arr,largest,index);
index = largest;
left = index*2+1;
}
}
public static void main(String[] args) {
int[] arr = {5,6,2,8,1,4,9,0,7};
heapSort(arr);
System.out.println(Arrays.toString(arr));
}
}
排序算法的稳定性及其汇总
任何一个相同的值在原始序列中相对次序是不变的
1.冒泡排序可以实现成稳定的(相同的值不交换)
2.插入排序可以实现成稳定的
3.选择排序不稳定
4.归并排序可以实现成稳定的(保证左边和右边相等时先拷贝左边)
5.快速排序不稳定
6.堆排序不稳定
工程中的综合排序算法
补充
比较器
package com.godzuo.java;
import java.util.Arrays;
import java.util.Comparator;
public class MyComparator {
public static class Student {
public String name;
public int id;
public int age;
public Student(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
}
public static class IdAscendingComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.id - o2.id;
}
}
public static class IdDescendingComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o2.id - o1.id;
}
}
public static class AgeAscendingComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.age - o2.age;
}
}
public static class AgeDescendingComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o2.age - o1.age;
}
}
public static void printStudents(Student[] students) {
for (Student student : students) {
System.out.println("Name : " + student.name + ", Id : " + student.id + ", Age : " + student.age);
}
System.out.println("===========================");
}
public static void main(String[] args) {
Student student1 = new Student("A", 1, 23);
Student student2 = new Student("B", 2, 21);
Student student3 = new Student("C", 3, 22);
Student[] students = new Student[] { student3, student2, student1 };
printStudents(students);
Arrays.sort(students, new IdAscendingComparator());
printStudents(students);
Arrays.sort(students, new IdDescendingComparator());
printStudents(students);
Arrays.sort(students, new AgeAscendingComparator());
printStudents(students);
Arrays.sort(students, new AgeDescendingComparator());
printStudents(students);
//自带的堆结构
PriorityQueue<Student> heap = new PriorityQueue<>(new AgeAscendingComparator());
heap.add(student1);
heap.add(student2);
heap.add(student3);
while (!heap.isEmpty()){
Student student = heap.poll();
System.out.println("Name : " + student.name + ", Id : " + student.id + ", Age : " + student.age);
}
}
}
package com.godzuo.java;
/**
* @author quanquan
* @create 2020-04-20-21:41
*/
public class MaxGap {
public static int maxGap(int[] nums) {
if (nums == null || nums.length < 2) {
return 0;
}
int len = nums.length;
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < len; i++) {
min = Math.min(min, nums[i]);
max = Math.max(max, nums[i]);
}
if (min == max) {
return 0;
}
boolean[] hasNum = new boolean[len + 1];
int[] maxs = new int[len + 1];
int[] mins = new int[len + 1];
int bid = 0;
for (int i = 0; i < len; i++) {
bid = bucket(nums[i], len, min, max); //找到元素应该放置的桶
mins[bid] = hasNum[bid] ? Math.min(mins[bid], nums[i]) : nums[i]; //更新桶中最小值
maxs[bid] = hasNum[bid] ? Math.max(maxs[bid], nums[i]) : nums[i]; //更新桶中最大值
hasNum[bid] = true;
}
int res = 0;
int lastMax = maxs[0];
int i = 1;
//找到每一个非空桶和距他最近的非空桶,用当前的最小,减前一个最大
for (; i <= len; i++) {
if (hasNum[i]) {
res = Math.max(res, mins[i] - lastMax);
lastMax = maxs[i];
}
}
return res;
}
public static int bucket(long num, long len, long min, long max) {
return (int) ((num - min) * len / (max - min));
}
}