python 下的数据结构与算法---6:6大排序算法

一:冒泡排序(Bubble Sort)

  原理:假设有n个数,第一轮时:从第一个元素开始,与相邻的元素比较,如果前面的元素小就交换,直到第n-1个元素时,这样的结果是将最大的元素放到了最后,同理,第二轮还是从第一个元素开始比较,直到第n-2个元素,这样能够把剩下的n-1个数中的最大的数放到第n-1的位置,一直这样进行n-1轮就能够完成排序。

 1 def Bublesort(seq):
 2     i = 0
 3     j = 0
 4     while i < len(seq):
 5         while j < len(seq)-i-1:
 6             if seq[j] > seq[j+1]:
 7                 seq[j],seq[j+1] = seq[j+1],seq[j]
 8             else:
 9                 j+=1
10         j=0
11         i+=1
12
13 a=[3,4,6,2,1]
14 Bublesort(a)
15 print(a)

冒泡排序

  由代码可知,其时间复杂度为O(n2).

二:选择排序(Selection Sort)

  原理:选择排序的思路非常简单,每次都遍历找出上次剩下的元素中的最大数,然后和剩下数中随后一个元素交换位置,一个进行n-1次

 1 #coding:utf-8
 2 #Attention:max标志需取为seq[0],我刚开始取了0,这会导致最后一次比较时出问题
 3 def SelectionSort(seq):
 4     i,j,maxel = 0,0,seq[0]
 5     while i < len(seq):
 6         while j < len(seq)-i:
 7             if seq[j] > maxel:
 8                 maxel = j
 9             j+=1
10         seq[maxel],seq[len(seq)-i-1] = seq[len(seq)-i-1],seq[maxel]
11         j,maxel=0,seq[0]
12         i+=1
13
14 a=[3,4,6,2,1]
15 SelectionSort(a)
16 print(a)

选择排序

  可以看出的是,其时间复杂度依然是O(n2),看起来和冒泡排序一样,但由于每轮其交换位置的次数少,故实际上其比冒泡排序好。

三:插入排序(Insertion Sort)

  原理:如下图所示,将第一个元素作为标准,每次将下一个元素放到前面正确的位置中去。

  技巧:从已排好序元素最后一个开始遍历比较,因为插入移动只会移动其后面的元素。

  

 1 def insertion_sort(a_list):
 2     for index in range(1, len(a_list)):
 3         current_value = a_list[index]
 4         position = index
 5         while position > 0 and a_list[position - 1] > current_value:        #从目前元素开始向前,若>目前值就后移一位
 6             a_list[position] = a_list[position - 1]
 7             position = position - 1
 8         a_list[position] = current_value
 9
10 a = [54, 26, 93, 17, 77, 31, 44, 55, 20]
11 insertion_sort(a)
12 print(a)

插入排序

  依旧可以看出的是,其时间复杂度为O(n2),但是他的不同之处在于其始终保持了一个部分有序的序列

四:希尔排序(Shell Sort)

  希尔排序这章书里面的配图不好,导致我理解错误直到运行程序出错才发现错误,后来看了些其他资料弄明白了。其实希尔排序就是跳跃式插入排序,我们试想一下,如果一个元素集是9,8,7,6,5,4,3,2,1,那么每次插入排序都要全部后移了,这样效率极低,如果能够不按顺序的进行插入排序就好多了,虽然每次并没有完全排好序,但是能够让他们离真实的位置更近,这就是其优势所在了。

  实现原理:每次取一个gap,第一次取集合元素个数整除2的结果,然后对从首元素开始每gap距离的元素组合成一个组并对其进行插入排序,假设集合[54, 26, 93, 17, 77, 31, 44, 55, 20],那么第一次gap为9//2=4,那么就能够有这些组:[54,77,20],[26,31],[93,44],[17,55],注意,并不是对其真的分组,只是将其看作一组后进行插入排序,那么结果是:[20, 26, 44, 17, 54, 31, 93, 55, 77],到此,第一次完成。第二次把gap改为上次gap//2的结果,也就是2,所以对上次的结果分组为[20,44,54,93,77],[26,17,31,55],对其进行插入排序后的结果是[20, 17, 44, 26, 54, 31, 77, 55, 93],到此第二次完成。第三次gap为1,注意,当gap为1时就表明是最后一轮了,最上此结果[20, 17, 44, 26, 54, 31, 77, 55, 93]全部进行插入排序就能够得到结果了。【仔细看看就能够发现其每次排序后真的是数字离其真实位置更近了】。

  注意:有个控制循环的条件就是每次分组的组数其实就是gap的值,容易看出是两层控制,外层控制进入的哪组分组,内层控制具体每组的插入排序

 1 def shell_sort(a_list):
 2     sublist_count = len(a_list) // 2
 3     while sublist_count > 0:
 4         for start_position in range(sublist_count):
 5             gap_insertion_sort(a_list, start_position, sublist_count)
 6         print("After increments of size", sublist_count, "The list is",a_list)
 7         sublist_count = sublist_count // 2
 8
 9 def gap_insertion_sort(a_list,start, gap):
