归并排序算法是目前为止我们拥有的最重要的算法之一。它是一种基于比较的排序算法,使用分治法解决那些原本复杂度为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,

[python] view plain copy
  1. def insert_sort(lists):
  2. # 插入排序
  3. count = len(lists)
  4. for i in range(<span style="color:#ff0000;">1</span>, count):
  5. key = lists[i]
  6. j = i - 1
  7. while j >= 0:
  8. if lists[j] > key:
  9. <span style="color:#ff0000;">lists[j + 1] = lists[j]
  10. lists[j] = key</span>
  11. j -= 1
  12. return lists
[python] view plain copy
  1. class solution():
  2. def insersort(self,array):
  3. for i in range(1,len(array)):
  4. while array[i-1]>array[i] and i>=1:
  5. t=array[i-1]
  6. array[i-1]=array[i]
  7. array[i]=t
  8. i-=1
  9. return array
  10. #array=[4,2,1,3]
  11. array=[4,3,2,1,3]
  12. r=solution().insersort(array)
  13. 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

[python] view plain copy
  1. <pre name="code" class="python">def bubblesort(A):
  2. for i in range(<span style="color:#ff0000;">0,len(A))</span>:
  3. for j in range(<span style="color:#ff0000;">1,len(A)-i)</span>:
  4. if A[<span style="color:#ff0000;">j-1]>A[j</span>]:
  5. A[j-1],A[j]=A[j],A[j-1]
  6. 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.

[python] view plain copy
  1. </pre><pre name="code" class="python">def quicksort(A<span style="color:#ff0000;">,p,r</span>):
  2. <span style="color:#ff0000;">if p<r:</span>
  3. q=Partition(A,p,r)
  4. quicksort(A,p,q-1)
  5. quicksort(A,q+1,r)
  6. def Partition(A,p,r):
  7. pivot=A[r]
  8. i=p-1
  9. for j in range(p,r):
  10. if A[j]<<span style="color:#ff0000;">=</span>pivot:
  11. i=i+1
  12. A[i],A[j]=A[j],A[i]
  13. A[i+1],A[r]=A[r],A[i+1]
  14. 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:
[python] view plain copy
  1. def select_sort(lists):
  2. # 选择排序
  3. count = len(lists)
  4. for i in range(<span style="color:#ff0000;">0, </span>count):
  5. min = i
  6. for j in range(i + 1, count):
  7. if lists[<span style="color:#ff0000;">min</span>] > lists[j]:
  8. min = j
  9. lists[min], lists[i] = lists[i], lists[min]
  10. 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:

[python] view plain copy
  1. <span style="color:#ff0000;">import math</span>
  2. def radix_sort(lists, radix=10):
  3. k = int(math.ceil(math.log(max(lists), <span style="color:#ff0000;">radix</span>)))
  4. bucket = [[] for i in range(<span style="color:#ff0000;">radix</span>)]
  5. for i in range(1, k+1):
  6. for j in lists:
  7. bucket[j/(radix**(i-1)) % radix].append(j)
  8. del lists[:]
  9. for z in bucket:
  10. lists += z
  11. del z[:]
  12. 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

[python] view plain copy
  1. def adjust_heap(lists, i, <span style="color:#ff0000;">size)</span>:
  2. <span style="color:#ff0000;">lchild = 2 * i + 1
  3. rchild = 2 * i + 2
  4. max = i</span>
  5. if <span style="color:#ff0000;">lchild < size </span>and lists[lchild] > lists[max]:
  6. max = lchild
  7. if <span style="color:#ff0000;">rchild < size </span>and lists[rchild] > lists[max]:
  8. max = rchild
  9. if <span style="color:#ff0000;">max != i:</span>
  10. <span style="color:#ff0000;">lists[max], lists[i] = lists[i], lists[max]</span>
  11. adjust_heap(lists, max, size)
  12. def build_heap(lists, <span style="color:#ff0000;">size</span>):
  13. for i in range(<span style="color:#ff0000;">int</span>(size/2),-1,-1):
  14. adjust_heap(lists, <span style="color:#ff0000;">i, size</span>)
  15. def heap_sort(lists):
  16. <span style="color:#ff0000;">size = len(lists)</span>
  17. build_heap(lists, <span style="color:#ff0000;">size</span>)
  18. for i in range(size-1,0,-1):
  19. lists[<span style="color:#ff0000;">0</span>], lists[i] = lists[i], lists[0]
[python] view plain copy
  1. <span style="white-space:pre">    </span><span style="color:#ff0000;">size-=1</span>
[python] view plain copy
  1. 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递归分解成只有一个元素的子项,一个元素就是已经排好序的了。

[python] view plain copy
  1. def mergesort(seq):
  2. if len(seq)<=1:
  3. return seq
  4. mid=int(len(seq)/2)
  5. left=<span style="color:#ff0000;">mergesort</span>(seq[:mid])
  6. right=<span style="color:#ff0000;">mergesort</span>(seq[mid:])
  7. return merge(left,right)

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

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

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

[python] view plain copy
  1. def merge(left,right):
  2. <span style="color:#ff0000;">result=[]  </span>
  3. i,j=0,0
  4. <span style="color:#ff0000;"> while i<len(left) and j<len(right):</span>
  5. if left[i]<<span style="color:#ff0000;">=</span>right[j]:
  6. result.append(left[i])
  7. i+=1
  8. else:
  9. result.append(right[j])
  10. j+=1
  11. <span style="color:#ff0000;">    result+=left[i:]
  12. result+=right[j:]  </span>
  13. return result

