当前位置:   article > 正文

四大排序——冒泡排序、选择排序、插入排序、堆排序_冒泡排序 堆排序 直接选择排序 直接插入排序

冒泡排序 堆排序 直接选择排序 直接插入排序

一、冒泡排序

1、解释:

冒泡排序是一种基于比较交换操作的排序算法

每轮冒泡的过程都是从第一个元素开始,将该元素和相邻下一个元素进行比较交换,使得较大的元素向右移动(如果该元素大于下一个元素,则两个元素交换;如果该元素小于等于下一个元素,则保持不变)。

这样一来,每轮冒泡的过程都可以确定一个元素放在正确的位置上,而这个元素就是剩余元素中最大的元素,正确的位置就是剩余位置中的最右侧的位置。这个过程就像是气泡上浮一样,所以叫做冒泡排序。

2、思想:

它的基本思想是对所有相邻记录的关键字值进行比效,如果是逆顺(a[j]>a[j+1]),则将其交换,最终达到有序化;

3、图解:

4、性能特点:

5、 代码解释——python

  1. def bubbleSort(arr):
  2. for i in range(1, len(arr)):
  3. l = 0 # 记录左边元素下标
  4. r = len(nums) - 1 # 记录右边元素下标
  5. flag = False # 设置标志位,判断当前趟次是否有元素交换
  6. # 正向排序最大值
  7. for j in range(l, r):
  8. if arr[j] > arr[j + 1]:
  9. arr[j], arr[j + 1] = arr[j + 1], arr[j]
  10. flag = True
  11. if not flag:
  12. break
  13. # 反向排序最小值
  14. for j in range(r, l, -1):
  15. if arr[j] < arr[j - 1]:
  16. arr[j], arr[j - 1] = arr[j - 1], arr[j]
  17. print(nums)
  18. return arr
  19. if __name__=="__main__":
  20. nums = [1, 42, 65, 876, 34, 656, 4, 6757, 89, 24, 65, 42]
  21. print("start:", nums)
  22. print("冒泡 :", bubbleSort(nums))

 (两个for语句的使用——python)

  1. """
  2. Python冒泡排序
  3. 两个for
  4. """
  5. s = list(map(int,input().split(" ")))# 输入列表,以空格分隔,返回列表。
  6. for i in range(len(s)):
  7. for j in range(len(s)-i-1):
  8. if s[j] > s[j+1] :# 此为判断是否大于后一个数,大于就换(升序判断),如果想是降序,就把">"改成"<"
  9. s[j], s[j+1] = s[j+1], s[j]
  10. for i in s:
  11. print(i,end=" ")# 输出

二、选择排序

1、解释

选择排序(Selection sort)是一种简单直观的排序算法

选择排序首先从待排序列表中找到最小(大)的元素,存放到元素列表的起始位置(与起始位置进行交换),作为已排序序列,第一轮排序完成。

然后,继续从未排序序列中找到最小(大)的元素,存放到已排序序列的末尾。直到所有元素都存放到了已排序序列中,列表排序完成。

选择排序每次都是去找最小(大)的元素,隐含了一种挑选的过程,所以被称为选择排序。
 

2、思想

1. 从待排序列表中找到最小的元素(升序排列,降序排列则找最大的元素),存放到列表的起始位置,作为已排序的序列。

2. 继续从未排序序列中找到最小的元素,存放到已排序序列的末尾(同时也是未排序序列的起始位置)。

3. 重复第2步,直到所有元素都已经存放到了已排序序列,则列表排序完成。
 

3、图解

4、性能特点

5、代码解释

(1)升序选择排序

  1. # 选择排序
  2. def selectionSort(arr):
  3. for i in range(len(arr) - 1):
  4. minIndex = i # 记录最小元素的索引
  5. # 找出最小元素
  6. for j in range(i + 1, len(arr)):
  7. if arr[j] < arr[minIndex]:
  8. minIndex = j
  9. # i不是最小元素时,将i和最小元素进行交换
  10. if i != minIndex:
  11. arr[i], arr[minIndex] = arr[minIndex], arr[i]
  12. return arr
  13. if __name__=="__main__":
  14. nums = [1, 42, 65, 876, 34, 656, 4, 6757, 89, 24, 65, 42]
  15. print("start:", nums)
  16. print("冒泡 :", selectionSort(nums))

(2)降序选择排序

  1. # 选择排序
  2. def selectionSort(arr):
  3. for i in range(len(arr) - 1):
  4. maxIndex = i # 记录最大元素的索引
  5. # 找出最大元素
  6. for j in range(i + 1, len(arr)):
  7. if arr[j] > arr[maxIndex]:
  8. maxIndex= j
  9. # i不是最大元素时,将i和最大元素进行交换
  10. if i != maxIndex:
  11. arr[i], arr[maxIndex] = arr[maxIndex], arr[i]
  12. return arr
  13. if __name__=="__main__":
  14. nums = [1, 42, 65, 876, 34, 656, 4, 6757, 89, 24, 65, 42]
  15. print("start:", nums)
  16. print("冒泡 :", selectionSort(nums))

(3)java

  1. public static void selectionSort(int[] arr) {
  2. /*判断数组为空或为一个元素的情况,即边界检查*/
  3. if (arr == null || arr.length < 2) {
  4. return;
  5. }
  6. /*每次要进行比较的两个数,的前面那个数的下标*/
  7. for (int i = 0; i < arr.length - 1; i++) {
  8. //min变量保存该趟比较过程中,最小元素所对应的索引,
  9. //先假设前面的元素为最小元素
  10. int minIndex = i;
  11. /*每趟比较,将前面的元素与其后的元素逐个比较*/
  12. for (int j = i + 1; j < arr.length; j++) {
  13. //如果后面的元素小,将后面元素的索引极为最小值的索引
  14. if(arr[j] < arr[minIndex]) {
  15. minIndex = j;
  16. }
  17. }
  18. //然后交换此次查找到的最小值和原始的最小值
  19. swap(arr, i, minIndex);
  20. }
  21. }
  22. public static void swap(int[] arr, int i, int j) {
  23. int tmp = arr[i];
  24. arr[i] = arr[j];
  25. arr[j] = tmp;
  26. }