10     for i in range(start + gap, len(a_list), gap):
11         current_value = a_list[i]
12         position = i
13         while position >= gap and a_list[position - gap] > current_value:
14             a_list[position] = a_list[position - gap]
15             position = position - gap
16         a_list[position] = current_value
17
18 a_list = [54, 26, 93, 17, 77, 31, 44, 55, 20]
19 shell_sort(a_list)
20 print(a_list)

希尔排序

  

五:归并排序(Merge Sort)

  原理图:由图可以看出,其也是用了递归原理,base就是只剩一个元素时返回其本身

  

 1 def partition(seq, start, mid, stop):
 2     lst = []
 3     i = start
 4     j = mid
 5     while i < mid and j < stop:
 6         if seq[i] < seq[j]:
 7             lst.append(seq[i])
 8             i+=1
 9         else:
10             lst.append(seq[j])
11             j+=1
12     while i < mid:
13         lst.append(seq[i])
14         i+=1
15     while j < stop:
16         lst.append(seq[j])
17         j+=1
18     for i in range(len(lst)):
19         seq[start+i]=lst[i]
20
21 def mergeSortRecursively(seq, start, stop):
22     if start >= stop-1:
23         return
24     mid = (start + stop) // 2
25     mergeSortRecursively(seq, start, mid)
26     mergeSortRecursively(seq, mid, stop)
27     partition(seq, start, mid, stop)
28
29 a=[3,4,6,8,2,1,5,9]
30 mergeSortRecursively(a, 0, len(a))
31 print(a)

归并排序

  来分析下其时间复杂度吧,由于每次都将list二分,这是logn,而每次排列是n,由于这两小步组成一步,故时间复杂度为O(nlogn)

六:快速排序(Quick Sort)

  原理:如下,第一次以第一个元素为标志,将后面小的放他左边,大的放他右边,而后将其放到中间。第二次分别在其两边重复这样的过程,最后直到每组只有一个数据。

  

  有个需要注意的是最坏情况下为以排好序的集合,那么后面的数都标志大或者小,操作太多或者无效,最理想的是标志能够是平均值左右,故最好对数据进行随机化处理。

  还有,看完代码后注意比较,可以是快速排序与归并排序是某种程度相反的,归并到了最后两个元素才开始排序,从部分有序积累到全部有序,而二分是反的,从第一次二分就是整个数列的二分,,最后二分到只有两个元素时,此时完成了全部有序。

 1 import random
 2 def partition(seq, start, stop):
 3     pivotIndex = start
 4     pivot = seq[pivotIndex]
 5     i = start+1
 6     j = stop-1
 7     while i <= j:
 8         while pivot > seq[i]:
 9             i+=1
10         while pivot < seq[j]:
11             j-=1
12         if i < j:
13             seq[j],seq[i] = seq[i],seq[j]
14             i+=1
15             j-=1
16     seq[pivotIndex],seq[j] = seq[j],pivot
17     return j
18
19 def quicksortRecursively(seq, start, stop):
20     if start >= stop-1:
21         return
22     pivotIndex = partition(seq, start, stop)
23     quicksortRecursively(seq, start, pivotIndex)
24     quicksortRecursively(seq, pivotIndex+1, stop)
25
26 def quicksort(seq):
27 # randomize the sequence first
28     for i in range(len(seq)):
29         j = random.randint(0,len(seq)-1)
30         seq[i],seq[j] = seq[j],seq[i]
31
32     quicksortRecursively(seq, 0, len(seq))
33
34 a=[3,4,6,8,2,1,5,9]
35 quicksort(a)
36 print(a)

快速排序

  同理可以分析出其时间复杂度为O(nlogn)

时间: 2024-12-21 06:48:31

python 下的数据结构与算法---6:6大排序算法的相关文章

python数据结构与算法第八天【排序算法】

1.排序算法的稳定性 稳定排序算法会让原本有相同键值的记录维持相对次序 例如:对以下元组按照元组的第一个元素升序排列,元组如下: (4,1) (3,1) (3,7) (5,6) 若要满足条件,则可能的排序有: 情况一: (3,1) (3,7) (4,1) (5,6) 情况二: (3,7) (3,1) (4,1) (5,6) 虽然情况一和情况二都是满足条件的,但是情况二在满足条件下打破了原本无需改变的顺序 原文地址:https://www.cnblogs.com/liuzhiqaingxyz/p/

数据结构精要------冒泡与直接排序算法