对链表进行归并排序

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

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

[python] view plain copy
  1. # Definition for singly-linked list.
  2. # class ListNode:
  3. #     def __init__(self, x):
  4. #         self.val = x
  5. #         self.next = None
  6. class Solution:
  7. # @param head, a ListNode
  8. # @return a ListNode
  9. def sortList(self, head):
  10. if head is None or head.next is None:
  11. return head
  12. mid = self.getMiddle(head)
  13. rHead = mid.next
  14. mid.next = None
  15. return self.merge(self.sortList(head), self.sortList(rHead))
  16. def merge(self, lHead, rHead):
  17. dummyNode = ListNode(0)
  18. dummyHead = dummyNode
  19. while lHead and rHead:
  20. if lHead.val < rHead.val:
  21. dummyHead.next = lHead
  22. lHead = lHead.next
  23. else:
  24. dummyHead.next = rHead
  25. rHead = rHead.next
  26. dummyHead = dummyHead.next
  27. if lHead:
  28. dummyHead.next = lHead
  29. elif rHead:
  30. dummyHead.next = rHead
  31. return dummyNode.next
  32. def getMiddle(self, head):
  33. if head is None:
  34. return head
  35. slow = head
  36. fast = head
  37. while fast.next and fast.next.next:
  38. slow = slow.next
  39. fast = fast.next.next
  40. return 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时,整个文件恰被分成一组,一次插入排序后,完成,算法便终止。

[python] view plain copy
  1. class solution():
  2. def shellsort(self,array):
  3. l=int(len(array)/2)
  4. while l>0:
  5. #l=int(l/2)
  6. for i in range(l,len(array)):
  7. while i>=l:
  8. if array[i]<array[i-l]:
  9. t=array[i-l]
  10. array[i-l]=array[i]
  11. array[i]=t
  12. i-=l
  13. l=int(l/2)
  14. return array
  15. array=[49,38,65,97,26,13,27,49,55,4]
  16. r=solution().shellsort(array)
  17. print(r)

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

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

[python] view plain copy
  1. class solution():
  2. def shellsort(self,array):
  3. step=int(len(array)/2)
  4. while step>0:
  5. for i in range(step):
  6. for j in range(i+step,len(array),step):
[python] view plain copy
  1. <span style="white-space:pre">        </span>    <span style="color:#ff0000;">k=j-step</span>
[python] view plain copy
  1. <span style="color:#ff0000;"><span style="white-space:pre">     </span>    key=array[j]
  2. while k>0:
  3. if array[k]>key:
  4. 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

[python] view plain copy
  1. step=int(step/2)
  2. return array
  3. array=[49,38,65,97,26,13,27,49,55,4]
  4. r=solution().shellsort(array)
  5. print(r)

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

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

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

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

  2. 【Kick Algorithm】十大排序算法及其Python实现

    文章来源于NewBeeNLP,作者kaiyuan 写在前面 看到好像春招都已经陆续都开始了,最近抽空打算把自己和朋友的经验整理一下分享出来.作为一个刚刚经历秋招打击的自闭儿童,可以非常负责任地说手撕算 ...

  3. 数据结构十大排序算法(python)

    十大经典排序算法 (java实现看这个)https://program.blog.csdn.net/article/details/83785159 名词解释: 1.冒泡排序 2.选择排序 3.插入排 ...

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

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

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

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

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

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

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

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

  8. 八大排序算法的 Python 实现

    八大排序算法的 Python 实现 本文用Python实现了插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入 ...

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

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

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

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

最新文章

  1. php mysql emoji表情_php 让MySQL支持Emoji表情 mysql 5.5.3+
  2. 如何在服务器中找到数据库文件夹,如何在服务器中找到数据库文件
  3. 【转】D3DLOCK详解
  4. boost::fusion::map用法的测试程序
  5. 铃木uy125摩托车机油_UY125 新瑞梦UM125发布 济南铃木于湖南株洲吹响国IV集结号...
  6. VMware扩展Tanzu产品系列与合作关系
  7. 我肝了一个月,给你写出了这本 Java 开发手册!
  8. T-SQL查询进阶--理解SQL Server中索引的概念,原理以及其他
  9. 设计模式面试题_2020年最全设计模式面试题总结!面试再也不用怕!已有千人收藏
  10. tombstone 信息解析
  11. 计算机技术专业求职简历,计算机技术专业求职简历模板
  12. PID控制器及其参数整定
  13. mariaDB数据库安装
  14. 修改win10搜索框(Cortana)调用默认浏览器(edge)和搜索引擎
  15. Oracle进阶(六)包(Package)和包体
  16. 2017CCPC中南地区赛暨湘潭大学邀请赛总结
  17. 银行,金融行业的清分,结算,清算,核算到底是什么含义? 现金需要搬运么?
  18. 二、极大联通子图、极小联通子图
  19. 全志平台Android4.0 SOFTAP STATION共存调试记录1
  20. Wireshark(2)-协议分析的起点

热门文章

  1. 阿法狗之后的围棋世界
  2. 数据挖掘十大算法---朴素贝叶斯
  3. 《Improving Cross-lingual Text Classification with Zero-shot Instance-Weighting》论文笔记
  4. archlinux触摸板设置
  5. ERP系统借贷关系表
  6. rar压缩包解开加密在线,忘记rar压缩包密码如何找回?
  7. php ligerui 导出excel,LigerUI表格树的使用
  8. 搜狐新闻数据400w+
  9. 秘密:从程序员到领导者的微妙之处
  10. HTML5+CSS3初学尝试(小米官网首页)