排序算法

1.冒泡排序
2.选择排序
3.插入排序
4.快速排序
5.堆排序
6.希尔排序
7.归并排序
8.计数排序
9.桶排序
10.基数排序

该篇排序方式:由小到大排序
1.冒泡排序
从后向前冒泡
从前向后冒泡

由小到大,从后向前冒泡:[90,78,65,43,20]
一次冒泡
第一次比较:[90,78,65,20,43] 一次交换操作
第二次比较:[90,78,20,65,43] 一次交换操作
第三次比较:[90,20,78,65,43] 一次交换操作
第四次比较:[20,90,78,65,43] 一次交换操作
二次冒泡
第一次比较:[20,90,78,43,65] 一次交换操作
第二次比较:[20,90,43,78,65] 一次交换操作
第三次比较:[20,43,90,78,65] 一次交换操作
三次冒泡
第一次比较:[20,43,90,65,78] 一次交换操作
第二次比较:[20,43,65,90,78] 一次交换操作
四次冒泡
第一次比较:[20,43,65,78,90] 一次交换操作
共十次交换操作
1.最后一个元素与相邻元素对比
2.小于相邻元素,则交换
3.大于等于相邻元素,无需交换,继续相邻元素的对比
4.直到与最左边的元素对比完成,一次冒泡结束
5.对剩下的序列,重复1~4的步骤
6.直到剩下的序列长度为1,整个冒泡结束

1.不使用递归实现

/**
 * 冒泡排序
 * 
 * 由小到大排序
 * 
 * 从后向前冒泡
 * 
 * @param arr
 */
public void bubbleSort(int[] arr) {
    if (arr == null || arr.length == 0)
        return;
    for (int i = 0; i < arr.length - 1; i++) {
        for (int j = arr.length - 1; j > i; j--) {
            if (arr[j] < arr[j - 1]) {
                swap(arr, j - 1, j);
            }
        }
    }
}

public void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

2.使用递归方式实现

/**
*
*冒泡排序函数
*/
public void sortByBubble(int[] paramInts) {
   sortByBubble(paramInts, 0);
}

/**
*
*冒泡排序的辅助方法
*paramInts:排序的数组对象
*index:序列最左边下标
*/
private void sortByBubble(int[] paramInts, int index) {
    if (index == paramInts.length - 1) {
        return;
    }
    for (int i = paramInts.length - 1; i > index; i--) {
        if (paramInts[i] < paramInts[i - 1]) {
            int tempValue = paramInts[i];
            paramInts[i] = paramInts[i - 1];
            paramInts[i - 1] = tempValue;
        }
    }
    sortByBubble(paramInts, index + 1);
}

从前向后冒泡
1.第一个元素与相邻的元素对比
2.小于相邻元素,则交换
3.大于等于相邻元素,无需交换,继续相邻元素的对比
4.直到与最右边元素对比完成,一次冒泡结束
5.对剩下的序列,重复1~4的步骤
6.直到剩下的序列长度为1,完成整个数组的冒泡

1.一次冒泡过程不使用递归实现

public void sortByBubble(int[] paramInts) {
    sortByBubble(paramInts, paramInts.length - 1);
}
/**
*
*由前向后冒泡排序的辅助方法
*paramInts:排序数组对象
*index:序列最右边的下标
*/
private void sortByBubble(int[] paramInts, int index) {
    if (index == 0) {//没有可冒泡的序列了
        return;
    }
    for (int i = 0; i < index; i++) {
        if (paramInts[i + 1] > paramInts[i]) {//小于相邻元素
            //与相邻元素交换
            int tempValue = paramInts[i];
            paramInts[i] = paramInts[i + 1];
            paramInts[i + 1] = tempValue;
        } 
    }
    sortByBubble(paramInts, index - 1);
}

2.一次冒泡过程使用递归代替for语句实现

/**
*
*冒泡排序
*
*使用递归方法实现
*/
private void sortByBubblinf(int[] paramInts) {
    sortByBubbling(paramInts, 0, paramInts.length - 1);
}
/**
*
*冒泡排序递归实现的辅助方法
*paramInts:排序的数组对象
*index:对比到元素的下标
*minInex:序列最右边元素下标
*/
private void sortByBubbling(int[] paramInts, int index, int minIndex)  {
    if (minIndex == 0) {//左边没有可对比的相邻元素
        return;
    } else if (index == minIndex) {//没有可对比的元素
        //重复1~5步骤
        sortByBubbling(paramInts, 0, minIndex - 1);
    } else if (paramInts[index] < paramInts[index + 1]) {
        //小于相邻元素,与相邻元素交换
        int temp = paramInts[index];
        paramInts[index] = paramInts[index + 1];
        paramInts[index + 1] = temp;
        sortByBubbling(paramInts, index + 1, minIndex); 
    } else {
        //大于等于相邻元素,重复步骤1~3
        sortByBubbling(paramInts, index + 1, minIndex);
    }  
}

介绍完冒泡排序,讲解一下冒泡的时间复杂度
冒泡排序的时间复杂度为O(n^2)

时间复杂度
计算方法
1.一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。
分析:随着模块n的增大,算法执行的时间的增长率和 f(n) 的增长率成正比,所以 f(n) 越小,算法的时间复杂度越低,算法的效率越高。

