您的位置:首页 > 其它

排序总结(1)---冒泡排序、选择排序、插入排序、希尔排序

2017-05-05 19:52 633 查看

排序总结(1)—冒泡排序、选择排序、插入排序、希尔排序

最近温习一下各排序算法,代码块中有详细的注释,test函数在结尾处

先来总结一下排序的时间复杂度、空间复杂度、稳定性

稳定的排序

稳定的排序时间复杂度空间复杂度
冒泡排序最差、平均都是O(n2),最好是O(n)1
双向冒泡排序最差、平均都是O(n2),最好是O(n)1
插入排序最差、平均都是O(n2),最好是O(n)1
归并排序最差、平均、最好都是O(nlogn)O(n)
桶排序O(n)O(k)
基数排序O(dn),d为常数O(n)
二叉树排序O(nlogn)O(n)
图书馆排序O(nlogn),最坏O(n2)O(n)
不稳定排序

不稳定的排序时间复杂度空间复杂度
选择排序最差、平均都是O(n2)1
希尔排序O(nlogn)1
堆排序最差、平均、最好情况都是O(nlogn)1
快速排序平均是O(nlogn),最坏情况是O(n2)O(nlogn)
冒泡排序:

/**
* @ClassName BublleSort
* @Description 冒泡排序 最好的时间复杂度:O(n) 最坏的时间的复杂度O(n2) 平均时间复杂度O(n2)
* 算法为就地排序,是稳定的排序算法
* @author yj
*/
public class BubbleSort {
/**
* 冒泡排序
* @param source needed sort array
*/
public static void bubbleSort(int[] source){
for(int i = 0;i < source.length-1;i++){//循环每一趟排序
for(int j = 0;j<source.length -i-1;j++){//一趟排序中
if(source[j]>source[j+1])swap(source,j,j+1);
}
}

}
/**
* 升级的冒泡排序<br>
* 加入了交换标识的冒泡排序,如果一趟排序中没有发生数据交换说明已经排序完成,
* 此时交换标识为false,在这一趟排序后提前终止算法
* @param source
*/
public static void bubbleSort2(int[] source){
boolean exchange;//交换标识,如果没有发生交换说明已经排序完成
for(int i = source.length-1;i>0;i--){//一趟排序
exchange = false;//每一次排序前设置为false
for(int j = 0;j<i;j++){
if(source[j]>source[j+1]){
swap(source,j,j+1);
exchange = true;//发生交换就设置为true
}
}
if(!exchange)//没有发生交换,终止
return ;
}
}
/**
* swap to number in the array
* @param source 需要交换的数组数据
* @param x the index of the number who needed swap in the array
* @param y 需要交换的数据在source中的位置
*/
public static void swap(int[] source,int x, int y){
int temp = source[x];
source[x] = source[y];
source[y] = temp;
}
}


选择排序:

/**
* 选择排序<br>
* 平均复杂度为O(n2),不稳定的排序
* @author hp
*
*/
public class SelectSort {
/**
* 每次循环找出最小值并记录下标index,如果标志位index与i不同,
* 就将位置为index的数据与位置为i的数据交换
* @param source
*/
public static void selectSort(int[] source) {
int index;// 下标标识,记录未排序序列中最小值
for (int i = 0; i < source.length - 1; i++) {//每次循环找出最小值并记录下标
index = i;// 记录未排序的第一个开始位置,进行比较
for (int j = i + 1; j < source.length; j++) {//循环找出未排序最小值记录到index
if(source[j]<source[index])index = j;
}
if(index != i){//如果标识不等于当前循环未排序的首位,说明有比首位更小的数字,进行交换
swap(source,i,index);
}
}
}

/**
* swap to number in the array
*
* @param source 需要交换的数组数据
* @param x the index of the number who needed swap in the array
* @param y 需要交换的数据在source中的位置
*/
public static void swap(int[] source, int x, int y) {
int temp = source[x];
source[x] = source[y];
source[y] = temp;
}
}


插入排序:

/**
* 平均算法复杂度O()n2
* @author hp
*
*/
public class InsertSort {
/**
* 插入排序
* @param source
*/
public static void insertSort(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);
}
}
}
/**
* swap to number in the array
*
* @param source 需要交换的数组数据
* @param x the index of the number who needed swap in the array
* @param y 需要交换的数据在source中的位置
*/
public static void swap(int[] source, int x, int y) {
int temp = source[x];
source[x] = source[y];
source[y] = temp;
}
}


希尔排序:

为了更清晰体现希尔排序的过程,在算法中插入了打印函数,每次数据交换都能清晰明了

/**
* 时间复杂度O(nlogn),不稳定排序
* 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。
* 所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;
* 然后,取第二个增量d2<d1重复上述的分组和排序,
* 直至所取的增量  =1(  <  …<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
* @author hp
*
*/
public class ShellSort {
public static void shellSort(int[] source){
int len = source.length;
for(len = len/2;len!=0;len/=2){//初始时取长度的一半为间隔长度,每次减半直到为0
for(int i = len;i<source.length;i++){//从每组的第二个位置开始,依次向前插入操作,然后循环到每组的第三个位置。。。
for(int j = i;(j-len)>=0&&source[j-len]>source[j];j-=len){//插入排序中的核心部分---向前比较、判断条件是否成立并交换
swap(source,j-len,j);
spy(source);//观察每次交换的情况
}
}
}
}
/**
* 方便观察每次排序的,可以窥探数组排序的情况
* @param source
*/
public static void spy(int[] source){
for(int k = 0;k<source.length;k++){
System.out.printf("%3s ",source[k]);
}
System.out.println();
}
/**
* swap to number in the array
*
* @param source 需要交换的数组数据
* @param x the index of the number who needed swap in the array
* @param y 需要交换的数据在source中的位置
*/
public static void swap(int[] source, int x, int y) {
int temp = source[x];
source[x] = source[y];
source[y] = temp;
}
}


测试一下:

public static void main(String[] args) {
int a[] = {4,2,1,6,3,6,0,-5,1,1};
System.out.println("排序前:  ");
for(int i = 0; i < 10; i++){
System.out.print(a[i]+"  ");
}
System.out.println("\n排序后:");
ShellSort.shellSort(a);
}


希尔排序的运行结果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