算法学习----各种排序算法的实现和对比1
在这里将排序算法按照时间和空间的复杂度的优劣将排序算法划分成3种:简单的排序算法、中级排序算法和高级排序算法。其中,简单排序算法包括:冒泡排序、选择排序、插入排序。中级排序算法是基于递归思想的归并排序。高级排序包括:希尔排序、基于划分的快速排序和基数排序算法。这里的算法比较,都是基于数据是数组的存储类型来说的。
1 简单排序算法
众所周知,简单排序算法主要有:冒泡排序法、选择排序法、插入排序法。由于过于简单,就不多做解释了。下面就对这几种简单的排序算法进行比较:
冒泡排序:一般情况儿乎不太使用冒泡排序算法。它过于简单了,以至于可毫不费力地写出来。然而当数据量很小的时候它会有些应用的价值。
选择排序:选择排序虽然把交换次数降到了最低,但比较的次数仍然很大。当数据量很小,并且交换数据相对于比较数据更加耗时的情况下,可以应用选择排序。
插入排序:在大多数情况下,假设当数据量比较小或基本上有序时,插入排序算法是三种简单排序算法中最好的选择。对于更大数据量的排序来说,快速排序通常是最快的方法(快速排序在高级排序算法中会讲的)。
以上算法的时间复杂度都是O(n*n)。不过,某些情况下某个算法可以比其他算法快很多。简单的总结来说:
• 冒泡排序算法是效率最差的算法,但它最简单。
• 插入排序算法是简单排序中的O(n*n)排序算法中应用最多的。
• 插入排序算法是简单排序中的O(n*n)排序算法中应用最多的。
以上所有排序算法除了需要初始数组之外,都只需要一个临时变量。
除了在速度方面(时间复杂度)比较排序算法外,还有一种对各种算法的衡量标准是算法需要的内存空间有多大(空间复杂度)。上面的三种简单的排序算法都可以"就地"完成排序,即除了初始的数组外几乎不需要其他内存空间。所有排序算法都需要一个额外的变量来暂时存储交换时的数据项。
下面是以上插入排序算法针对不同数据类型的实现代码(见注释):
package intdata.InsertionSort;
import java.util.*;
public class Sort {
//对整形Int数据的数组插入排序
public static void insertionSort(int[] a){ //a 为数字对象的一个引用。引用=地址
int i,j,key,n=a.length; //i为数组下标;j为循环次数,与i有联系;key为容器。
for(j=1;j<n;j++){
key=a[j];//将新的数据(牌)给容器
i=j-1;//i为手中原有的牌数,a[i]为手中原有的(牌)
while(i>=0 && a[i] > key ){//从小到大
a[i+1]=a[i]; //将原数往后放一位
i--; //循环,直到减为0。
}
a[i+1]=key;//把新的数据插入正确的标号。
}
}
//对可比较型数据的(数组)版本的插入排序
public static void insertionSort(Comparable[] a){
int i,j,n=a.length;
Comparable key; //容器key的类型一定要和数据a的类型一致
for(j=1;j<n;j++){
key = a[j];
i=j-1;
while(i>=0 && a[i].compareTo(key) > 0){ //a[i]>key
a[i+1]=a[i];
i--;
}
a[i+1] = key;
}
}
//对可比较型数据的(线性表)版本的插入排序
public static void insertionSort(List<Comparable> a){
int j,i,n=a.size();
Comparable key;
for(j=1;j<n;j++){ //n-1
key=a.get(j);
i=j-1;
while(i>=0 && a.get(i).compareTo(key)> 0) { //a[i]>key
a.set(i+1, a.get(i)); //将a[i]的值给a[i+1]
i--;
//Collections.rotate(a.subList(i+1, j+1), 1); //将2个元素交换 i+1为手里的数
} //j+1为容器中刚拿到的数
a.set(i+1, key);
}
}
//能够对所有可比较数据类型(线性表)做任意方向的插入排序
public static void insertionSort(List<Comparable> a,Comparator comp){
int i,j;
Comparable key;
for(j=1;j<a.size();j++){
key = a.get(j);
i=j-1;
while(i>=0 && comp.compare(a.get(i), key) >0){
i--;
}
Collections.rotate(a.subList(i+1,j+1),1);
}
}
}
</pre>下面是各种数据类型的简单插入排序的测试程序:<pre name="code" class="java">package intdata.InsertionSort;
import java.util.*;
public class Test1 {
/*public static void main(String args[]){
int A[] = {5,7,1,9,2,44,52,10,3,8,100};
int i;
Sort.insertionSort(A);
for(i=0;i<A.length;i++)
System.out.print(A[i]+" ");
System.out.println();
}
public static void main(String args[]){
Integer[] a = {5,1,9,3,46,90,19,100};
String[] b = {"shangdong","beijing","xian","shanghai","xiameng","wuhan"};
Double[] c = {8.5,9.3,71.3,90.2,10.5,82.1,3.2};
int i;
Sort.insertionSort(a);
for(i=0;i<a.length;i++)
System.out.print(a[i]+" ");
System.out.println();
Sort.insertionSort(b);
for(i=0;i<b.length;i++)
System.out.print(b[i]+" ");
System.out.println();
Sort.insertionSort(c);
for(i=0;i<c.length;i++)
System.out.print(c[i]+" ");
System.out.println();
}
public static void main(String args[]){
Integer[] a = {5,1,9,3,46,90,19,100};
String[] b = {"shangdong","beijing","xian","shanghai","xiameng","wuhan"};
Double[] c = {8.5,9.3,71.3,90.2,10.5,82.1,3.2};
int i;
ArrayList<Integer> A = new ArrayList<Integer>();
for(i=0;i<a.length;i++)
A.add(a[i]);
Vector<String> B = new Vector<String>();
for(i=0;i<b.length;i++)
B.add(new String(b[i]));
LinkedList<Double> C = new LinkedList<Double>();
for(i=0;i<c.length;i++)
C.add(c[i]);
Sort.insertionSort((List)A);
System.out.println(A);
Sort.insertionSort((List)B);
System.out.println(B);
Sort.insertionSort((List)C);
System.out.println(C);
}*/
public static void main(String[] args){
//jvm 内存架构 堆内存 栈内存,字符池
// String aa = "abc";
// String bb = "abc";
// String cc = new String("abc");
// System.out.println(cc==bb);
int[] a = {5,1,9,3,46,90,19,100,11,65};
String[] b = {"shangdong","beijing","xian","shanghai","xiameng","wuhan"};
Double[] c = {8.5,9.3,71.3,90.2,10.5,82.1,3.2};
int i;
// 自动封箱int-->integer
ArrayList<Integer> A = new ArrayList<Integer>();
for(i=0;i<a.length;i++){
A.add(a[i]);
}
Vector<String> B = new Vector<String>();
for(i=0;i<b.length;i++)
B.add(new String(b[i]));
LinkedList<Double> C = new LinkedList<Double>();
for(i=0;i<c.length;i++)
C.add(c[i]);
Sort.insertionSort((List)A,new Greater());
System.out.println(A);
Sort.insertionSort((List)B,new Less());
System.out.println(B);
Sort.insertionSort((List)C,new Less());
System.out.println(C);
}
}
2 中级的排序算法:归并排序
这里所谓的中级排序算法是指在算法的时间复杂度上比较优秀的算法,那就是基于递归思想的的归并排序。归并排序在速度上比简单排序快的多,时间复杂度为O(N*logN),但空间上需要一个大小等于原来数组的工作空间。
未完待续~~~~中级排序和高级排序算法内容在:算法学习----各种排序算法的实现和对比2中