作为程序员的我们在程序开发的时候经常会用到一些简单的排序算法,例如:对数组进行快速排序:要实现这些就需要运用到数据结构排序算法的知识,那么熟练使用和掌握排序算法对于开发人员来说是百利而无一害.同时记录一下知识点也是自己对自己的进一步巩固总结: 那么何为排序算法呢? 排序是计算机内经常进行的一种操作,其目是一组 "无序 "的记录序列调整为 "有序 "的记 录序列.排序分内排序和外排序. 那么何为内排和外排呢? 内排序 :指在排序 期间数据对象全部存放在内存排序. 外排

数据结构与算法系列十(排序算法概述)

1.引子 1.1.为什么要学习数据结构与算法? 有人说,数据结构与算法,计算机网络,与操作系统都一样,脱离日常开发,除了面试这辈子可能都用不到呀! 有人说,我是做业务开发的,只要熟练API,熟练框架,熟练各种中间件,写的代码不也能“飞”起来吗? 于是问题来了:为什么还要学习数据结构与算法呢? #理由一: 面试的时候,千万不要被数据结构与算法拖了后腿 #理由二: 你真的愿意做一辈子CRUD Boy吗 #理由三: 不想写出开源框架,中间件的工程师,不是好厨子 1.2.如何系统化学习数据结构与算法?

十大排序算法总结(Python3实现)

十大排序算法总结(Python3实现) 本文链接:https://blog.csdn.net/aiya_aiya_/article/details/79846380 目录 一.概述 二.算法简介及代码展示 1.冒泡排序 2.简单选择排序 3.简单插入排序 4.堆排序 5.快速排序 6.希尔排序 7.归并排序 8.计数排序 9.桶排序 10.基数排序 11.#代码说明 三.感悟总结 ________________________________________ 一.概述 排序算法大概是hello

8大排序算法图文讲解

排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 常见的内部排序算法有:插入排序.希尔排序.选择排序.冒泡排序.归并排序.快速排序.堆排序.基数排序等. 本文将依次介绍上述八大排序算法. 算法一:插入排序 插入排序示意图 插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入. 算法步骤: 1)将第一待排序序列第一

九大排序算法总结

九大排序算法再总结 算法的由来:9世纪波斯数学家提出的:“al-Khowarizmi” 排序的定义: 输入:n个数:a1,a2,a3,...,an 输出:n个数的排列:a1',a2',a3',...,an',使得a1'<=a2'<=a3'<=...<=an'. In-place sort(不占用额外内存或占用常数的内存):插入排序.选择排序.冒泡排序.堆排序.快速排序. Out-place sort:归并排序.计数排序.基数排序.桶排序. 当需要对大量数据进行排序时,In-plac

面试——8大排序算法图文讲解

排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 常见的内部排序算法有:插入排序.希尔排序.选择排序.冒泡排序.归并排序.快速排序.堆排序.基数排序等. 本文将依次介绍上述八大排序算法. 算法一:插入排序 插入排序示意图 插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入. 算法步骤: 1)将第一待排序序列第一

九大排序算法Java实现

之前学习数据结构与算法时花了三天时间整理九大排序算法,并采用Java语言来实现,今天第一次写博客,刚好可以把这些东西从总结的文档中拿出来与大家分享一下,同时作为自己以后的备忘录. 1.排序算法时间复杂度.稳定性分类: 2.排序算法问题描述与实现 2.1冒泡排序(交换排序-稳定) [问题描述]对于一个int数组,请编写一个冒泡排序算法,对数组元素排序. 问题分析:冒泡排序,顾名思义,从前往后遍历,每次遍历在末尾固定一个最大值. 易错点:每次内层循环结束都会在末尾确定一个元素的位置,因此内层循环的判

九大排序算法及其实现- 插入.冒泡.选择.归并.快速.堆排序.计数.基数.桶排序

  闲着的时候看到一篇“九大排序算法在总结”,瞬间觉得之前数据结构其实都有学过,但当初大多数都只是老师随口带过,并没有仔细研究一下.遂觉:这是欠下的账,现在该还了.   排序按照空间分类: In-place sort不占用额外内存或占用常数的内存 插入排序.选择排序.冒泡排序.堆排序.快速排序. Out-place sort:归并排序.计数排序.基数排序.桶排序. 或者按照稳定性分类: stable sort:插入排序.冒泡排序.归并排序.计数排序.基数排序.桶排序. unstable sort

链表插入和删除,判断链表是否为空,求链表长度算法的,链表排序算法演示——C语言描述

关于数据结构等的学习,以及学习算法的感想感悟,听了郝斌老师的数据结构课程,其中他也提到了学习数据结构的或者算法的一些个人见解,我觉的很好,对我的帮助也是很大,算法本就是令人头疼的问题,因为自己并没有学习过算法的系统性的课程,现在还是处于不断摸索的阶段,好多算法题目根本就没有什么思路,导致自己对好多题目都很是头疼,就算是自己做过的一些算法的题目,再次遇到也还是不一定会做出来,他给出的建议就是,看懂别人的程序,然后自己去敲,一定会出错,然后调试,有错误接着调试,一直到没有错误为止,并且要时常的去复习