冒泡排序的时间复杂度计算过程:
冒泡排序是一种用时间换空间的排序方法,最坏情况是把顺序的排列变成逆序,或者把逆序的数列变成顺序。
在这种情况下,每一次比较都需要进行交换运算。
举个例子来说,一个数列 5 4 3 2 1 进行冒泡升序排列,
第一次大循环从第一个数(5)开始到倒数第二个数(2)结束,
比较过程:先比较5和4,4比5小,交换位置变成4 5 3 2 1;
比较5和3,3比5小,交换位置变成4 3 5 2 1
……
最后比较5和1,1比5小,交换位置变成4 3 2 1 5。
这时候共进行了4次比较交换运算,最后1个数变成了数列最大数。
第二次大循环从第一个数(4)开始到倒数第三个数(2)结束。进行3次比较交换运算。
……
所以总的比较次数为 4 + 3 + 2 + 1 = 10次对于n位的数列则有比较次数为 (n-1) + (n-2) + ... + 1 = n * (n - 1) / 2,这就得到了最大的比较次数而O(N^2)表示的是复杂度的数量级。
举个例子来说,如果n = 10000,那么 n(n-1)/2 = (n^2 - n) / 2 = (100000000 - 10000) / 2,相对10^8来说,10000小的可以忽略不计了,所以总计算次数约为0.5 * N2。用O(N2)就表示了其数量级(忽略前面系数0.5)。

2.选择排序
[90,78,65,43,20]
一次选择[20, 78, 65, 43, 90] 一次交换操作
二次选择:[20, 43, 65, 78, 90] 一次交换操作
三次选择:[20, 43, 65, 78, 90] 0次交换操作
四次选择:[20, 43, 65, 78, 90] 0次交换操作
共两次交换操作
1.查找序列中的最小元素与序列最左边元素交换
2.剩下的序列中,重复1步骤
3.直到序列的长度为1,完成排序

/**
*选择排序
*/
public void sortByCulling(int[] paramInts) {
    sortByCulling(paramInts, 0);
}
/**
*选择排序辅助方法
*paramInts:排序的数组对象
*index:序列最左边元素的下标
*
*/
private void sortByCulling(int[] paramInts, int index) {
    if (index == paramInts.length - 1) {
        return;
    } 
    //查询序列中的最小元素
    int tempIndex = index;
    int tempValue = paramInts[tempIndex];
    //扫描序列中的元素
    for (int i = index + 1; i < paramInts.length; i++) {
        if ( paramInts[i] < tempValue) {//找到更小的元素
            //记录下最小元素及下标
            tempValue = paramInts[i];
            tempIndex = i;
        }
    }
    //扫描完序列
    //判断最小元素是否是序列最左边的元素
    if (tempIndex != index) {//不是
        //交换元素
        paramInts[tempIndex] = paramInts[index];
        paramInts[index] = tempValue;
    }  
    //调用函数本身
    sortByCulling(paramInts, index + 1);
}

3.插入排序
[90,78,65,43,20]
一次插入
[78, 90, 65, 43, 20] 一次交换操作
二次插入
[78, 65, 90, 43, 20] 一次交换操作
[65, 78, 90, 43, 20] 一次交换操作
三次插入
[65, 78, 43, 90, 20] 一次交换操作
[65, 43, 78, 90, 20] 一次交换操作
[43, 65, 78, 90, 20] 一次交换操作
四次插入:
[43, 65, 78, 20, 90] 一次交换操作
[43, 65, 20, 78, 90] 一次交换操作
[43, 20, 65, 78, 90] 一次交换操作
[20, 43, 65, 78, 90] 一次交换操作
共十次交换操作
1.从第一个元素开始,该元素认定为已经被排序
2.取出下一个元素与已经排序的元素从后向前依次对比
3.如果取出的元素小与对比的元素,则交换
4.直到大于等于对比的元素则停止
5.重复2~4的步骤
6.直到没有可取出的元素为止

/**
*插入排序函数
*
*/
public void sortByInsertionCulling (int[] paramInts) {
    sortByInsertionCulling(paramInts, 1);
}
/**
*插入排序辅助方法
*paramInts:排序数组对象
*index:取出元素的下标
*/
private void sortByInsertionCulling(int[] paramInts, int index) {
    if (index == paramInts.length) {//取出元素的下标已经超出数组的长度,已经没有可取的元素
        return;
    }
    //取出下标为index的元素
    int tempValue = paramInts[index];
    //记录取出元素的下标
    int tempIndex = index;
    //取出的元素与已经排序的元素从后向前依次对比
    for (int i = index - 1; i >= 0; i--) {
        if (tempValue < paramInts[i]) {//取出的元素小于当前元素
            //与当前元素交换
            paramInts[tempIndex] = paramInts[i];
            paramInts[i] = tempValue;
            tempIndex = i;
        } else {//小于等于取出的元素
            //停止对比
            break;
        }
    }
    //重复2~4步骤,调用函数本身
    sortByInsertionCulling(paramInts, index + 1);
}

快速排序
基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列
[90,78,65,43,20]
一趟快速排序
[20, 78, 65, 43, 90] 一次交换操作
两趟快速排序
[20, 78, 65, 43, 90] 0次交换操作
三趟快速排序
[20, 43, 65, 78, 90] 一次交换操作
四趟快速排序
[20, 43, 65, 78, 90] 0次交换操作
共两次交换操作
参考文章一
参考文章二

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容

  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 5,149评论 0 52
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 3,723评论 0 15
  • 概述排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的...
    Luc_阅读 2,247评论 0 35
  • 一、概述 排序算法概念 在计算机科学与数学中,一个排序算法是将一组杂乱无章的数据按一定的规律顺次排列起来的算法。排...
    简书冷雨阅读 1,008评论 0 0
  • 今天,忽而想起了小蕊子,一头乌黑的短发,乌溜溜的大眼睛,高挺的鼻梁,一张大厚嘴唇向外翻着。 不记得她...
    yeyingzi阅读 229评论 0 0