Python实现常用排序算法

一.冒泡排序

  • 冒泡排序算法的运作如下:

1.比较相邻元素,如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素做同样的工作,从开始第一队到结尾最后一对。在这一点,最后的元素应该会是最大的数。
3.针对所有的元素重复以上步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,知道没有任何一对数字需要比较。

  • 时间复杂度:

若文件的初始状态是正序的,一趟扫描可以完成排序,此时最小时间复杂度为O(n)。
若文件初始状态是反序的,最大时间复杂度为O(n)。

  • 稳定性:冒泡排序是一种稳定的排序算法。

  • 代码:

#!/usr/bin/env python
#coding=utf-8
#BubbleSort
def BubbleSort(SortList):
    ListLength = len(SortList)
    while ListLength > 0:
        for i in range(ListLength - 1):
            if SortList[i] > SortList[i+1]:
                SortList[i] = SortList[i] + SortList[i+1]
                SortList[i+1] = SortList[i] - SortList[i+1]
                SortList[i] = SortList[i] - SortList[i+1]
        ListLength -= 1
    print SortList

if __name__ == '__main__':
    SortList = [6,5,4,3,2,1]
    BubbleSort(SortList)
  • 执行结果:

/usr/bin/python2.7 /root/PycharmProjects/01/BubbleSort.py
[1, 2, 3, 4, 5, 6]

Process finished with exit code 0

二.快速排序

  • 基本思想:

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按照此方法对两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

  • 代码:

def QuickSort(L,low,high):
    i = low
    j = high
    if i >= j:
        return L
    key = L[i]
    while i < j:
        while i < j and L[j] >=key:
            j -= 1
        L[i] = L[j]
        while i < j and L[i] <= key:
            i += 1
        L[j] = L[i]
    L[i] = key
    QuickSort(L,low,i-1)
    QuickSort(L,j+1,high)
    return L

if __name__ == '__main__':
    L = [6,5,4,8,2,1]
    QuickSort(L,0,len(L)-1)
    print L
  • 执行结果:

/usr/bin/python2.7 /root/PycharmProjects/01/QuickSort.py
[1, 2, 4, 5, 6, 8]

Process finished with exit code 0

三.归并排序

  • 基本思想

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序,若将两个有序表合并成一个有序表,称为二路归并。

  • 工作原理:
    第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列。
    第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置。
    第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置,重复三步骤直到某一指针超出序列尾,将另一序列剩下的所有元素直接复制到合并序列尾。

  • 比较:归并排序为稳定排序,比较次数小于快速排序的比较次数,移动次数多于快速排序的移动次数。

  • 代码:

def MergeSort(lists):
    if len(lists) <= 1:
        return lists
    num = int( len(lists) / 2 )
    left = MergeSort(lists[:num])
    right = MergeSort(lists[num:])
    return Merge(left,right)
def Merge(left,right):
    r, l=0, 0
    result=[]
    while l<len(left) and r<len(right):
        if left[l] < right[r]:
            result.append(left[l])
            l += 1
        else:
            result.append(right[r])
            r += 1
    result += left[l:]
    result += right[r:]
    return result
print MergeSort([1,2,3,4,5,6,7,88,99,18])
  • 执行结果
/usr/bin/python2.7 /root/PycharmProjects/01/MergeSort.py
[1, 2, 3, 4, 5, 6, 7, 18, 88, 99]

Process finished with exit code 0

四.桶排序

  • 桶排序工作原理
    将数组分到有限量的的桶子里,每个桶子再个别排序(有可能使用别的排序算法或是以递归方式继续使用桶排序进行排序)。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间O(n),但桶排序并不是比较排序,他不受到O(nlogn)影响。

  • 总结:
    桶排序的平均时间复杂度为线性的O(N+C),其中C=N*(logN-logM)。如果相对于同样的N,桶数量M越大,其效率越高,最好时间复杂度达到O(N),桶排序的空间复杂度为O(N+M),如果输入数据非常庞大,而桶的数量也非常多,则空间代价无疑是昂贵的,桶排序是稳定的。
    五.插入排序

  • 基本原理
    插入排序是将一个数据插入到已经拍好序的有序数据中,从而得到一个新的,个数加一的有序数列,该算法适用于少量数据的排序,是稳定的排序算法。

  • 基本思想
    每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。

  • 分类:
    直接插入排序,二分插入排序(又称为折半插入排序),链表插入排序,希尔排序(又称缩小增量排序)。

  • 直接插入排序
    直接插入排序是一种简单的插入排序,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插完为止,得到一个新的有序序列。

  • 折半插入排序
    (1)计算 0 ~ i-1 的中间点,用 i 索引处的元素与中间值进行比较,如果 i 索引处的元素大,说明要插入的这个元素应该在中间值和刚加入i索引之间,反之,就是在刚开始的位置 到中间值的位置,这样很简单的完成了折半;
    (2)在相应的半个范围里面找插入的位置时,不断的用(1)步骤缩小范围,不停的折半,范围依次缩小为 1/2 1/4 1/8 …….快速的确定出第 i 个元素要插在什么地方;
    (3)确定位置之后,将整个序列后移,并将元素插入到相应位置。

  • 希尔排序法
    希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。
    各组内的排序通常采用直接插入法。由于开始时s的取值较大,每组内记录数较少,所以排序比较快。随着不断增大,每组内的记录数逐步增多,但由于已经按排好序,因此排序速度也比较快。
点赞