数据结构 -- 基本排序算法
算法学习 -- 基本排序算法
算法总述:
1、冒泡排序
2、插入排序
3、选择排序
4、快速排序
5、归并排序
6、希尔排序
7、堆排序
8、基数排序
1、冒泡排序算法
冒泡排序算法,又称之为相邻交换排序法,就像是水中的泡泡一样,大的泡泡向上浮动,就像是待排序中的最大数在最后一样。
算法思路:待排序的序列中,数字之间两两比较,若相邻的元素大小顺序有误,就将其交换,如此,将序列扫描一遍,就能将最大的元素排在后面,一共将会循环排序(n个元素-1)次。
算法代码:
/** * 冒泡排序 */ public class Demone1 { public static void main(String[] args) { int[] arrary = new int[]{2,6,1,4,8,3,9,5}; bubbling(arrary); } private static void bubbling(int[] arrary) { int temp = 0; // 一共需要循环扫描 n - 1 次 ,没循环一次将最大的元素放在最后,所以最后的元素就不必在参与比较 for (int i = arrary.length - 1; i > 0; i--) { for (int j = 0; j < i; j++) { // i : 7、6、5、4、3、2、1 if (arrary[j] > arrary[j + 1]) { temp = arrary[j]; arrary[j] = arrary[j + 1]; arrary[j + 1] = temp; } } /** * 输出每一遍的扫描结果 */ printArray(arrary); } } public static void printArray(int[] array) { for (int i = 0; i < array.length; i++) { System.out.print(array[i] + "\t"); } System.out.println(); } }
算法结果:

问题:由结果可以看出来,前三次,就排序好了,但是还是无脑的走了后面的四次步骤。可见算法还不是很好。
改进:冒泡算法(二)
改进的算法思路:就是定义一个变量,用于监控,是否每一次循环扫描是否有数字进行了交换,若是发现已经不需要交换了(即count==0),即退出。
/** * 改进版 */ public class Demone1 { public static void main(String[] args) { int[] arrary = new int[]{2,6,1,4,8,3,9,5}; bubbling(arrary); } private static void bubbling(int[] arrary) { int temp = 0; // 一共需要循环扫描 n - 1 次 ,没循环一次将最大的元素放在最后,所以最后的元素就不必在参与比较 for (int i = arrary.length - 1; i > 0; i--) { int count = 0;//记录交换的次数,因为只有需要交换才是值得花时间的,若是发现已经不需要就直接退出循环扫描。 for (int j = 0; j < i; j++) { // i : 7、6、5、4、3、2、1 if (arrary[j] > arrary[j + 1]) { temp = arrary[j]; arrary[j] = arrary[j + 1]; arrary[j + 1] = temp; count++; } } /** * 输出每一遍的扫描结果 */ if (count == 0) { break; } printArray(arrary); } } public static void printArray(int[] array) { for (int i = 0; i < array.length; i++) { System.out.print(array[i] + "\t"); } System.out.println(); } }
算法结果:

算法分析(时空复杂度):
冒泡排序中,n 个元素需要进行 n-1 次扫描。
最好情况下:就是一边扫描过去后,不需要交换,只进行了 n-1 次比较,时间复杂度为 O(n)
最坏情况下和平均情况下:需要进行 (n - 1) + (n - 2) + (n - 3) + ... + 3 + 2 + 1 = n (n - 1) / 2 即时间复杂度 O(n^2)
算法稳定性:当两个数字相同时,不会进行交换顺序的,所以就不会出现算法不稳定性。
2、插入排序算法
算法思路:插入排序,就是将数组中的元素逐一与已经排好序的数列进行比较,然后放在适当的位置。考虑的角度,可以是由后往前考虑,前面是已经排好序的数列,后面是还未排序的数组。角度刚好与选择排序的角度相反,选择排序的角度是由前往后,前面是已经排好的顺序,后面是待排序的数组。
算法代码:
/** * 插入排序 */ public class Demone2 { public static void main(String[] args) { int[] arrary = new int[]{2,6,1,4,8,3,9,5}; insertSort(arrary); } private static void insertSort(int[] arrary) { // 需要循环 n - 1 次 ,从第2个元素开始,因为第一个元素没有必要,无意义。 for (int i = 1; i < arrary.length; i++) { int temp = arrary[i]; // 暂存数据 int j = i - 1; // 得到当前元素的前一个元素的下标,用于后期可以循环后移数据 while (j >= 0 && temp < arrary[j]) { arrary[j + 1] = arrary[j]; j--; } /** * 最小的元素放在适当的位置,前面的 j-- 将会多减一个1,所以在这加上1就是适当的位置,例如:2、6、4 ,4就会放在2、6之间 * j 会减到 0,但是应该放在的位置是 1 则需要加 1 */ arrary[j + 1] = temp; } printArray(arrary); } public static void printArray(int[] array) { for (int i = 0; i < array.length; i++) { System.out.print(array[i] + "\t"); } System.out.println(); } }
算法结果:

算法分析(时空复杂度):
最好情况下:就是一边扫描过去后,不需要交换,只进行了 n-1 次比较,时间复杂度为 O(n)
最坏情况下与平均情况下:需要进行 (n - 1) + (n - 2) + (n - 3) + ... + 3 + 2 + 1 = n (n - 1) / 2 即时间复杂度 O(n^2)
算法稳定性:算法稳定,因为只有小于才会交换,而两个数相同时,不会交换,则算法稳定。
空间复杂度:只需要使用变量就可以,则空间复杂度最佳。
3、选择排序算法
算法思路:选择排序就是从未排序的数字序列中,挑选一个最小的数,与当前的元素进行比较,若当前的数大于最小的数,就进行交换,反之就不交换,当前的元素向前移动。
算法代码:
/** * 选择排序 */ public class Demone3 { public static void main(String[] args) { int[] arrary = new int[]{2, 6, 1, 4, 8, 3, 9, 5}; choiceSort(arrary); } private static void choiceSort(int[] arrary) { /** * 循环 n - 1 次,最后一个元素不需要循环。 */ int minNum = 0; int index = 0; for (int i = 0; i < arrary.length - 1; i++) { minNum = arrary[i];//记录最小值,与后边的数据进行比较 index = i;// 记录当前的元素的下标 for (int j = i + 1; j < arrary.length; j++) { if (arrary[j] < minNum) { minNum = arrary[j]; index = j; } } int temp = arrary[index]; arrary[index] = arrary[i]; arrary[i] = temp; printArray(arrary); } } public static void printArray(int[] array) { for (int i = 0; i < array.length; i++) { System.out.print(array[i] + "\t"); } System.out.println(); } }
算法结果:

算法分析(时空复杂度):
最好情况下、最坏情况下与平均情况下:(由于都是需要扫描每一个元素,并且还要扫描该元素后面的所有的元素,比较大小)都是需要进行比较 (n - 1) + (n - 2) + (n - 3) + ... + 3 + 2 + 1 = n (n - 1) / 2。时间复杂度:O(n^2)
算法稳定性:由于该算法的思想是,将当前元素后的未排序的元素进行选择比较出最下的,与元素交换,数据的排列有可能会改变。比如:他是扫描未排序的全部的元素比较大小,现在有两个7(前)、7(后),最后将7(后)添加到了头,所以就会出现算法的不稳定性。
空间复杂度:由于只是使用了一个额外的空间,空间复杂度为:O(1),为最佳。
4、快速排序算法
算法思路:
算法代码:
算法分析(时空复杂度):
5、归并排序算法
算法思路:
算法代码:
算法分析(时空复杂度):
6、希尔排序算法
算法思路:
算法代码:
算法分析(时空复杂度):
7、堆排序算法
算法思路:
算法代码:
算法分析(时空复杂度):
8、基数排序算法
算法思路:
算法代码:
算法分析(时空复杂度):

浙公网安备 33010602011771号