主要参考:

八大排序算法的 Python 实现
http://python.jobbole.com/82270/

算法导论

以下摘自:伯乐在线:http://blog.jobbole.com/70639/

    

归并排序算法是目前为止我们拥有的最重要的算法之一。它是一种基于比较的排序算法,使用分治法解决那些原本复杂度为O(N^2)的问题。归并排序是由数学家John von Neumann于1945年发明的。

快速排序是解决排序问题的另一种途径,它使用就地分解算法,同时它也是一种分治算法。这个算法的问题在于它是不稳定的排序算法,但它在基于内存的数组排序上确实非常高效。

最后,堆排序算法使用一个优先队列降低数据的查找时间,它也是一种就地排序算法,同样也是不稳定的排序算法。

相较于曾经使用的其他排序算法(如冒泡排序),上述算法带来了显著的改进。事实上,多亏了它们,今天我们才有了数据挖掘、人工智能、链接分析,以及世界上大部分的计算机工具,也包括网络在内。

先来感受一下排序的可视化吧:

用舞蹈来诠释排序算法,欢乐多多!

冒泡排序: http://t.cn/hrf58M

希尔排序:http://t.cn/hrosvb

选择排序:http://t.cn/hros6e

插入排序:http://t.cn/hros0W

快速排序:http://t.cn/ScTA1d

归并排序:http://t.cn/Sc1cGZ

视觉直观感受 7 种常用的排序算法

http://blog.jobbole.com/11745/

