遍历 ( n − 1 ) (n-1) (n−1) 次要排序的数列,每次遍历时,它都会从前往后依次的比较相邻两个数的大小;如果前者比后者大,则交换它们的位置。一次遍历之后,最大的元素在数列的末尾。
采用相同的方法再次遍历时,第二大的元素就被排列在最大元素之前。
重复此操作,直到整个数列都有序为止
public class Main{
public static void BubbleSort(int[] arr, int n){
boolean change = false;
int mid = 0;
for(int i=n-1; i>0; i--){
change = false;
for(int j=0; j<i; j++){
if(arr[j] > arr[j+1]){
change = true;
mid = arr[j+1];
arr[j+1] = arr[j];
arr[j] = mid;
}
}
if(!change){
break;
}
}
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,0};
BubbleSort(arr, arr.length);
for(int xx: arr){
System.out.printf("%d ", xx);
}
}
}
随便在序列中选择一个数最为基准,将大于该数的放到右边,小于该数的放到左边,并将该数放到中间,再递归的以同样的方法排两边的数。
public class Main{
public static void QuickSort(int[] arr, int l, int r){
if(l >= r){
return;
}
int mid = arr[l];
int cur_l = l;
int cur_r = r;
while(cur_l < cur_r){
//from right to find the first number smaller than 'mid'
while(cur_l < cur_r && arr[cur_r] >= mid){
cur_r--;
}
if(cur_l < cur_r){
arr[cur_l] = arr[cur_r];
}
//from left to find the first number bigger than 'mid'
while(cur_l < cur_r && arr[cur_l] <= mid){
cur_l++;
}
if(cur_l < cur_r){
arr[cur_r] = arr[cur_l];
}
}
arr[cur_l] = mid;
QuickSort(arr, l, cur_l-1);
QuickSort(arr, cur_l+1, r);
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,0};
QuickSort(arr, 0 ,arr.length-1);
for(int xx: arr){
System.out.printf("%d ", xx);
}
}
}
数组前半部分是排好的有序数组,数组后半部分是待排数组。
每次从后边的待排数组中拿出一个插入到前边有序数组中的正确位置。
public class Main{
public static void InsertSort(int[] arr, int n){
for(int i=0; i<n; i++){
int index = i-1;
int cur = arr[i];
while(index >= 0 && arr[index] > cur){
arr[index+1] = arr[index];
index--;
}
arr[index+1] = cur;
}
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,0,3};
InsertSort(arr, arr.length);
for(int xx: arr){
System.out.printf("%d ", xx);
}
}
}
希尔排序是改进的插入排序,之前插入排序是将整个数列看成一个整体,而这样数据量过大时,耗时较长,故采用分组策略,每次指定一个步长,根据步长进行分组,并把每个分组进行插入排序,并逐步缩短步长,直到最后步长为0,即可实现整个序列有序。
public class Main{
public static void ShellSort(int[] arr, int n){
for(int gap=n/2; gap>=1; gap/=2){
for(int i=0; i<gap; i++){
InsertSort(arr, n, i, gap);
}
}
}
public static void InsertSort(int[] arr, int n, int start, int gap){
for(int i=start; i<n; i+=gap){
int index = i-gap;
int cur = arr[i];
while(index >= 0 && arr[index] > cur){
arr[index+gap] = arr[index];
index-=gap;
}
arr[index+gap] = cur;
}
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,0,3};
ShellSort(arr, arr.length);
for(int xx: arr){
System.out.printf("%d ", xx);
}
}
}
public class Main{
public static void SelectSort(int[] arr, int n){
int min_index;
for(int i=0; i<n; i++){
//find the smallest in [i, n]
min_index = i;
for(int j=i+1; j<n; j++){
if(arr[j] < arr[min_index]){
min_index = j;
}
}
//make the smallest to [i]
int change = arr[min_index];
arr[min_index] = arr[i];
arr[i] = change;
}
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,0,3};
SelectSort(arr, arr.length);
for(int xx: arr){
System.out.printf("%d ", xx);
}
}
}
对于堆排序,Java Collection 中有个 PriorityQueue
优先队列, 可以快速实现堆排序
//在类似csp这种没有实时反馈的比赛中,尽量使用不抛出异常的语句,否则就直接爆0
PriorityQueue<Integer> pq = new PriorityQueue<>();
for(int i=0; i<10; i++){
pq.offer(10-i);
}
while(!pq.isEmpty()){
System.out.printf("%d ", pq.peek());
pq.poll();
}
手写二叉树维护堆。(数组实现)
public class Main{
public static void ChangeDown(int[] arr, int index, int n){
int child = index*2 + 1;
while(child < n){
//find the biggest child
if(child < n-1 && arr[child] < arr[child+1]){
child++;
}
if(arr[index] >= arr[child]){
break;
}else{
int mid = arr[index];
arr[index] = arr[child];
arr[child] = mid;
}
index = child;
child = index * 2 + 1;
}
}
public static void HeapSort(int[] arr, int n){
//construct maxheap
for(int i=(n-1)/2; i>=0; i--){
ChangeDown(arr, i, n);
}
//sort the array
for(int i=n-1; i>=0; i--){
int mid = arr[0];
arr[0] = arr[i];
arr[i] = mid;
ChangeDown(arr, 0, i);
}
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,0,3};
HeapSort(arr, arr.length);
for(int xx: arr){
System.out.printf("%d ", xx);
}
}
}
归并排序可以配合多线程加快速度。
自顶向下进行归并排序
图片来自 http://wangkuiwu.github.io/media/pic/datastruct_algrithm/algrithm/merge_01.jpg
public class Main{
public static void merge(int[] arr, int start, int mid, int end){
int[] result = new int[end-start+1];
int cur1 = start;
int cur2 = mid+1;
int index = 0;
while(cur1 <=mid && cur2 <=end){
if(arr[cur1] > arr[cur2]){
result[index++] = arr[cur2];
cur2++;
}else{
result[index++] = arr[cur1];
cur1++;
}
}
while(cur1 <= mid){
result[index++] = arr[cur1++];
}
while(cur2 <= end){
result[index++] = arr[cur2++];
}
for(int i=0; i<end-start+1; i++){
arr[start+i] = result[i];
}
}
public static void MergeSort(int[] arr,int start, int end){
if(start >= end){
return;
}
int mid = start + (end - start)/2;
//divide into two array
MergeSort(arr, start, mid);
MergeSort(arr, mid+1, end);
//merge two array
merge(arr, start, mid, end);
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,0,3};
MergeSort(arr, 0, arr.length-1);
for(int xx: arr){
System.out.printf("%d ", xx);
}
}
}
桶排序用一个数组的下标代表值,每存在一个值,就将对于下标的值加1,最后从头将数组扫描一遍即可
import java.util.Arrays;
public class Main{
public static void BucketSort(int[] arr, int n, int maxx){
int[] bucket = new int[maxx];
Arrays.fill(bucket, 0);
for(int i=0; i<n; i++){
bucket[arr[i]]++;
}
int index = 0;
for(int i=0; i<maxx; i++){
while(bucket[i]>0){
arr[index++] = i;
bucket[i]--;
}
}
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,0,3};
BucketSort(arr, arr.length, 20);
for(int xx: arr){
System.out.printf("%d ", xx);
}
}
}
作为桶排序的拓展,将整数按位数切割成不同的数字,然后按每个位数分别比较。
import java.util.Arrays;
public class Main{
public static void BubbleSort(int[] arr, int n, int exp){
int[] bubble = new int[10];
int[] result = new int[n];
Arrays.fill(bubble, 0);
for(int i=0; i<n; i++){
bubble[(arr[i]/exp)%10]++;
}
for(int i=1; i<n; i++){
bubble[i] = bubble[i] + bubble[i-1];
}
for(int i=0; i<n; i++){
result[bubble[(arr[i]/exp)%10]-1] = arr[i];
bubble[(arr[i]/exp)%10]--;
}
for(int i=0; i<n ;i++){
arr[i] = result[i];
}
}
public static void RadixSort(int[] arr, int n){
int maxx = arr[0];
for(int i=1; i<n; i++){
if(arr[i] > maxx){
maxx = arr[i];
}
}
for(int i=1; maxx/i>0; i*=10){
BubbleSort(arr, n, i);
}
}
public static void main(String[] args) {
int[] arr = {1,2,200,3,4,5,6,0,3};
RadixSort(arr, arr.length);
for(int xx: arr){
System.out.printf("%d ", xx);
}
}
}
图片来源https://www.cnblogs.com/onepixel/articles/7674659.html
参考博客: