赞
踩
冒泡排序是一种基于比较和交换操作的排序算法。
每轮冒泡的过程都是从第一个元素开始,将该元素和相邻下一个元素进行比较和交换,使得较大的元素向右移动(如果该元素大于下一个元素,则两个元素交换;如果该元素小于等于下一个元素,则保持不变)。
这样一来,每轮冒泡的过程都可以确定一个元素放在正确的位置上,而这个元素就是剩余元素中最大的元素,正确的位置就是剩余位置中的最右侧的位置。这个过程就像是气泡上浮一样,所以叫做冒泡排序。
它的基本思想是对所有相邻记录的关键字值进行比效,如果是逆顺(a[j]>a[j+1]),则将其交换,最终达到有序化;
-
- def bubbleSort(arr):
- for i in range(1, len(arr)):
- l = 0 # 记录左边元素下标
- r = len(nums) - 1 # 记录右边元素下标
- flag = False # 设置标志位,判断当前趟次是否有元素交换
- # 正向排序最大值
- for j in range(l, r):
- if arr[j] > arr[j + 1]:
- arr[j], arr[j + 1] = arr[j + 1], arr[j]
- flag = True
-
- if not flag:
- break
- # 反向排序最小值
- for j in range(r, l, -1):
- if arr[j] < arr[j - 1]:
- arr[j], arr[j - 1] = arr[j - 1], arr[j]
-
- print(nums)
- return arr
-
-
- if __name__=="__main__":
- nums = [1, 42, 65, 876, 34, 656, 4, 6757, 89, 24, 65, 42]
- print("start:", nums)
- print("冒泡 :", bubbleSort(nums))
(两个for语句的使用——python)
- """
- Python冒泡排序
- 两个for
- """
-
- s = list(map(int,input().split(" ")))# 输入列表,以空格分隔,返回列表。
- for i in range(len(s)):
- for j in range(len(s)-i-1):
- if s[j] > s[j+1] :# 此为判断是否大于后一个数,大于就换(升序判断),如果想是降序,就把">"改成"<"
- s[j], s[j+1] = s[j+1], s[j]
-
- for i in s:
- print(i,end=" ")# 输出
选择排序(Selection sort)是一种简单直观的排序算法。
选择排序首先从待排序列表中找到最小(大)的元素,存放到元素列表的起始位置(与起始位置进行交换),作为已排序序列,第一轮排序完成。
然后,继续从未排序序列中找到最小(大)的元素,存放到已排序序列的末尾。直到所有元素都存放到了已排序序列中,列表排序完成。
选择排序每次都是去找最小(大)的元素,隐含了一种挑选的过程,所以被称为选择排序。
1. 从待排序列表中找到最小的元素(升序排列,降序排列则找最大的元素),存放到列表的起始位置,作为已排序的序列。
2. 继续从未排序序列中找到最小的元素,存放到已排序序列的末尾(同时也是未排序序列的起始位置)。
3. 重复第2步,直到所有元素都已经存放到了已排序序列,则列表排序完成。
(1)升序选择排序
- # 选择排序
- def selectionSort(arr):
- for i in range(len(arr) - 1):
- minIndex = i # 记录最小元素的索引
- # 找出最小元素
- for j in range(i + 1, len(arr)):
- if arr[j] < arr[minIndex]:
- minIndex = j
- # i不是最小元素时,将i和最小元素进行交换
- if i != minIndex:
- arr[i], arr[minIndex] = arr[minIndex], arr[i]
- return arr
-
-
- if __name__=="__main__":
- nums = [1, 42, 65, 876, 34, 656, 4, 6757, 89, 24, 65, 42]
- print("start:", nums)
- print("冒泡 :", selectionSort(nums))
(2)降序选择排序
- # 选择排序
- def selectionSort(arr):
- for i in range(len(arr) - 1):
- maxIndex = i # 记录最大元素的索引
- # 找出最大元素
- for j in range(i + 1, len(arr)):
- if arr[j] > arr[maxIndex]:
- maxIndex= j
- # i不是最大元素时,将i和最大元素进行交换
- if i != maxIndex:
- arr[i], arr[maxIndex] = arr[maxIndex], arr[i]
- return arr
-
-
- if __name__=="__main__":
- nums = [1, 42, 65, 876, 34, 656, 4, 6757, 89, 24, 65, 42]
- print("start:", nums)
- print("冒泡 :", selectionSort(nums))
(3)java
- public static void selectionSort(int[] arr) {
- /*判断数组为空或为一个元素的情况,即边界检查*/
- if (arr == null || arr.length < 2) {
- return;
- }
-
- /*每次要进行比较的两个数,的前面那个数的下标*/
- for (int i = 0; i < arr.length - 1; i++) {
- //min变量保存该趟比较过程中,最小元素所对应的索引,
- //先假设前面的元素为最小元素
- int minIndex = i;
- /*每趟比较,将前面的元素与其后的元素逐个比较*/
- for (int j = i + 1; j < arr.length; j++) {
- //如果后面的元素小,将后面元素的索引极为最小值的索引
- if(arr[j] < arr[minIndex]) {
- minIndex = j;
- }
- }
- //然后交换此次查找到的最小值和原始的最小值
- swap(arr, i, minIndex);
- }
- }
-
- public static void swap(int[] arr, int i, int j) {
- int tmp = arr[i];
- arr[i] = arr[j];
- arr[j] = tmp;
- }
-
插入排序,一般也被称为直接插入排序。
对于少量元素的排序,它是一个有效的算法 。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动。
插入排序(Insertion Sorting)的基本思想是:
把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素;
排序过程中每次从无序表中取出第一个元素,在有序表中从后往前进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。
最好情况 | 最坏情况 | 平均时间复杂度 | 空间复杂度 | 稳定性 |
O(n) | O(n^2) | O(n^2) | O(1) | 稳定 |
(1)java
- public static void main(String[] args) {
- int []arr={101,34,119,1};
- insertSort(arr);
- System.out.println("排序后的数组为:"+Arrays.toString(arr));
- }
- public static void insertSort(int[]arr){
- if (arr==null||arr.length==1){
- return;
- }
- //从第二个元素开始,和前面的有序表进行比较
- for (int i=1;i<arr.length;i++){
- int temp=arr[i];//记录要插入的值,将待插入的值取出并保存在temp中,防止数据移动时该元素丢失
- int j=i-1;
- //从后往前进行遍历比较
- for (;j>=0;j--){
- if (arr[j]>temp){
- arr[j+1]=arr[j];//后移一个位置
- }
- else {
- arr[j+1]=temp;//直接将待插入的元素,插入在有序表的尾部
- break;
- }
- }
- arr[j+1]=temp;//遍历完有序表所有大于temp的元素后,将temp插入
- }
- }
优化
- public static void insertionSort(int[] arr) {
- if (arr == null || arr.length < 2) {
- return;
- }
-
- //每次将从0-i位置的元素进行排序
- for (int i = 1; i < arr.length; i++) { // 0 ~ i 做到有序
- //int j = i - 1; j >= 0表示左边位置的边界条件
- //arr[j] > arr[j + 1]表示最右边的数与相邻数的比较
- //j--表示将这个过程向左推进
- //swap(arr, j, j + 1)表示进行两个相邻数比较时,左边的数大于右边数时,才交换否则不交换
- for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
- swap(arr, j, j + 1);
- }
- }
- }
-
- public static void swap(int[] arr, int i, int j) {
- int tmp = arr[i];
- arr[i] = arr[j];
- arr[j] = tmp;
- }
堆是一种叫做完全二叉树的数据结构,可以分为大根堆,小根堆,而堆排序就是基于这种结构而产生的一种程序算法。
大根堆:每个节点的值都大于或者等于他的左右孩子节点的值,在堆排序算法中用于升序排列
小根堆:每个结点的值都小于或等于其左孩子和右孩子结点的值,在堆排序算法中用于降序排列
(1).首先将待排序的数组构造成一个大根堆,此时,整个数组的最大值就是堆结构的顶端
(2).将顶端的数与末尾的数交换,此时,末尾的数为最大值,剩余待排序数组个数为n-1
(3).将剩余的n-1个数再构造成大根堆,再将顶端数与n-1位置的数交换,如此反复执行,便能得到有序数组
注意:升序用大根堆,降序就用小根堆(默认为升序)
最好情况 | 最坏情况 | 平均时间复杂度 | 空间复杂度 | 稳定性 |
O(nlogn) | O(nlogn) | O(nlogn) | O(1) | 不稳定 |
- #最大堆:
-
- def topHeap(list,size):
- #i节点的子节点为2i+1,2i+2
- for i in range(size//2-1,-1,-1):
- if 2*i+1<size: #左孩子存在
- if list[2*i+1]>list[i]:
- list[2*i+1],list[i]=list[i], list[2*i+1]
- if 2*i+2<size: #右孩子存在
- if list[2*i+2]>list[i]:
- list[2*i+2],list[i]=list[i], list[2*i+2]
- list=[11,2,3,4,12,18,16]
- for i in range(len(list),0,-1):
- topHeap(list,i)
- list[0],list[i-1]=list[i-1],list[0] #每轮交换栈顶元素至相应位置
- print(list)
- #最小堆
-
- def topHeap(list,size): #i节点的子节点为2i+1,2i+2
- for i in range(size//2-1,-1,-1):
- if 2*i+1<size: #左孩子存在
- if list[2*i+1]<list[i]:
- list[2*i+1],list[i]=list[i], list[2*i+1]
- if 2*i+2<size: #右孩子存在
- if list[2*i+2]<list[i]:
- list[2*i+2],list[i]=list[i], list[2*i+2]
- list=[11,2,3,4,12,18,16]
- for i in range(len(list),0,-1):
- topHeap(list,i)
- list[0],list[i-1]=list[i-1],list[0] #每轮交换栈顶元素至相应位置
- print(list)
——————————————————————————————————————————
收集信息时,发现的一个宝藏博主写的关于诸多排序详解:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。