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

一、冒泡排序

1、解释:

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

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

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

2、思想:

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

3、图解:

4、性能特点:

5、 代码解释——python


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=" ")# 输出

二、选择排序

1、解释

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

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

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

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

2、思想

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

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

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

3、图解

4、性能特点

5、代码解释

(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、解释

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

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

2、思想

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

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

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

3、图解

4、性能特点

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

5、代码解释

(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、思想

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

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

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

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

3、图解

4、性能特点

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

5、代码解释

#最大堆:

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)

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

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

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

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
冒泡排序选择排序都是常见的排序算法,下面分别介绍一下它们的工作原理和实现。 冒泡排序(Bubble Sort)是一种简单的排序算法,它重复地遍历要排序的列表,比较相邻的两个元素并将它们按照大小顺序进行交换,直到整个列表排序完成。 冒泡排序的步骤如下: 1. 从第一个元素开始,比较相邻的两个元素。 2. 如果顺序不正确,则交换它们的位置。 3. 继续比较下一对相邻元素,直到比较完所有元素。 4. 如果还有任何交换操作发生,则重复前面的步骤。 以下是用 Python 实现冒泡排序的代码: ```python def bubble_sort(arr): n = len(arr) for i in range(n): # 每次遍历会将最大的元素冒泡到最后 for j in range(0, n-i-1): if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] return arr ``` 选择排序(Selection Sort)也是一种简单的排序算法,它每次从未排序的部分中选择最小的元素,并将其放置在已排序部分的末尾。 选择排序的步骤如下: 1. 找到未排序部分中的最小元素。 2. 将最小元素与未排序部分的第一个元素交换位置。 3. 将已排序部分的长度加1。 4. 重复上述步骤,直到整个列表排序完成。 以下是用 Python 实现选择排序的代码: ```python def selection_sort(arr): n = len(arr) for i in range(n): min_index = i # 找到未排序部分的最小元素 for j in range(i+1, n): if arr[j] < arr[min_index]: min_index = j # 将最小元素与未排序部分的第一个元素交换位置 arr[i], arr[min_index] = arr[min_index], arr[i] return arr ``` 希望对你有所帮助!如果还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值