Python算法之排序

     排序是数据结构这门课里的重点内容。主要有:插入排序、希尔排序、选择排序、冒泡排序、快速排序、归并排序、堆排序、基数排序、桶排序等等。其中选择、冒泡等算法都很简单,没什么细节就不多说了。

    其实我们在学算法的时候不仅要学会它的实现细节,更重要的是它的思想和特点,会把它的思想应用于其他的具体问题中,同时也会从具体问题中归纳出某个算法的模型。

插入排序

    插入排序是我们很熟悉的排序算法,希尔排序也是其中一种,但我想大家平时用的不多,它有两个特点:

一是将一个元素插入已排好序的序列中;

二是实现方法用数组的倒插法。

#InsertSort
def InsertSort(seq):  
    length = len(seq)  
    for i in range(1,length):  
        temp = seq[i]  
        for j in range(i-1, -1, -1):  
            if temp < seq[j]:  
                seq[j+1]=seq[j]         
            else:  
                j+=1  
                break  
        if seq[j] is not temp:  
            seq[j]=temp  
              


快速排序

    快排被认为是速度最快的排序算法,它的特点是把所有的元素和一个选定的基准元素比较,大于基准元素的放后面,小的放前面,每次循环确定一个基准元素的位置。基准元素选的好,效率会大大提高。它的特点是:

一它的实现是一种二叉树的结构;

二每次循环确定一个元素位置。

 

#QuickSort
def QuickSort(seq, low, high):#[low, high]
    if low >= high:
        return 
    start = low
    end = high
    temp = seq[low]
    if low < high:
        while low < high:
            while low < high and seq[high] >= temp:
                high = high - 1
            if low < high:
                seq[low] = seq[high]
            while low < high and seq[low] <= temp:
                low = low + 1
            if low < high:
                seq[high] = seq[low]
        seq[low] = temp
        QuickSort(seq, start, low-1)
        QuickSort(seq, low+1, end)


堆排序

    堆排序是s[i] >=s [2*i] and s[i] >= s[2*i+1] ,堆排序是二叉树的结构,堆排序每次只能确定根节点为最小值或者最大值,其他节点顺序未定。典型应用求topK的数。特点:

一每次确定一个最值,适用于topK;

二是二叉树结构,速度为k*logn

#HeapSort,small root heap
def HeapSort(seq):
    
    def SmallRootHeap(seq):
        _len = len(seq)
        fromIndex = _len//2
        for i in range(fromIndex, 0, -1):
            k = 2*i-1
            j = i-1
            while k <= _len-1:
                if k+1 <= _len-1 and seq[k] > seq[k+1]:
                        k = k+1
                if seq[j] > seq[k]:
                    seq[j], seq[k] = seq[k], seq[j]
                    j = k
                    k = 2*j
                else:
                    break

    def RemoveRoot(seq):
        _len = len(seq)
        val = seq[0]
        seq[0] = seq[_len-1]
        seq.pop()
        SmallRootHeap(seq)
        return val

    _seq = []
    _seq.extend(seq)
    SmallRootHeap(_seq)
    i = 0
    while i != len(seq):
        seq[i] = RemoveRoot(_seq)#
        i = i+1
  


归并排序

    归并排序是一种贪心算法,可以将复杂的问题化简为具有相同特征的子问题。这种结构模型是:

function(root):

    if some condition:  

        function(lchild)

        function(rchild)

        do something

以上可以看出这种结构关键在于do something,其他的都是递归调用function

#MergeSort
def MergeSort(seq):

    def Merge(seq, low, mid, high):#[low, high]
        _seq = []
        k = low
        j = mid+1
        i = 0
        while k <= mid and j <= high:
            if seq[k] <= seq[j]:
                _seq.append(seq[k])
                k = k+1
            else:
                _seq.append(seq[j])
                j = j+1
            i = i+1
        while k <= mid:
            _seq.append(seq[k])
            i = i+1
            k = k+1
        while j <= high:
            _seq.append(seq[j])
            i = i+1
            j = j+1
        for i in range(len(_seq)):
            seq[low+i] = _seq[i]
            

    def Sort(seq, low, high):
        
        if low < high:
            mid = (high+low)//2
            Sort(seq, low, mid)
            Sort(seq, mid+1, high)
            Merge(seq, low, mid, high)       
          
    Sort(seq, 0, len(seq)-1)
    


桶排序

    桶排序类似于hash表,在一定范围内的大量元素排序有很高的效率,特点是分治。如1亿个在1000以内的整数排序。可以建立1001个桶,然后遍历1亿个元素,再对1001个桶内的元素排序(可以用快排等等)。

#BucketSort
def BucketSort(seq, minVal, maxVal, num = 10):
    bucketNum = (maxVal-minVal)//num +1
    bucket = [[] for i in range(bucketNum)]
    #step one
    for i in range(len(seq)):#put seq[i] into the correct bucket
        bucket[(seq[i]-minVal)//num].append(seq[i])
    #step two
    seq.clear()
    for i in range(len(bucket)):#quick sort of the i-th bucket's elements
        QuickSort(bucket[i], 0, len(bucket[i])-1)
        seq.extend(bucket[i])
      


基数排序

    基数排序也用到了桶的思想,给定d组关键字先按关键字k1排序分组入桶,同一组中记录关键码k1相等,然后将各桶依次连接即合并各分组,再按k2排序分组入桶,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。

#RadixSort
def RadixSort(seq, radix):
    bucketNum = 10
    for k in range(radix):
        bucket = [[] for i in range(bucketNum)]
        for i in range(len(seq)):
            if k == 0:
                bucket[seq[i]%bucketNum].append(seq[i])
            else:
                bucket[(seq[i]//(bucketNum*k))%bucketNum].append(seq[i])
        seq.clear()
        for i in range(bucketNum):
            QuickSort(bucket[i], 0, len(bucket[i])-1)
            seq.extend(bucket[i])
        bucket.clear()  


测试代码

#Date    :2013-9-23
#Author  :DVD0423
#Function:Sort
            
def do_test():
    seq = [8,7,6,5,4,3,112,113,116,115,118,34,38,37,35,39,99,90,98,95]  
    print('Please input the sequence:')  
    print(seq)
    print('After the Sort:')
    RadixSort(seq, 3)
    print(seq)  
  
if __name__ == '__main__':  
    do_test()  


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值