最近一直在看排序算法及相关的文档,现在把一些常用的排序算法做一个总结,其中的相当一部分参考《Java面试宝典》;我只是整理下,使其成为电子版,以后便于翻阅。
这是初衷。
排序算法,按照其稳定性分类,可分为稳定的排序和非稳定的排序。这里的稳定的排序解释为,在待排序的文件中,如果存在多个关键字相同的几率,经过排序后,这些具有相同关键字的记录之间的相对次序保持不变,则该排序算法是稳定的,反之,若其相对次序发生变化,则称为不稳定的排序算法。
可以这样理解,若待排序的数字为{1,1,2,1,1,1,1,2,2,2,2,2},则稳定的排序对应的相同的数字,经排序后都为1的,其排序后先后顺序仍保持不变,非稳定的可能会使得相同的关键字后面的会排到前面。(我不太认为这种分类方法有什么意义,只是程序中修改一个等于号的问题。)
稳定的排序算法 | 时间复杂度 | 空间复杂度 |
---|---|---|
气泡排序 | 最差,平均都是O(n^2),最好是O(n) | 1 |
鸡尾酒排序(双向的冒泡排序) | 最差,平均都是O(n^2),最好是O(n) | 1 |
插入排序 | 最差,平均都是O(n^2),最好是O(n) | 1 |
归并排序 | 最差,平均和最好都是O(nlogn) | O(n) |
桶排序 | O(n) | O(k) |
基数排序 | O(dn)(d为常数) | O(n) |
二叉树排序 | O(nlogn) | O(n) |
图书馆排序 | O(nlogn) | O(n) |
不稳定的排序 | 时间复杂度 | 空间复杂度 |
选择排序 | 最差,平均都是O(n^2) | 1 |
希尔排序 | O(nlogn) | 1 |
堆排序 | 最差,平均和最好情况都是O(nlogn) | 1 |
快速排序 | 平均是O(nlogn),最坏是O(n^2) | O(logn) |
气泡排序代码:
/**
*
*/
package test;
/**
* @author {Binbin Sun}
* 冒泡排序
* 2016年3月27日
*/
public class bubbleSort {
public static void bubbleSort(int[] source){
for(int i = source.length-1; i > 0; i--){
for(int j =0; j < i; j++){
if(source[j] > source[j+1] ){
swap(source, j, j+1);
}
}
}
}
//不得不说,上面的两个i,j的循环设计的很巧妙,不错。
/**
* @param source
* @param j
* @param i
*/
private static void swap(int[] source, int j, int i) {
int temp = source[j];
source[j]=source[i];
source[i]=temp;
}
public static void main(String[] args){
int [] a = {4,1,2,3,4,6,78,-4,4,5,6,8,1,2,3};
bubbleSort(a);
for(int i = 0; i<a.length;i++){
System.out.println(a[i]);
}
}
}
快速排序:
package test;
/**
* @author {Binbin Sun}
*快速排序:快速排序使用了~~‘分治法’~~的基本思想,即将原问题分解为若干个规模更小但是结构与原问题相似的子问题,
*秭归的解这些子问题,然后将这些子问题的解的组合为原问题的解。
*快速排序的基本思想,分解,求解,组合;
* 2016年3月28日
*/
public class quickSort {
public static void quickSort(int source[], int low, int high){
int i,j,x;
if(low<high){
i= low;
j= high;
x= source[i];
while(i<j){
while(i<j &&source[j]>x){
j--;
}
if(i<j){
source[i]=source[j];
i++;
}
while(i< j&&source[i]<x){
i++;
}
if(i<j){
source[j]=source[i];
j--;
}
}
source[i]=x;
quickSort(source,low,i-1);
quickSort(source,i+1,high);
}
}
public static void main (String[] args){
int[] a= {4,4,2,3,46,7,1,7,3,1,46,8,4,7,9,11,1,2};
int i;
System.out.println("Before Sort…… ");
for(i=0;i<a.length;i++){
System.out.printf("%2d ",a[i]);
}
quickSort(a,0,a.length-1);
System.out.println("\r\n"+"After Sorting…… ");
for(i=0;i<a.length;i++){
System.out.printf("%2d ",a[i]);
}
}
}
二分排序:
/**
*
*/
package test;
/**
* @author {Binbin Sun}
*二分查找
* 2016年3月28日
*/
public class binarySort {
public static void main(String[] args){
int [] a = {1,2,3,5,21,3,1,2,4,6,4,7,8,9};
int i,j;
int low, mid,high;
int temp;
for(i = 1; i<a.length;i++){
temp=a[i];
low=0;
high=i-1;
while(low<=high){
mid=(low+high)/2;
if(a[mid]>temp){
high = mid-1;
}else{
low= mid+1;
}
}
for(j=i-1;j>high;j--){
a[j+1]=a[j];
}
a[high+1]=temp;
}
for(i =0;i<a.length;i++){
System.out.printf("%d ",a[i]);
}
}
}
归并排序:
package test;
/**
* @author {Binbin Sun}
*归并排序
* 2016年3月28日
*/
public class mergeSort {
public static void merge(int array[], int start1, int end1, int start2, int end2){
int i,j;
{
i = start1;
j = start2;
}
//System.out.println(" "+i);
int k=0;
int [] temp = new int[end2-start1+1];
while(i<=end1&&j<=end2){
if(array[i]>array[j])
temp[k++]=array[j++];
else
temp[k++]=array[i++];
}
while(i<=end1)
temp[k++]=array[i++];
while(j<=end2)
temp[k++]=array[j++];
k= start1;
for(int element: temp){
array[k++]=element;
}
}
public static void mergeSort(int array[],int start, int end){
if(start<end){
int mid = (start+end)/2;
//两路归并
mergeSort(array,start,mid);
mergeSort(array,mid+1,end);
merge(array,start,mid,mid+1,end);
//多路归并
/*
int mid = (start+end)/4;
mergeSort(array,start,1*mid);
mergeSort(array,1*mid+1,2*mid);
mergeSort(array,2*mid+1,3*mid);
mergeSort(array,3*mid+1,end);
merge(array,start,1*mid,1*mid,2*mid);
merge(array,start,2*mid,2*mid+1,end);
*/
}
}
public static void main(String[] args){
int [] a = {1,2,34,4,1,2,34,67,9,8,11,21,16,11,31,21,14,17};
System.out.println("Before Sort…… ");
for(int i=0;i<a.length;i++){
System.out.printf("%2d ",a[i]);
}
mergeSort(a,0,a.length-1);
System.out.println("\r\n"+"After Sorting…… ");
for(int i=0;i<a.length;i++){
System.out.printf("%2d ",a[i]);
}
}
}
插入排序:
/**
*
*/
package test;
/**
* @author {Binbin Sun}
*插入排序
* 2016年3月27日
*/
public class select2Sort {
public static void select2Sort(int[] source){
for(int i = 1; i< source.length;i++){
for(int j =i; (j > 0)&&(source[j]<source[j-1]);j--){
swap(source,j,j-1);
}
}
}
private static void swap(int[] source, int j, int i) {
int temp = source[j];
source[j]=source[i];
source[i]=temp;
}
public static void main(String[] args){
int [] a = {4,1,2,3,4,6,78,-4,4,5,6,8,1,2,3};
select2Sort(a);
for(int i = 0; i<a.length;i++){
System.out.println(a[i]);
}
}
}
选择排序:
/**
*
*/
package test;
/**
* @author {Binbin Sun}
*选择排序
* 2016年3月27日
*/
public class selectSort {
public static void selectSort(int[] source){
for(int i =0; i < source.length; i++){
for(int j = i + 1; j < source.length; j++){
if(source[i]>source[j]){
swap(source,i ,j);
}
}
}
}
/**
* @param source
* @param i
* @param j
*/
private static void swap(int[] source, int i, int j) {
int temp;
temp= source[i];
source[i]=source[j];
source[j]=temp;
}
public static void main(String[] args){
int [] a = {4,1,2,3,4,6,78,-4,4,5,6,8,1,2,3};
selectSort(a);
for(int i = 0; i<a.length;i++){
System.out.println(a[i]);
}
}
}
希尔排序:
/**
*
*/
package test;
/**
* @author {Binbin Sun}
*shell排序-希尔排序
* 2016年3月27日
*/
public class shellSort {
public static int[] a={4,2,1,3,4,6,7,97,4,634,6,46-8,13,1,2,23};
public static void main(String[] args){
int i;
int Index = a.length;
System.out.println("排序前……");
for(i = 0; i <Index-1;i++)
System.out.printf("%3s ",a[i]);
System.out.println(" ");
shellSort(Index-1);
System.out.println("排序后: ");
for(i = 0; i< Index-1;i++)
System.out.printf("%3s", a[i]);
System.out.println(" ");
}
public static void shellSort(int Index){
int i, j, k;
int temp;
boolean Change;
int DataLength;
int Pointer;
DataLength = (int) Index/2;
while(DataLength !=0){
for(j = DataLength; j < Index; j++ ){
Change = false;
temp = a[j];
Pointer = j -DataLength;
while(temp < a[Pointer]&& Pointer>= 0 && Pointer<=Index){
a[Pointer+DataLength] = a[Pointer];
Pointer = Pointer-DataLength;
Change = true;
if(Pointer < 0||Pointer>Index)
break;
}
a[Pointer+DataLength]=temp;
if(Change){
System.out.println("排序中……");
for(k=0; k< Index;k++)
System.out.printf("%3s ", a[k]);
System.out.println(" ");
}
}
DataLength = DataLength/2;
System.out.print("DataLength= "+DataLength);
}
}
}
这些排序算法中,我比较喜欢希尔排序。