算法——列表排序和排序算法

一、列表排序

  排序就是将一组“无序”的记录序列调整为“有序”的记录序列。

  列表排序:将无序列表变为有序列表。

    输入:列表

    输出:有序列表

  两种基本的排序方式:升序和降序。

  python内置的排序函数:sort()。

二、常见排序算法  


名称


复杂度


说明


备注


冒泡排序
Bubble Sort


O(N*N)


将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮


插入排序

Insertion sort


O(N*N)


逐一取出元素,在已经排序的元素序列中从后向前扫描,放到适当的位置


起初,已经排序的元素序列为空


选择排序


O(N*N)


首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此递归。


快速排序

Quick Sort


O(n *log2(n))


先选择中间值,然后把比它小的放在左边,大的放在右边(具体的实现是从两边找,找到一对后交换)。然后对两边分别使用这个过程(递归)。


堆排序HeapSort


O(n *log2(n))


利用堆(heaps)这种数据结构来构造的一种排序算法。堆是一个近似完全二叉树结构,并同时满足堆属性:即子节点的键值或索引总是小于(或者大于)它的父节点。


近似完全二叉树


希尔排序

SHELL


O(n1+)

0<£<1


选择一个步长(Step) ,然后按间隔为步长的单元进行排序.递归,步长逐渐变小,直至为1.


箱排序
Bin Sort


O(n)


设置若干个箱子,把关键字等于 k 的记录全都装入到第k 个箱子里 ( 分配 ) ,然后按序号依次将各非空的箱子首尾连接起来 ( 收集 ) 。


分配排序的一种:通过" 分配 " 和 " 收集 " 过程来实现排序。

1、冒泡排序(Bubble Sort)

  列表每两个相邻的数,如果前面比后面大,则交换这两个数。

  一趟排序完成后,则无序区减少一个数,有序区增加一个数。

  代码关键点:趟、无序区范围。

(1)图示说明

          

  这样排序一趟后,最大的数9,就到了列表最顶成为了有序区,下面的部分则还是无序区。然后在无序区不断重复这个过程,每完成一趟排序,无序区减少一个数,有序区增加一个数。图示最后一张图要开始第六趟排序,排序从第0趟开始计数。剩一个数的时候不需要排序了,因此整个排序排了n-1趟。

(2)代码示例

import random

def bubble_sort(li):
    for i in range(len(li)-1):    # 总共是n-1趟
        for j in range(len(li)-i-1):   # 每一趟都有箭头,从0开始到n-i-1
            if li[j] > li[j+1]:  # 比对箭头指向和箭头后面的那个数的值
                # 当箭头所指数大于后面的数时交换位置, 升序排列;条件相反则为降序排列
                li[j], li[j+1] = li[j+1], li[j]

li = [random.randint(0, 10000) for i in range(30)]
print(li)
bubble_sort(li)
print(li)

"""
[5931, 5978, 6379, 4217, 9597, 4757, 4160, 3310, 6916, 2463, 9330, 8043, 8275, 5614, 8908, 7799, 9256, 3097, 9447, 9327, 7604, 9464, 417, 927, 1720, 145, 6451, 7050, 6762, 6608]
[145, 417, 927, 1720, 2463, 3097, 3310, 4160, 4217, 4757, 5614, 5931, 5978, 6379, 6451, 6608, 6762, 6916, 7050, 7604, 7799, 8043, 8275, 8908, 9256, 9327, 9330, 9447, 9464, 9597]
"""

  如果要打印出每次排序结果:

import random

def bubble_sort(li):
    for i in range(len(li)-1):    # 总共是n-1趟
        for j in range(len(li)-i-1):   # 每一趟都有箭头,从0开始到n-i-1
            if li[j] > li[j+1]:  # 比对箭头指向和箭头后面的那个数的值
                # 当箭头所指数大于后面的数时交换位置, 升序排列;条件相反则为降序排列
                li[j], li[j+1] = li[j+1], li[j]
        print(li)

li = [random.randint(0, 10000) for i in range(5)]
print(li)
bubble_sort(li)
print(li)

"""
[1806, 212, 4314, 1611, 8355]
[212, 1806, 1611, 4314, 8355]
[212, 1611, 1806, 4314, 8355]
[212, 1611, 1806, 4314, 8355]
[212, 1611, 1806, 4314, 8355]
[212, 1611, 1806, 4314, 8355]
"""

(3)算法时间复杂度

  n是列表的长度,算法中也没有发生循环折半的过程,具备两层关于n的循环,因此它的时间复杂度是O(n2)。

(4)冒泡排序优化

  如果在一趟排序过程中没有发生交换就可以认定已经排好序了。因此可做如下优化:

import random

def bubble_sort(li):
    for i in range(len(li)-1):    # 总共是n-1趟
        exchange = False
        for j in range(len(li)-i-1):   # 每一趟都有箭头,从0开始到n-i-1
            if li[j] > li[j+1]:  # 比对箭头指向和箭头后面的那个数的值
                # 当箭头所指数大于后面的数时交换位置, 升序排列;条件相反则为降序排列
                li[j], li[j+1] = li[j+1], li[j]
                exchange = True   # 如果发生了交换就置为true
        print(li)
        if not exchange:
            # 如果exchange还是False,说明没有发生交换,结束代码
            return

# li = [random.randint(0, 10000) for i in range(5)]
li = [1806, 212, 4314, 1611, 8355]
bubble_sort(li)

"""
[212, 1806, 1611, 4314, 8355]
[212, 1611, 1806, 4314, 8355]
[212, 1611, 1806, 4314, 8355]
"""

  对比前面排序的次数少了很多,算法得到了优化~

