注:其中快排的辅助空间为logn
1、插入排序
static void directInsertSort(int []array){
int i,j,temp;
for (i = 1; i < array.length; i++) {
//待插入元素
temp = array[i];
for (j = i-1; j>=0 && array[j]>temp; j--) {
//将大于temp的往后移动一位
array[j+1] = array[j];
}
array[j+1] = temp;
}
}
2、希尔排序
思想:使数组中任意间隔为h的元素都是有序的
public static void main(String[] args) {
int[] a = {1,5,2,15,3,0,5,4,10,23,2,1,25};
if(a.length == 0){
System.out.println("error");
}else{
insertSort(a,0,a.length-1);
for(int i = 0;i <= a.length-1;i++){
System.out.print(a[i]+" ");
}
}
}
private static void insertSort(int[] a, int l, int length) {
int i,j,h;
for(h = l ;h <= (length-l)/9;h = h*3+1);
for( ;h > 0;h = h/3){
for(i = h+l; i <=length ; i++)
{
j = i;
int v = a[i];
while(j >=l+h && v < a[j-h]){
a[j] = a[j-h];
j = j-h;
}
a[j] = v;
}
}
}
private static void exch(int[] a, int k, int j) {
int temp = a[k];
a[k] = a[j];
a[j] = temp;
}
3、选择排序
private static void chooseSort(int[] a, int i, int length) {
int j = length;
for(int k = i;k < j;k++){
int min = k;
for(int z = k+1;z <= j;z++){
if(a[min] > a[z]){
min = z;
}
}
exch(a,k,min);
}
}
private static void exch(int[] a, int k, int j) {
int temp = a[k];
a[k] = a[j];
a[j] = temp;
}
4、堆排序(大根堆)
/*
* 堆排序(大根堆)
*/
public class HeapSort {
public static void heap(int[] arr,int start,int end){
int temp = arr[start];
int i = 2*start+1;
int k = start;
while(end >= i){
if(arr[i] < arr[i+1] && (i+1) <= end) i = i+1;//选出左右节点中最大的与父节点交换
if(arr[i] < temp) break;
arr[k] = arr[i];
k = i;
i = 2*i+1;
}
arr[k] = temp;//temp!=arr[start]
}
public static void sort(int[] arr,int length){
for(int i = (length-1)/2;i >= 0;i--){//将最大的元素放在根节点
heap(arr, i, length);
}
//将每次循环中最大的元素与每次循环的最后一个节点交换位置
for(int j = length;j > 0;j--){
int temp = arr[0];
arr[0] = arr[j];
arr[j] = temp;
heap(arr,0,j-1);
}
}
5、冒泡排序
private static void maoPaoSort(int[] a, int l, int r) {
for(int i = l;i < r;i++){//a[l]~a[r],取到最小的值在最前面
for(int j = r;j > i;j--){//两两比较,把小的值交换到前面
if(a[j] < a[j-1])
exch(a, j, j-1);
}
}
}
private static void exch(int[] a, int k, int j) {
int temp = a[k];
a[k] = a[j];
a[j] = temp;
}
6、快速排序
(1)单方向快排
public static void Quick(int[] a,int start,int end){
if(start < end){
int q = flag(a,start,end);
Quick(a,start,q-1);
Quick(a,q+1,end);
}
}
private static int flag(int[] a, int start, int end) {
int i = start;
int x = a[end];
for(int j = i;j <= end-1;j++){
if(a[j] >= x){
swap(a,i,j);
i++;
}
}
swap(a,i,end);
return i;
}
private static void swap(int[] a, int i, int j) {
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
(2)两路快排
public static void Quick(int[] a,int start,int end){
if(start < end){
int q = flag(a,start,end);//此时q以左比q小,q以右比q大
Quick(a,start,q-1);
Quick(a,q+1,end);
}
}
private static int flag(int[] a, int start, int end) {
int i = start-1;
int v = a[end];
int j = end;
while(true){
while(a[++i] < v);
while(a[--j] > v)
if(j==0) break;
if(j <= i)
break;
swap(a,i,j);
}
swap(a,i,end);//将比较的值放到i上
return i;
7、两路归并排序
//归并排序两个有序的数组自底向上的归并排序
public static void main(String[] args) {
int[] c = {1,3,5,7,9,11,123,2,4,6,8,10,11,12};
System.out.println(System.currentTimeMillis());
mergeSort(c, 0, c.length-1);
System.out.println(System.currentTimeMillis());
for(int q = 0;q < c.length;q++){
System.out.print(c[q]+" ");
}
}
static void mergeSort(int[] array, int left, int right) {
if(left<right){
int middle = (left+right)/2;
//对左边进行递归
mergeSort(array, left, middle);
//对右边进行递归
mergeSort(array, middle+1, right);
//合并
merge(array,left,middle,right);
}
}
static void merge(int[] array, int left, int middle, int right) {
int[] tempArray = new int[array.length];
int middleRight = middle+1; //右边的起始位置
int temp = left;
int third = left;
while(left<=middle && middleRight<=right){
//从两个数组中选取较小的数放入临时数组
if(array[left]<=array[middleRight]){
tempArray[third++] = array[left++];
}else{
tempArray[third++] = array[middleRight++];
}
}
//将剩余的部分放入临时数组
while(left<=middle){
tempArray[third++] = array[left++];
}
while(middleRight<=right){
tempArray[third++] = array[middleRight++];
}
//将临时数组的排序结果复制到原数组
while(temp<=right){
array[temp] = tempArray[temp++];
}
}
8、桶排序
public static void main(String[] args) {
int i;
int a[] = {8,2,3,4,3,6,6,3,-1,-6,-5,6,9};
System.out.printf("before sort:");
for (i=0; i<a.length; i++)
System.out.printf("%d ", a[i]);
System.out.printf("\n");
bucketSort(a);
System.out.printf("after sort:");
for (i=0; i<a.length; i++)
System.out.printf("%d ", a[i]);
System.out.printf("\n");
}
public static void bucketSort(int[] A) {
//1. 构造桶
//1.1 确定桶的个数n
int n = A.length;
//1.2 声明并初始化一个List,存放链表;s
List<ArrayList<Integer>> Blist = new ArrayList<>(n);
for(int i = 0; i < n; i++)
Blist.add(new ArrayList<Integer>(5));
//2.将数组中的元素放到桶中
//2.1 确定元素的最值
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for(int a : A){
max = Math.max(max, a);
min = Math.min(min, a);
}
//2.2 确定每个元素放入桶的编号并放进去
for(int i : A){
//2.2.1 确定桶的编号
int len = A.length;
//加1是为了保证inde< A.length,防止程序抛出IndexOutofBoundsEx;
int index = (int)((i-min) / (max-min+1.0) * A.length);
//2.2.2 放入对应的桶中
Blist.get(index).add(i);
}
//3.桶内排序
for(int i = 0; i < Blist.size(); i++){
java.util.Collections.sort(Blist.get(i));
}
//4.合并数据
int j = 0;
for(ArrayList<Integer> arr : Blist){
for(int i : arr){
A[j++] = i;
}
}
}
基数排序
public static void main(String[] args)
{
int[] A=new int[]{73,22, 93, 43, 55, 14, 28, 65, 39, 81};
radixSort(A, 100);
for(int num:A)
{
System.out.println(num);
}
}
private static void radixSort(int[] a, int d) {
int n=1;//代表位数对应的数:1,10,100...
int k=0;//保存每一位排序后的结果用于下一位的排序输入
int length=a.length;
int[][] bucket=new int[10][length];//排序桶用于保存每次排序后的结果,这一位上排序结果相同的数字放在同一个桶里
int[] order=new int[length];//用于保存每个桶里有多少个数字
while(n<d)
{
for(int num:a) //将数组a里的每个数字放在相应的桶里
{
int digit=(num/n)%10;
bucket[digit][order[digit]]=num;
order[digit]++;
}
for(int i=0;i<length;i++)//将前一个循环生成的桶里的数据覆盖到原数组中用于保存这一位的排序结果
{
if(order[i]!=0)//这个桶里有数据,从上到下遍历这个桶并将数据保存到原数组中
{
for(int j=0;j<order[i];j++)
{
a[k]=bucket[i][j];
k++;
}
}
order[i]=0;//将桶里计数器置0,用于下一次位排序
}
n*=10;
k=0;//将k置0,用于下一轮保存位排序结果
}
}