三、插入排序

1、解释

插入排序,一般也被称为直接插入排序。

对于少量元素的排序,它是一个有效的算法 。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动。
 

2、思想

插入排序(Insertion Sorting)的基本思想是:

把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素;

排序过程中每次从无序表中取出第一个元素,在有序表中从后往前进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。
 

3、图解

4、性能特点

最好情况最坏情况平均时间复杂度空间复杂度稳定性
O(n)O(n^2)O(n^2)O(1)稳定

5、代码解释

(1)java

  1. public static void main(String[] args) {
  2. int []arr={101,34,119,1};
  3. insertSort(arr);
  4. System.out.println("排序后的数组为:"+Arrays.toString(arr));
  5. }
  6. public static void insertSort(int[]arr){
  7. if (arr==null||arr.length==1){
  8. return;
  9. }
  10. //从第二个元素开始,和前面的有序表进行比较
  11. for (int i=1;i<arr.length;i++){
  12. int temp=arr[i];//记录要插入的值,将待插入的值取出并保存在temp中,防止数据移动时该元素丢失
  13. int j=i-1;
  14. //从后往前进行遍历比较
  15. for (;j>=0;j--){
  16. if (arr[j]>temp){
  17. arr[j+1]=arr[j];//后移一个位置
  18. }
  19. else {
  20. arr[j+1]=temp;//直接将待插入的元素,插入在有序表的尾部
  21. break;
  22. }
  23. }
  24. arr[j+1]=temp;//遍历完有序表所有大于temp的元素后,将temp插入
  25. }
  26. }

优化

  1. public static void insertionSort(int[] arr) {
  2. if (arr == null || arr.length < 2) {
  3. return;
  4. }
  5. //每次将从0-i位置的元素进行排序
  6. for (int i = 1; i < arr.length; i++) { // 0 ~ i 做到有序
  7. //int j = i - 1; j >= 0表示左边位置的边界条件
  8. //arr[j] > arr[j + 1]表示最右边的数与相邻数的比较
  9. //j--表示将这个过程向左推进
  10. //swap(arr, j, j + 1)表示进行两个相邻数比较时,左边的数大于右边数时,才交换否则不交换
  11. for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
  12. swap(arr, j, j + 1);
  13. }
  14. }
  15. }
  16. public static void swap(int[] arr, int i, int j) {
  17. int tmp = arr[i];
  18. arr[i] = arr[j];
  19. arr[j] = tmp;
  20. }

四、堆排序

1、解释

堆是一种叫做完全二叉树的数据结构,可以分为大根堆,小根堆,而堆排序就是基于这种结构而产生的一种程序算法。

大根堆:每个节点的值都大于或者等于他的左右孩子节点的值,在堆排序算法中用于升序排列

小根堆:每个结点的值都小于或等于其左孩子和右孩子结点的值,在堆排序算法中用于降序排列

2、思想

(1).首先将待排序的数组构造成一个大根堆,此时,整个数组的最大值就是堆结构的顶端

(2).将顶端的数与末尾的数交换,此时,末尾的数为最大值,剩余待排序数组个数为n-1

(3).将剩余的n-1个数再构造成大根堆,再将顶端数与n-1位置的数交换,如此反复执行,便能得到有序数组

注意:升序用大根堆,降序就用小根堆(默认为升序)
 

3、图解

4、性能特点

最好情况最坏情况平均时间复杂度空间复杂度稳定性
O(nlogn)O(nlogn)O(nlogn)O(1)不稳定

5、代码解释

  1. #最大堆:
  2. def topHeap(list,size):
  3. #i节点的子节点为2i+1,2i+2
  4. for i in range(size//2-1,-1,-1):
  5. if 2*i+1<size: #左孩子存在
  6. if list[2*i+1]>list[i]:
  7. list[2*i+1],list[i]=list[i], list[2*i+1]
  8. if 2*i+2<size: #右孩子存在
  9. if list[2*i+2]>list[i]:
  10. list[2*i+2],list[i]=list[i], list[2*i+2]
  11. list=[11,2,3,4,12,18,16]
  12. for i in range(len(list),0,-1):
  13. topHeap(list,i)
  14. list[0],list[i-1]=list[i-1],list[0] #每轮交换栈顶元素至相应位置
  15. print(list)

  1. #最小堆
  2. def topHeap(list,size): #i节点的子节点为2i+1,2i+2
  3. for i in range(size//2-1,-1,-1):
  4. if 2*i+1<size: #左孩子存在
  5. if list[2*i+1]<list[i]:
  6. list[2*i+1],list[i]=list[i], list[2*i+1]
  7. if 2*i+2<size: #右孩子存在
  8. if list[2*i+2]<list[i]:
  9. list[2*i+2],list[i]=list[i], list[2*i+2]
  10. list=[11,2,3,4,12,18,16]
  11. for i in range(len(list),0,-1):
  12. topHeap(list,i)
  13. list[0],list[i-1]=list[i-1],list[0] #每轮交换栈顶元素至相应位置
  14. print(list)

——————————————————————————————————————————

收集信息时,发现的一个宝藏博主写的关于诸多排序详解:

十大排序算法小结_排序大小算法有哪些_张维鹏的博客-CSDN博客

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号