# 排序算法（insert ，shell ，quick ，select , merge ，heap）

``````public class Sort {

public static void main(String[] args) {
Integer[] a1 = {52, 39, 67, 95, 70, 8, 25, 52};
//String类型已经实现Comparable接口，compareTo方法定义为按字典顺序比较
//(当第一个字符相同时，从第二个比较，以此类推)
String[] a = {"Sa", "Sb", "O", "R", "T", "E", "X", "A", "M", "P", "L", "E"};

System.out.println("排序前：");
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
//insert(a);
//shell(a);
//quick(a,0,a.length-1);
//select(a);
//merge(a);
heap(a);
System.out.println("\n排序后：");
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
}
//直接插入算法,时间复杂度为O(n^2),稳定
public static void insert(Comparable[] a) {
for (int i = 0; i < a.length; i++)
for (int j = i; j > 0; j--)
//保证插入排序是稳定算法
if (less(a[j], a[j - 1]))
exch(a, j, j - 1);
else
break;  //当后比前大或相等时终止内部的后续for循环，因为j之前的元素已经有序

}
//Shell排序,时间复杂度为O(n^3/2),不稳定
public static void shell(Comparable[] a) {
//选择增量为3x+1
int N = a.length;
int h = 1;
while (h < N / 3)
h = 3 * h + 1;
while (h >= 1) {
for (int i = h; i < N; i++) {
for (int j = i; j >= h && less(a[j], a[j - h]); j -= h)
exch(a, j, j - h);
}
h = h / 3;
}
}
//快速排序，时间复杂度O(log2n)，不稳定
public static void quick(Comparable[] a, int lo, int hi) {
if (hi <= lo)
return;
int j = partition(a, lo, hi);
quick(a, lo, j - 1);
quick(a, j + 1, hi);
}
//快速排序的partition算法,返回中间位置的索引
private static int partition(Comparable[] a, int lo, int hi) {
int i = lo;
int j = hi + 1;
Comparable v = a[lo];
while (true) {
//即使不满足less()的条件，也会先执行++i或者--j
while (less(a[++i], v))
if (i == hi)
break;
while (less(v, a[--j]))
if (j == lo)
break;
if (i >= j) break;
exch(a, i, j);
}
exch(a, lo, j);
return j;
}

//直接选择排序,时间复杂度O(n^2),不稳定
public static void select(Comparable[] a) {
int N = a.length;
Comparable temp = null;
for (int i = 0; i < N - 1; i++) {
int min = i;
for (int j = i + 1; j < N; j++)
if (!less(a[min], a[j]))
min = j;
if (min != i)
exch(a, i, min);
}
}
//2路归并算法，时间复杂度O(nlog2n),稳定
public static void merge(Comparable[] a) {
int N = a.length;
Comparable[] aux = new Comparable[N];
/*for (int k = 0; k <N; k++)
aux[k] = a[k];
不能在此处对aux赋值，因为在for循环中会使得每次传入的值
都为merge(Comparable[]a)中的aux数组。
*/
for(int sz=1;sz<N;sz=sz+sz)
for(int lo = 0;lo<N-sz;lo+=sz+sz)
merge(a,aux,lo,lo+sz-1,Math.min(lo+sz+sz-1,N-1));
}

private static void merge(Comparable[]a,Comparable[]aux, int lo, int mid, int hi) {

for (int k = lo; k <= hi; k++) {
aux[k] = a[k];
}

//归并回a数组*/
int i = lo, j = mid + 1;
System.out.println("\nlo: "+lo+" hi: "+hi);
for (int k = 0; k <aux.length; k++)
System.out.print(aux[k]+" ") ;

for (int k = lo; k <= hi; k++) {
if      (i > mid)              a[k] = aux[j++];     //当左半部分指针右移超过中间，只剩右半部
else if (j > hi)               a[k] = aux[i++];     //同上，对边界条件进行判断
else if (less(aux[j], aux[i])) a[k] = aux[j++];
else                           a[k] = aux[i++];     //i=mid等情况
}
aux =a;
System.out.println("aux2:");
for (int k = 0; k <aux.length; k++)
System.out.print(aux[k]+" ") ;

}
//堆排序，时间复杂度O(nlog2n),不稳定
public static void heap(Comparable[] pq) {
int N = pq.length;
for (int k = N / 2; k >= 1; k--)
sink(pq, k, N);
while (N > 1) {
heapexch(pq, 1, N);
sink(pq, 1, --N);
}
}

private static void sink(Comparable[] pq, int k, int N) {
while (2 * k <= N) {
int j = 2 * k;
if (j < N && heapless(pq, j, j + 1)) j++; //若左节点比右节点小，则移到右节点
if (!heapless(pq, k, j)) break; //若父节点不小于子节点则退出循环
heapexch(pq, k, j); //交换父节点和子节点
k = j;
}
}
private static boolean heapless(Comparable[] pq, int i, int j) {
return pq[i - 1].compareTo(pq[j - 1]) < 0;
}

private static void heapexch(Object[] pq, int i, int j) {
Object swap = pq[i - 1];
pq[i - 1] = pq[j - 1];
pq[j - 1] = swap;
}

private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}

private static void exch(Comparable[] a, int i, int j) {
Comparable temp = null;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}``````
• 本文已收录于以下专栏：

## Bubble, Insertion, Selection, Quick and Heap Sort

Bubble, Insertion, Selection, Quick and Heap Sort
• guoxiaojie_415
• 2015年08月15日 15:56
• 868

## 常用排序算法时间复杂度和空间复杂度简析

• u012301943
• 2014年06月24日 21:08
• 1101

## SHELL里用SELECT语句做INSERT语句.

• kimsung
• 2010年01月19日 15:41
• 2139

## Oracle SQL：insert into语句总结 与 merge into用法总结

insert into语句总结 vs merge into用法总结：1、insert into 插入数据;2、merge into 有则更新,无则插入;...
• yihuiworld
• 2015年03月27日 16:33
• 19704

## 【Data Structure】nlogn-SortMethods(Quick/Heap/Shell/Merge)

• Ya_da
• 2015年12月05日 22:09
• 412

## merge into 当using后的select结果为空时，不能执行update和insert

• ywl570717586
• 2015年11月18日 09:56
• 2221

## MergeSort与QuickSort的详细分析

MergeSort和QuickSort是两种比较类似的sort方式，他们都是通过Divide and Conquer来实现的。都需要使用recursion的方式进行排序。他们的相同之处在于原理上一致...
• qt_pixie
• 2006年11月02日 03:06
• 8122

## SQL Server的Merge —— 一步实现 insert,update,delete

USE tempdb GO IF OBJECT_ID('SourceTable') IS NOT NULL DROP TABLE SourceTable IF OBJECT_ID('TargetTab...
• yenange
• 2016年09月29日 16:46
• 853

## 【PAT】1089. Insert or Merge (25)

According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and g...
• realxuejin
• 2015年10月22日 16:13
• 535

## MERGE语句用来合并UPDATE和INSERT语句，一张表的大数据操作，要同时进行增删改，提高性能

• JesseCary
• 2017年03月06日 20:44
• 1357

举报原因： 您举报文章：排序算法（insert ，shell ，quick ，select , merge ，heap） 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)