可视化对比十多种排序算法(C#版)

http://blog.jobbole.com/72850/

接下来自己实践操作一番

每个算法 先来段舞蹈观赏一下,然后找来各路牛人最直白的解释,最后是Python代码

1. 插入排序:

http://t.cn/hros0W

http://www.cnblogs.com/kkun/archive/2011/11/23/2260265.html

http://blog.jobbole.com/72850/

它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

如上图例子,

(a)有序序列:4,未排序:3,1,2,从3开始,从后向前,先跟4比较大小,如果3<4,则交换二者位置

Insertion sort works the way many people sort a hand of playing cards.

We start with an empty left hand and the cards face down on the table.

We then remove one card at a time from the table and insert it into the correct position in the left hand.

To find the correct position for a card, we compare it with each of the cards already in the hand, from right to left,

def insert_sort(lists):# 插入排序count = len(lists)for i in range(<span style="color:#ff0000;">1</span>, count):key = lists[i]j = i - 1while j >= 0:if lists[j] > key:<span style="color:#ff0000;">lists[j + 1] = lists[j]lists[j] = key</span>j -= 1return lists
class solution():def insersort(self,array):for i in range(1,len(array)):while array[i-1]>array[i] and i>=1:t=array[i-1]array[i-1]=array[i]array[i]=ti-=1return array#array=[4,2,1,3]
array=[4,3,2,1,3]
r=solution().insersort(array)print(r)<span style="white-space:pre">                   </span>#[1, 2, 3, 3, 4]

2. 冒泡排序:

http://t.cn/hrf58M

http://www.cnblogs.com/kkun/archive/2011/11/23/2260280.html

http://blog.csdn.net/morewindows/article/details/6657829

             

上图:

每次比较相邻的两个元素,如果第一个比第二个大,就交换他们两个。

第一轮,从0到N-1,会把最大的元素沉到最后一位

第二轮,从0到N-2

从0到N-3

一直到排完所有

复杂度分析:

http://www.cnblogs.com/jiqingwu/p/bubble_sort_analysis.html

<pre name="code" class="python">def bubblesort(A):for i in range(<span style="color:#ff0000;">0,len(A))</span>:for j in range(<span style="color:#ff0000;">1,len(A)-i)</span>:if A[<span style="color:#ff0000;">j-1]>A[j</span>]:A[j-1],A[j]=A[j],A[j-1]return A

i用来记录从后向前已经被沉淀好的位置

3. 快速排序:

http://t.cn/ScTA1d

http://blog.csdn.net/morewindows/article/details/6684558

Quicksort, applies the divide-and-conquer paradigm

Here is the three-step divide-and-conquer process for sorting a typical subarray A[p,r]
Divide: Partition (rearrange) the array A[p,r] into two (possibly empty) subarrays A[p,q-1] and A[p+1,r] such that each element of A[p,q-1] is less than or equal to A[q] ,

which is, in turn, less than or equal to each element of A[p+1,r]  .

Compute the index q as part of this partitioning procedure.
Conquer: Sort the two subarrays A[p,q-1] and A[p+1,r] by recursive calls to quicksort.

Combine: Because the subarrays are already sorted,no work is needed to combine them: the entire array A[p,r] is now sorted.

</pre><pre name="code" class="python">def quicksort(A<span style="color:#ff0000;">,p,r</span>):<span style="color:#ff0000;">if p<r:</span>q=Partition(A,p,r)quicksort(A,p,q-1)quicksort(A,q+1,r)def Partition(A,p,r):pivot=A[r]i=p-1for j in range(p,r):if A[j]<<span style="color:#ff0000;">=</span>pivot:i=i+1A[i],A[j]=A[j],A[i]A[i+1],A[r]=A[r],A[i+1]return i+1

4. 选择排序:

http://t.cn/hros6e

The algorithm divides the input list into two parts: the sublist of items already sorted, which is built up from left to right at the front (left) of the list,

and the sublist of items remaining to be sorted that occupy the rest of the list.

Initially, the sorted sublist is empty and the unsorted sublist is the entire input list.

The algorithm proceeds by finding the smallest (or largest, depending on sorting order) element in the unsorted sublist,

exchanging (swapping) it with the leftmost unsorted element (putting it in sorted order), and moving the sublist boundaries one element to the right.

It has O(n2) time complexity, making it inefficient on large lists, and generally performs worse than the similar insertion sort. Selection sort is noted for its simplicity, and it has performance advantages over more complicated algorithms in certain situations, particularly where auxiliary memory is limited.

Python:
def select_sort(lists):# 选择排序count = len(lists)for i in range(<span style="color:#ff0000;">0, </span>count):min = ifor j in range(i + 1, count):if lists[<span style="color:#ff0000;">min</span>] > lists[j]:min = jlists[min], lists[i] = lists[i], lists[min]return lists

5. 基数排序:

http://blog.csdn.net/cjf_iceking/article/details/7943609

radix sort is a non-comparative integer sorting algorithm that sorts data with integer keys

by grouping keys by the individual digits

which share the same significant position and value.

基数排序(以整形为例),将整形10进制按每位拆分,然后从低位到高位依次比较各个位。主要分为两个过程:
(1)分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中(比如53,个位为3,则放入3号桶中)
(2)收集,再将放置在0~9号桶中的数据按顺序放到数组中

平均时间复杂度:O(dn)(d即表示整形的最高位数)

空间复杂度:O(10n) (10表示0~9,用于存储临时的序列)

稳定性:稳定

Python:

<span style="color:#ff0000;">import math</span>
def radix_sort(lists, radix=10):k = int(math.ceil(math.log(max(lists), <span style="color:#ff0000;">radix</span>)))bucket = [[] for i in range(<span style="color:#ff0000;">radix</span>)]for i in range(1, k+1):for j in lists:bucket[j/(radix**(i-1)) % radix].append(j)del lists[:]for z in bucket:lists += zdel z[:]return lists

6. 堆排序

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。

Heapsort also introduces another algorithm design technique: using a data structure, in this case one we call a “heap,” to manage information.

可以利用数组的特点快速定位指定索引的元素。

its height is Theta(lgn)

Running time is O(nlgn)

The (binary) heap data structure is an array object that we can view as a nearly complete binary tree

(The tree is completely filled on all levels except possibly the lowest, which is filled from the left up to a point)

The root of the tree is A[1] , and given the index i of a node, we can easily compute the indices of its parent, left child, and right child:

堆分为大根堆和小根堆,

大根堆的要求是每个节点的值都不大于其父节点的值,即

In a max-heap, the max-heap property is that for every node i other than the root,

A[PARENT[i]] >= A[i]。

(Thus, the largest element in a max-heap is stored at the root)

在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。

For the heapsort algorithm, we use max-heaps.

MAX-HEAPIFY(A,i)

Maintaining the heap property
At each step, the largest of the elements A[i], A[LEFT(i)], and A[RIGHT(i)] is determined, and its index is stored in largest.

call MAX-HEAPIFY recursively on that subtree.

the running time of MAX- HEAPIFY on a node of height h as O(h)

BUILD-MAX-HEAP(A)

use the procedure MAX-HEAPIFY in a bottom-up manner to convert an array A[1...n] , where n=A: length, into a max-heap.

Each call to MAX-HEAPIFY costs O(lgn) time, and BUILD- MAX-HEAP makes O(n) such calls. Thus, the running time is O(n lg n)

we can build a max-heap from an unordered array in linear time.

HEAPSORT(A)

The heapsort algorithm starts by using BUILD-MAX-HEAP to build a max-heap on the input array A[1...n] ,

Since the maximum element of the array is stored at the root A[1], put it into its correct final position

decrementing A:heap-size—we observe that the children of the root remain max-heaps

The HEAPSORT procedure takes time O(n lg n)

since the call to BUILD-MAX- HEAP takes time O(n) and each of the n-1 calls to MAX-HEAPIFY takes time O(lgn)

先build一个heap,有个特性是root处是最大值,

所以把最大值交换到末尾,然后再main地build一个heap,得到第二大的值

再次交换,再次maintain

def adjust_heap(lists, i, <span style="color:#ff0000;">size)</span>:<span style="color:#ff0000;">lchild = 2 * i + 1rchild = 2 * i + 2max = i</span>if <span style="color:#ff0000;">lchild < size </span>and lists[lchild] > lists[max]:max = lchildif <span style="color:#ff0000;">rchild < size </span>and lists[rchild] > lists[max]:max = rchildif <span style="color:#ff0000;">max != i:</span><span style="color:#ff0000;">lists[max], lists[i] = lists[i], lists[max]</span>adjust_heap(lists, max, size)def build_heap(lists, <span style="color:#ff0000;">size</span>):for i in range(<span style="color:#ff0000;">int</span>(size/2),-1,-1):adjust_heap(lists, <span style="color:#ff0000;">i, size</span>)def heap_sort(lists):<span style="color:#ff0000;">size = len(lists)</span>build_heap(lists, <span style="color:#ff0000;">size</span>)for i in range(size-1,0,-1):lists[<span style="color:#ff0000;">0</span>], lists[i] = lists[i], lists[0]
<span style="white-space:pre">  </span><span style="color:#ff0000;">size-=1</span>
        adjust_heap(lists, <span style="color:#ff0000;">0,</span> size)

size从A的0开始数到size

7.归并排序:

http://t.cn/Sc1cGZ

https://en.wikipedia.org/wiki/Merge_sort

Mergesort is a divide and conquer algorithm that was invented by John von Neumann in 1945.

Conceptually, a merge sort works as follows:
Divide the unsorted list into n sublists, each containing 1 element (a list of 1 element is considered sorted).
Repeatedly merge sublists to produce new sorted sublists until there is only 1 sublist remaining. This will be the sorted list.

归并排序最令人兴奋的特点是:不论输入是什么样的,它对N个元素的序列排序所用时间与NlogN成正比。http://blog.csdn.net/littlethunder/article/details/9472301

http://www.pythontab.com/html/2014/pythonhexinbiancheng_1114/910.html

归并排序也称合并排序,是分治法的典型应用。

分治思想是将每个问题分解成个个小问题,将每个小问题解决,然后合并。

具体的归并排序就是,将一组无序数按n/2递归分解成只有一个元素的子项,一个元素就是已经排好序的了。

然后将这些有序的子元素进行合并。

合并的过程就是 对 两个已经排好序的子序列,先选取两个子序列中最小的元素进行比较,

选取两个元素中最小的那个子序列并将其从子序列中去掉添加到最终的结果集中,直到两个子序列归并完成。

复杂度分析:

http://xwrwc.blog.163.com/blog/static/46320003201141582544245/

这是一个递推公式(Recurrence),我们需要消去等号右侧的T(n)

把T(n/2)展开成2T(n/4)+cn/2(下图中的(c)),然后再把T(n/4)进一步展开,直到最后全部变成T(1)=c

这是一个树状结构,每一层的和都是cn,共有lgn+1层,因此总的执行时间是cnlgn+cn,相比nlgn来说,cn项可以忽略,因此T(n)的上界是Θ(nlgn)。

T(n)的上下界都是Θ(nlgn),显然T(n)就是Θ(nlgn)。

http://blog.csdn.net/littlethunder/article/details/9472301

将一组无序数按n/2递归分解成只有一个元素的子项,一个元素就是已经排好序的了。

def mergesort(seq):  if len(seq)<=1:  return seq  mid=int(len(seq)/2)  left=<span style="color:#ff0000;">mergesort</span>(seq[:mid])  right=<span style="color:#ff0000;">mergesort</span>(seq[mid:])  return merge(left,right)  

然后将这些有序的子元素进行合并。

合并的过程就是 对 两个已经排好序的子序列,先选取两个子序列中最小的元素进行比较,

选取两个元素中最小的那个子序列并将其从子序列中去掉添加到最终的结果集中,直到两个子序列归并完成。

def merge(left,right):  <span style="color:#ff0000;">result=[]  </span>i,j=0,0  <span style="color:#ff0000;"> while i<len(left) and j<len(right):</span>  if left[i]<<span style="color:#ff0000;">=</span>right[j]:  result.append(left[i])  i+=1  else:  result.append(right[j])  j+=1
<span style="color:#ff0000;">    result+=left[i:]  result+=right[j:]  </span>return result  

对链表进行归并排序

需要额外写一个获得mid的点

http://bookshadow.com/weblog/2014/11/21/leetcode-sort-list/

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:# @param head, a ListNode# @return a ListNodedef sortList(self, head):if head is None or head.next is None:return headmid = self.getMiddle(head)rHead = mid.nextmid.next = Nonereturn self.merge(self.sortList(head), self.sortList(rHead))def merge(self, lHead, rHead):dummyNode = ListNode(0)dummyHead = dummyNodewhile lHead and rHead:if lHead.val < rHead.val:dummyHead.next = lHeadlHead = lHead.nextelse:dummyHead.next = rHeadrHead = rHead.nextdummyHead = dummyHead.nextif lHead:dummyHead.next = lHeadelif rHead:dummyHead.next = rHeadreturn dummyNode.nextdef getMiddle(self, head):if head is None:return headslow = headfast = headwhile fast.next and fast.next.next:slow = slow.nextfast = fast.next.nextreturn slow

其他:

http://www.cnblogs.com/jingmoxukong/p/4308823.html

http://blog.csdn.net/morewindows/article/details/6678165/

8.希尔排序:

http://t.cn/hrosvb

http://blog.csdn.net/morewindows/article/details/6668714

希尔排序(Shell Sort)也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。

该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,

随着增量逐渐减少,每组包含的关键词越来越多,

当增量减至1时,整个文件恰被分成一组,算法便终止。

因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。

舞蹈例子,

第一次,把10分成 2 份,此时增量 10/2 = 5 ,第二组从 0+5=5 开始,然后第2组的各个元素与前面距离自己5步的元素进行比较

第二次,把5分成 2 份,此时增量 5/2 = 2 ,第二组从 0+2=2开始,然后第2组的各个元素与距离自己2步的第1组各个元素进行比较

当增量减至1时,整个文件恰被分成一组,一次插入排序后,完成,算法便终止。

class solution():def shellsort(self,array):l=int(len(array)/2)while l>0:#l=int(l/2)for i in range(l,len(array)):while i>=l:if array[i]<array[i-l]:t=array[i-l]array[i-l]=array[i]array[i]=ti-=ll=int(l/2)return arrayarray=[49,38,65,97,26,13,27,49,55,4]
r=solution().shellsort(array)
print(r)

http://blog.jobbole.com/72850/

这个应该是标准的希尔排序吧

class solution():def shellsort(self,array):step=int(len(array)/2)while step>0:for i in range(step):for j in range(i+step,len(array),step):
<span style="white-space:pre">      </span>    <span style="color:#ff0000;">k=j-step</span>
<span style="color:#ff0000;"><span style="white-space:pre">        </span>    key=array[j]while k>0:if array[k]>key:array[k+group]=array[k]                         </span><pre name="code" class="python"><span style="color:#ff0000;"><span style="white-space:pre">          </span>    array[k]=key</span>

k-=step

step=int(step/2)return arrayarray=[49,38,65,97,26,13,27,49,55,4]
r=solution().shellsort(array)
print(r)

内部相当于快速排序的partition部分

【算法】-8大排序算法总结-Python相关推荐

  1. 排序算法——十大排序算法的图示与实现

    十大排序算法概览 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序. 非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于 ...

  2. 排序算法——十大排序算法总结与对比

    一.十大排序算法复杂度对比 二.关于排序算法的总结 1.基数排序仅仅适用于整型数的排序,一般不与另外的排序方法一起比较. 2.关于算法的稳定性:不稳定的算法有 "快希选堆"--快速 ...

  3. 八十八、Python | 十大排序算法系列(下篇)

    @Author:Runsen @Date:2020/7/10 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏 ...

  4. 八十七、Python | 十大排序算法系列(上篇)

    @Author:Runsen @Date:2020/7/10 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏 ...

  5. 一篇夯实一个知识点系列--python实现十大排序算法

    写在前面 排序是查找是算法中最重要的两个概念,我们大多数情况下都在进行查找和排序.科学家们穷尽努力,想使得排序和查找能够更加快速.本篇文章用Python实现十大排序算法. 很多人学习python,不知 ...

  6. python快速排序算法没看懂_你需要知道的九大排序算法【Python实现】之快速排序...

    五.快速排序 基本思想:  通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,则分别对这两部分继续进行排序,直到整个序列有序. 算法实现: ​ #coding: ...

  7. 这或许是东半球分析十大排序算法最好的一篇文章

    作者 | 不该相遇在秋天 转载自五分钟学算法(ID:CXYxiaowu) 前言 本文全长 14237 字,配有 70 张图片和动画,和你一起一步步看懂排序算法的运行过程. 预计阅读时间 47 分钟,强 ...

  8. C++实现十大排序算法(冒泡,选择,插入,归并,快速,堆,希尔,桶,计数,基数)排序算法时间复杂度、空间复杂度、稳定性比较(面试经验总结)

    排序算法分类 内部排序算法又分为基于比较的排序算法和不基于比较的排序算法,其分类如下: 比较排序:   直接插入排序    希尔排序 (插入)  冒泡排序     快速排序  (交换) 直接选择排序  ...

  9. 「干货总结」程序员必知必会的十大排序算法

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:硬刚一周,3W字总结,一年的经验告诉你如何准备校招! 个人原创100W+访问量博客:点击前往,查看更多 绪论 身 ...

  10. 「归纳|总结」程序员必知必会的十大排序算法

    微信搜一搜「bigsai」关注这个有趣的程序员 新人原创公众号,求支持一下!你的点赞三连肯定对我至关重要! 文章已收录在 我的Github bigsai-algorithm 欢迎star 本文目录 绪 ...

最新文章

  1. HDU5934(强连通分量)
  2. flowJS源码个人分析
  3. Progressbar 实现从右向左 加载(逆向)
  4. 东软java的笔试_东软的笔试题
  5. 如何运行vue项目(从gethub上download的开源项目)
  6. java通过jdbc访问mysql,update数据返回值的思考
  7. SCVMM Self-Service Portal 2.0 SP1安装体验
  8. Spring+SpringMVC+maven使用@aspectJ添加切面
  9. 知名PS滤镜合集工具Nik Collection 4 for Mac
  10. Linux多台机器配置ssh免登录
  11. vba6.3提取自WPS2012专业增强版 带教程 (wps可能是因为该宏在此工作簿中不可用)
  12. 字体变换大小的html代码,JQuery 实时改变网页字体大小的代码
  13. 微信公众号迁移保持OPENID不变新老账户粉丝迁移问题
  14. HighCharts柱状图显示百分比
  15. 【论文笔记】covid-19肺部感染区域分割基准
  16. 前端常用PS技巧总结之更换图片背景颜色
  17. 京东Q3财报净亏损28亿元,连续亏损,徐雷会下课吗?
  18. openwrt 做二级路由 同网段无线桥接教程 relayd
  19. Profile多环境支持
  20. 创:战纪 的严重剧透

热门文章

  1. 基于微信小程序的自驾旅游管理系统
  2. java 区分中英文_Java 区分文本中的中英文字符函数
  3. iGrimaceV8 V8在线威锋源apt.so/qwkjv8手机直接下载安装教程图:
  4. 微信小程序-如何解决onShareAppMessage转发gif格式图片不展示?【亲测有效】
  5. 用Python把20年的GDP、人口以及房价数据进行了可视化
  6. Python Tkinter Text控件随输入自动拓展到尾行
  7. 辞职信辞职信辞职信辞职信
  8. 【网络通讯开发系列】如何使用C语言编程通过UDP通讯解析域名
  9. 2021年N1叉车司机复审考试及N1叉车司机模拟试题
  10. 专访:InMobi全球CEO Naveen Tewari