2、选择排序

原文地址:https://www.cnblogs.com/xiugeng/p/9638052.html

时间: 2024-10-03 22:09:30

算法——列表排序和排序算法的相关文章

排序算法总结----比较类排序

概述:排序算法可分为比较性的排序,以及运算性的排序:这里详细介绍这些排序的原理,性能,实现,以及应用场合. 前面是维基百科的介绍,这里介绍几个比较典型的算法. 理论 计算复杂性理论 大O符号 全序关系 列表 稳定性 比较排序 自适应排序 排序网络 整数排序 交换排序 冒泡排序 鸡尾酒排序 奇偶排序 梳排序 侏儒排序 快速排序 臭皮匠排序 Bogo排序 选择排序 选择排序 堆排序 Smooth排序 笛卡尔树排序 锦标赛排序 循环排序 插入排序 插入排序 希尔排序 二叉查找树排序 图书馆排序 Pat

【排序】快速排序算法

特别说明: 对于算法,重在理解其思想.解决问题的方法,思路.因此,以下内容全都假定待排序序列的存储结构为:顺序存储结构. 快速排序介绍 快速排序算法相较于插入.冒泡.选择排序来说而言要稍微复杂些.其主要用的是分治思想,将问题划分为更小的子问题来解决.因此,快速排序的思想其实很简单.在(目前的)时间复杂度为  的排序算法中,快速排序的系数是最小的.因此,在平均情况下,快速排序算法是被认为最快的一种排序算法(要不怎么称之为快速排序呢?). 快速排序算法在大数据量情况下,实践证明在平均情况下的排序算法

【排序】冒泡排序算法

特别说明: 对于算法,重在理解其思想.解决问题的方法,思路.因此,以下内容全都假定待排序序列的存储结构为:顺序存储结构. 冒泡排序思想 冒泡排序与插入排序.简单选择排序一样,都是比较简单的一类排序算法.假设待排序序列为 ,则冒泡排序算法思想如下: 01.设置  =  - 1 (注:0     - 1, 用于标记外层循环迭代): 02.如果  = 0,则排序结束,退出: 03.设置  = 0 (注:0    , 用于标记内层循环迭代): 04.如果  = ,跳转并执行 09 步骤 (即:该趟冒泡排

数据结构与算法之三 深入学习排序

在本章中,你将学习: 通过使用快速排序来排序数据 通过使用归并排序来排序数据 快速排序算法: 快速排序是最有效率的排序算法之一,此算法基于分治法 连续将问题细分为更小的问题,直到问题成为可以直接解决的小问题 在快速排序算法中,你: 从名为枢轴的列表处选择元素. 将列表划分为两部分: 列表左端的所有元素小于等于枢轴. 列表右端的所有元素大于枢轴. 在此列表两部分的正确位置存储枢轴. 划分之后为创建的两个子列表重复此过程(找枢轴的过程). 直到每个子列表中只剩一个元素. 思想:就是不断找出符合条件的

【排序】插入排序算法

    特别说明: 对于算法,重在理解其思想.解决问题的方法,思路.因此,以下内容全都假定待排序序列的存储结构为:顺序存储结构. 一:插入排序算法思想 01.设待排序序列为 .插入排序将  划分为由已排序好序的  部分 以及 未排序的  部分组成: 注意:刚开始时  部分其实可认为只有一个元素,即: 元素 02.排序开始时,每次从  序列中(随机,但一般是直接取第一个元素)取出一个元素 ,将其插入到已排好序  部分的"适当位置 ",使得以下条件成立:      ,{ 1  x  i  

数据结构和算法17 之拓扑排序

本文为博主原创文章,转载请注明出处:http://blog.csdn.net/eson_15/article/details/51194219 这一节我们学习一个新的排序算法,准确的来说,应该叫"有向图的拓扑排序".所谓有向图,就是A->B,但是B不能到A.与无向图的区别是,它的边在邻接矩阵里只有一项(友情提示:如果对图这种数据结构部不太了解的话,可以先看一下这篇博文:数据结构和算法之 无向图.因为拓扑排序是基于图这种数据结构的). 有向图的邻接矩阵如下表所示: A B C A

排序算法(冒泡排序,选择排序,插入排序,快速排序)

数组的排序算法 选择排序 每次选择所要排序得数组中的最大值(由大到小排序,由小到大排序则选择最小值)的数组元素,将这个数组元组的值与最前面没有排序的数组元素进行交换, 第一次排序之后,最大的数字来到了第一位,再从第二个元素开始找,找到最大的元素,与第二个交换位置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <std

简单算法之9种排序

甭管什么,笔者就喜欢凑个9.这次,关于排序的算法还是9种,小结一下.排序的算法,尽管有很多的方法例子,但这次是自己总结的,挺有意思算法希望大家喜欢.直接上代码楼,以下算法,都经过笔者亲测,并修改使之有效(粘贴可用). package com.css.java.learning.massbag; import java.util.Arrays; /**算法: * 排序相关小结 * @author Red_ant * 20181119 */ public class OrderMethod { /*

python 排序和查找算法

一.搜索 1.顺序查找 数据存储在具有线性或顺序关系的结构中时,可顺序访问查找 def sequential_search(ilist, item): pos = 0 while pos < len(ilist): if ilist[pos] == item: return pos else: pos = pos + 1 return -1 2.二分查找 对于有序顺序表可使用二分查找,每次从中间项开始,故每次可以排除剩余项的一半 def binary_search(ilist, item): f