java排序算法小结
本文和大家讨论交流常见的排序算法。包括冒泡排序、选择排序、插入排序、归并排序、希尔排序、快速排序、基数排序等7种排序算法。阐述基本原理和各算法的特点,并做一些简单的分析和归纳。
(一)冒泡排序
①算法原理
重复地访问待排序的元素集,依次比较两个相邻元素,如果它们的顺序错误就交换顺序,直到排序完毕。
②java实现
//冒泡排序
public static void bubbleSort(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - i -1; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
测试:
③优缺点
优点:从概念和实现上来讲最简单,是稳定的排序算法;
缺点:冒泡排序算法运行起来较慢,每次只能移动相邻两个元素。
(二)选择排序
①算法原理
每一次从待排序的元素集中选出最小(大)的一个元素,存放在起始位置,直到排序完毕。
②java实现
//选择排序
public static void selectSort(int[] array) {
int min=0;
int temp=0;
for(int i=0;i<array.length;i++){
min=i;
for(int j=i+1;j<array.length;j++) {
if(array[j]<array[min]){
min=j;
}
}
temp=array[i];
array[i]=array[min];
array[min]=temp;
}
}
测试:
③优缺点
优点:相较而言,移动元素次数较少且已知(n-1);
缺点:比较次数多,是不稳定的排序算法。
(三)插入排序
①算法原理
将一系列记录插入到已排序好的有序表中,得到一个新有序表。
②java实现
//插入排序
public static void insertionSort(int[] array) {
for(int i = 1; i<array.length; i++){
int temp = array[i];
int j = i-1;
while(j>=0 && array[j]>temp){
array[j+1] = array[j];
j--;
}
array[j+1] = temp;
}
}
测试:
③优缺点
优点:排序效率相对较快,是稳定的排序算法;
缺点:比较次数不一定,比较次数越少,插入点后的数据移动越多,特别是当数据总量庞大的时候。
(四)归并排序
①算法原理
将已有序的子序列合并,得到完整有序的序列。
②java实现
//归并排序
public static void mergeSort(int[] array) {
for(int out =1;out<array.length;out++) {
int temp =array[out];
int j = out;
while (j>0 && array[j-1] >= temp) {
array[j] = array[j-1];
--j;
}
array[j] = temp;
}
}
测试:
③优缺点
优点:相较其他几种算法速度快,是稳定的排序算法
缺点:需要在存储器中有一个与排序数据等长的数组,占用空间较大。
(五)希尔排序
①算法原理
把待排序的序列看做一个矩阵的形式,对矩阵的子序列分别进行插入排序,得到完整的排序后的序列。
②java实现
//希尔排序
public static void shellSort(int[] array) {
if(array == null || array.length <= 1){
return;
}
int num = array.length/2;
while(num >=1){
for(int i=0;i<array.length;i++){
for(int j=i;j<array.length-num;j=j+num){
if(array[j]>array[j+num]){
int temple = array[j];
array[j] = array[j+num];
array[j+num] = temple;
}
}
}
num = num/2;
}
}
测试:
③优缺点
优点:排序速度快;
缺点:是不稳定的排序算法。
(六)快速排序
①算法原理
把待排序的序列划分为两个子序列,然后递归地调用自身为子序列排序,得到整个排序后的序列。
②java实现
//快速排序
public static void fastSort(int[] array,int l,int h) {
if( l > h) {
return;
}
int i = l;
int j = h;
int key = array[l];
while( i< j) {
while(i<j && array[j] > key){
j--;
}
while( i<j && array[i] <= key) {
i++;
}
if(i<j) {
int p = array[i];
array[i] = array[j];
array[j] = p;
}
}
int p = array[i];
array[i] = array[l];
array[l] = p;
fastSort(array, l, i-1 );
fastSort(array, i+1, h);
}
public static void fastSort(int[] array) {
if(array.length>0) {
fastSort(array, 0 , array.length-1);
}
}
测试:
③优缺点
优点:大多数情况下,速度最快;
缺点:是不稳定的排序算法。
(七)基数排序
①算法原理
将待排序的所有数值元素统一数位长度,从最低位开始依次排序,得到整个排序后的序列。
②java实现
//基数排序
public static void radixSort(int[] array) {
int exp;
int max = getMax(array);
for (exp = 1; max/exp > 0; exp *= 10) {
countSort(array, exp);
}
}
private static void countSort(int[] array,int exp) {
int[] out = new int[array.length];
int[] buckets = new int[10];
for (int i = 0; i < array.length; i++) {
buckets[ (array[i]/exp)%10 ]++;
}
for (int i = 1; i < 10; i++) {
buckets[i] += buckets[i - 1];
}
for (int i = array.length - 1; i >= 0; i--) {
out[buckets[ (array[i]/exp)%10 ] - 1] = array[i];
buckets[ (array[i]/exp)%10 ]--;
}
for (int i = 0; i < array.length; i++) {
array[i] = out[i];
}
out = null;
buckets = null;
}
private static int getMax(int[] a) {
int max;
max = a[0];
for (int i = 1; i < a.length; i++) {
if (a[i] > max) {
max = a[i];
}
}
return max;
}
测试:
③优缺点
优点:是稳定的排序算法;
缺点:有一定局限性,主要用来比较有符号数值。
分析与归纳:
一、稳定性方面:
稳定的排序算法:冒泡排序、插入排序、归并排序、基数排序;
不稳定的排序算法:选择排序、希尔排序、快速排序。
二、时间复杂度方面:
线性阶(O(n)):基数排序;
线性对数阶(O(nlog2n)):快速排序、归并排序;
指数阶(O(n^(1+§)),§∈[0,1]):希尔排序、插入排序、冒泡排序、选择排序。
排序算法在很多科研领域都有重要应用,特别是在处理大量数据场景。优秀的算法设计可以节省大量的时间和空间,极大提高生产工作、科研学习的效率。