一篇文章带你整体把控算法中的基本问题《排序

简介: 排序本篇文章对算法中的基本问题--排序 的思想进行了描述,后续文章会对所有排序算法进行实现,欢迎关注本系列。可以转载,但请声明源链接:文章源链接justin3go.com(有些latex公式某些平台不能渲染可查看这个网站)
published: true
date: 2022-1-22
tags: '算法与数据结构'


稳定性:相同关键字元素的相对次序保持不变,则是稳定排序。

排序

本篇文章对算法中的基本问题--排序 的思想进行了描述,后续文章会对所有排序算法进行实现,欢迎关注本系列。

可以转载,但请声明源链接:文章源链接justin3go.com(有些latex公式某些平台不能渲染可查看这个网站)

直接插入排序


每次将一个待排序的记录插入到已排好序的数据区中直到全部插入完为止。

是稳定的排序。

监视哨的插入排序:

  • 设置监视哨r[0],将待插入记录的值赋给r[0]
  • 设置查找起始位置j
  • 查找:
  • while(r[0].key<r[j-1].key)
  • r[j]=r[0]
  • 监视哨的作用
  • 进入查找循环之前,保存了r[i]的副本,记录后移时不会丢失r[i]的内容。
  • 循环中“监视”下标变量j是否越界。
  • 一旦越界(即j=0),能控制while循环结束。
  • 避免在while循环内每次都要检测j是否越界的问题。

希尔排序


shell排序是对位置间隔较大的结点进行比较,则结点一次比较后能跨过较距离,可能提高排序速度。

shell排序是不稳定的排序。

冒泡排序


此处省略。

稳定的排序。

快速排序


对一组无序的数据集合,选择任意元素作为基准点

  • 该基准点左边的所有记录都小于或等于它。
  • 是基准点右边的所有记录都大于多等于它。
  • 然后重复上述操作,分别对左右半区进行快速排序。

是不稳定的排序。

需要一个栈空间来实现递归。

简单选择排序


  • 通过n-1次关键字比较,从n个记录中找出关键字最小的记录,将它与第一个记录交换。
  • 通过n-2次比较,从剩余的n-1个记录中找出关键字次小的记录。
  • 重复上述操作,进行n-1躺排序后结束。

堆排序


大根堆:根结点(即堆顶)的关键字是堆里所有结点关键字中最大者的堆,称为大根堆。

小根堆:根结点(即堆顶)的关键字是堆里所有结点关键字中最小者的堆,称为小根堆。

堆排序的思路:

  • 按某种方法生成大根堆,该大根堆的根就是键值最大的元素。
  • 将根与向量尾部的元素进行互换,即最大值放到向量的末尾(有序区)。
  • 将剩余的n-1个元素再次调整成大根堆,可得到次大值。
  • 将次大值放到向量的倒数第二的位置。
  • ······
  • 如此反复,直到全部关键字排好序为止。


# -*- coding:utf-8 -*-
def head_sort(list):
    length_list = len(list)
    first=int(length_list/2-1)
    # 假设len=8, 这里first=3, 下面的range就是[3210]
    for start in range(first,-1,-1):  # 循环把所有子树生成大根堆
        max_heapify(list,start,length_list-1)
    for end in range(length_list-1,0,-1):
        list[end],list[0]=list[0],list[end]
        max_heapify(list,0,end-1)  # 后面就是自上而下的交换了,不用每个都判断了(不用像生成大根堆那样)
    return list
def max_heapify(ary,start,end): # 把子树生成大根堆
    root = start
    # 其中标*的两句话是为什么结点到上面的几层仍然可以与底层的进行比较交换的原因
    while True:  # *
        child = root*2 + 1
        if child > end:  # 判断是否有左孩子
            break
        if child + 1 <= end and ary[child]<ary[child+1]: # 判断是否有右孩子,且如有就留大的
            child = child + 1
        if ary[root]<ary[child]:  # 把刚那个大的孩子与根进行比较交换
            ary[root],ary[child]=ary[child],ary[root]
            root=child  # *
        else:
            break
#测试:
list=[10,23,1,53,654,54,16,646,65,3155,546,31]
print head_sort(list)


归并排序


将若干已排好序的子序列合并成一个有序的。

目录
相关文章
|
4月前
|
算法
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
|
1月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(下)(c语言实现)(附源码)
本文继续学习并实现了八大排序算法中的后四种:堆排序、快速排序、归并排序和计数排序。详细介绍了每种排序算法的原理、步骤和代码实现,并通过测试数据展示了它们的性能表现。堆排序利用堆的特性进行排序,快速排序通过递归和多种划分方法实现高效排序,归并排序通过分治法将问题分解后再合并,计数排序则通过统计每个元素的出现次数实现非比较排序。最后,文章还对比了这些排序算法在处理一百万个整形数据时的运行时间,帮助读者了解不同算法的优劣。
124 7
|
1月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(上)(c语言实现)(附源码)
本文介绍了四种常见的排序算法:冒泡排序、选择排序、插入排序和希尔排序。通过具体的代码实现和测试数据,详细解释了每种算法的工作原理和性能特点。冒泡排序通过不断交换相邻元素来排序,选择排序通过选择最小元素进行交换,插入排序通过逐步插入元素到已排序部分,而希尔排序则是插入排序的改进版,通过预排序使数据更接近有序,从而提高效率。文章最后总结了这四种算法的空间和时间复杂度,以及它们的稳定性。
105 8
|
2月前
|
搜索推荐 Shell
解析排序算法:十大排序方法的工作原理与性能比较
解析排序算法:十大排序方法的工作原理与性能比较
79 9
|
2月前
|
算法 搜索推荐 Java
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
41 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
|
2月前
|
算法
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
34 0
|
2月前
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
82 0
|
4月前
|
搜索推荐 算法 Java
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
该博客文章通过UML类图和Java源码示例,展示了如何使用适配器模式将QuickSort类和BinarySearch类的排序和查找功能适配到DataOperation接口中,实现算法的解耦和复用。
56 1
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
|
4月前
|
算法 搜索推荐 Java
算法实战:手写归并排序,让复杂排序变简单!
归并排序是一种基于“分治法”的经典算法,通过递归分割和合并数组,实现O(n log n)的高效排序。本文将通过Java手写代码,详细讲解归并排序的原理及实现,帮助你快速掌握这一实用算法。
49 0
|
4月前
|
算法 关系型数据库 MySQL
揭秘MySQL中的版本号排序:这个超级算法将颠覆你的排序世界!
【8月更文挑战第8天】在软件开发与数据管理中,正确排序版本号对软件更新及数据分析至关重要。因MySQL默认按字符串排序版本号,可能出现&#39;1.20.0&#39;在&#39;1.10.0&#39;之前的不合理情况。解决办法是将版本号各部分转换为整数后排序。例如,使用`SUBSTRING_INDEX`和`CAST`函数从`software`表的`version`字段提取并转换版本号,再按这些整数排序。这种方法可确保版本号按逻辑正确排序,适用于&#39;major.minor.patch&#39;格式的版本号。对于更复杂格式,需调整处理逻辑。掌握此技巧可有效应对版本号排序需求。
219 3