排序算法总结-python实现

最近在复习软考,把看到的排序算法整理了一下,之所以用python写,是因为python写起来简单....好吧,后来写的时候发现有些地方用C写还方便些。python虽然简洁,但用起来效率感觉还是有些低,不过这不是重点啦。。。

1.代码与说明

# -*- coding: utf-8 -*-

def bubbleSort(Data):
    '''冒泡排序: 时间复杂度最好O(n),平均O(n*n),最坏O(n*n),辅助空间 O(1),算法稳定
       n个数,每次从第一个数开始和相邻的数比较,将大的冒泡到后面去。第一趟将最大的冒泡到最后,
       然后第二次只需比较0~n-1,将其中最大的冒泡到n-1,依次下去...总共进行n-1趟排序即可
    '''
    if Data:
        for i in range(len(Data)):
            for j in range(len(Data)-i-1):
                if Data[j]>Data[j+1]:
                    Data[j],Data[j+1]=Data[j+1],Data[j]
    return Data

def quickSort(Data,low,high):
    '''快速排序:O(n*logn),O(n*logn),O(n*n),O(n*logn),不稳定
        冒泡的改进,被认为是当前最优秀的内部排序算法(当然这也不是绝对的,还要看具体情况)。实现基于分治法:分解-解决-合并。
        基本思想:
        1.从数列中取出一个基数,
        2.将数列中比他大的放在右边,小的在左边。
        3.两边区间重复2,直到各区间只有一个数。
        整个算法中的基数就是个坑,跳来跳去,总之比他小始终放一边,大的放另一边就行
        参考:http://blog.csdn.net/morewindows/article/details/6684558
    '''
    if low < high:
        left,right,base=low,high,Data[low]
        while left <right:
            #从后往前找比base小的数
            while left <right and Data[right] >=base:
                right-=1
            if left < right:
                Data[left]=Data[right]
                #left+=1 这里直接+1更快,因为Data[left]必然小于base,下次循环不用算
            #从前往后找比base大的数
            while left <right and Data[left] < base:
                left+=1
            if left <right:
                Data[right]=Data[left]
                #right-=1
        #left=right时一趟循环终止,base填回坑里去
        Data[left]=base             
        quickSort(Data,low,left-1)  #递归左边
        quickSort(Data,left+1,high) #递归右边
        
def insertSort(Data):
    '''插入排序: 时间复杂度最好O(n),平均O(n*n),最坏O(n*n),辅助空间 O(1),算法稳定
        如果Data不为空则开始比较。Data[0]~Data[j]是排好的序列L1,key是未排待插入数据
        如果key小于L1的最大值则将进行插入操作,while循环找到比key小的index并将key插入
        在index后面。while循环用来寻找插入位置并将比key大的数后移,如果key本身比L1的
        最大值还大则无需插入,直接for循环比较下一个
    '''
    if Data:
        for i in range(1,len(Data)):
            key,j = Data[i],i-1
            while j>=0 and Data[j] > key:
                Data[j+1]=Data[j]
                j-=1
            Data[j+1]=key
    return Data

def selectSort(Data):
    '''选择排序: 时间复杂度最好O(n*n),平均O(n*n),最坏O(n*n),辅助空间 O(1),算法不稳定
        n个数,每一趟从待排序列L2中选择最大(或最小)数顺序放在已排好序列L1后面(或前面)
        总共经过n-1趟可排好,与插入排序相比,都是将数据分为已排和未排序列并将未排元素整理
        到已排序列中,不同的是插入排序在未排序列中按序整理,选排则是按大小选择整理。
    '''
    if Data:
        for i in range(len(Data)-1):
            minnum=i
            for j in range(i+1,len(Data)):#在L2中寻找最小值
                if Data[j]<Data[minnum]:
                    minnum=j
            if minnum != i:#如果找到直接交换,插入在L1后面
                Data[i],Data[minnum]=Data[minnum],Data[i]
    return Data
                    
def shellSort(Data):
    '''希尔排序: 时间复杂度最好未知,平均O(pow(n,1.25),最坏未知,辅助空间 O(1),不稳定
        插入排序的改进,将数据分组,每组m个(m叫步长)每次对每组的第i个元素排序,
        然后再分组,再排序,直到步长为1.至于分组的方法需要理论推导,此处每次步长都取n/2减半
        更好的步长选择方法见wiki:http://zh.wikipedia.org/wiki/希尔排序
        其他实现方法:http://blog.csdn.net/morewindows/article/details/6668714
    '''
    n=len(Data)
    if  n > 1:
        gap=n/2 
        while gap > 0:   
            for i in range(gap):#按步长插入排序
                for j in range(i+gap,n,gap):
                    if Data[j] < Data[j-gap]:
                        key = Data[j]
                        k=j-gap
                        while k >=0 and Data[k] > key:
                            Data[k+gap]=Data[k]
                            k-=gap
                        Data[k+gap]=key
            gap/=2
    return Data
                    
        
if __name__ =="__main__":
    Data=[3,5,1,56,3,7,34,21,8]
    print Data
    #insertSort(Data)
    #bubbleSort(Data)
    #selectSort(Data)
    #shellSort(Data)
    quickSort(Data,0,len(Data)-1)
    print Data 
            
            
            
            

2.python内置排序

实际上python列表内置了排序算法。sort和sorted。

3.瞎扯

1.内部排序是指待排序列完全存放在内存中进行的排序,适合不太大的序列。包括

插入排序(直接插入排序)

快速排序

选择排序(简单选择排序)

冒泡排序

希尔排序

堆排序

归并排序

2.外部排序指能处理大量数据的排序算法,数据不能一次装入内存,通常要借助外存储器。常采用排序-归并策略,比如外归并排序。详情参考wiki:http://zh.wikipedia.org/wiki/外排序 

3.python中没有自增和自减运算,这在写代码的时候异常不方便。当然咯,这也与python的设计目标有关系。python的设计哲学是优雅,明确、简单。他们可能认为这样不太优雅,不利于代码的可读性,譬如js也不推荐使用++和--。另外一个原因,那就是python不提供像C那样直接操作内存的功能。当执行a+=1时,C会直接修改a在内存中的值,而python则会在内存中新建一个整型变量(也不完全这样,有些小数据python会复用,见下面第4点),然后让a指向它。所以如果要执行a++,C语言中a还是那个a,而python中的a已经不是原来的a了,这样就乱套了!

说到这里,再扯一下python中的可变对象和不可变对象。python中所有对象都是值的引用。不可变指的是值不可变。要修改变量的值就要在内存中新建一个值并让变量指向它,原来的如果不用就会被GC回收。可变对象不需要在其他地方申请内存,直接在自己后面申请/释放空间即可,原地址不变。

4.对于小数值整型对象,比如1~100,python虚拟机在启动时会先在内存中生成好,放在缓冲区以便于快速调用。看下面的例子:

开始a,b为100,a is b是True,说明a,b指向内存中同一个对象,后面值变大了,a=100000时python会在内存中新建一个对象,b=100000也会新建一个对象,所以a,b指向不同对象,故为False。id(a)是查看a的地址。

5.有关for循环,实质上是一个遍历,for i in range(0,10),range()会生成一个0到9的list让i遍历。这样就有一个缺陷:i在循环前每一步的值是确定的,不能动态改变。而在C语言中,for(int i=n/2,i>0,i=i/2),i是随着循环每次都会改变的。不过事实上,i的值在循环前也是可以推算出来的,因此肯定是可以用python的for循环代替C的for(int i=n/2,i>0,i=i/2),只不过LZ还没想到,谁知道还麻烦说一声,哈哈!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《算法图解-python.pdf》是一本介绍算法和使用Python语言实现算法的书籍。该书的目的是帮助读者了解算法的基本概念和原理,并通过Python编程实践来加深理解。 这本书以图解的方式呈现算法的思想和应用,使复杂的算法问题变得直观易懂。读者可以通过阅读该书,学习到各种常见的算法设计和解决思路,如排序算法、搜索算法、图算法等。同时,该书也会介绍一些高级算法,如动态规划、贪婪算法等,以及如何通过Python语言实现这些算法。 《算法图解-python.pdf》的内容结构清晰,通俗易懂。每个算法都有详细的解释和示例代码,读者可以通过实际编程来加深对算法的理解。此外,书中还包含了一些挑战性的练习题,供读者进一步巩固所学的知识。 通过阅读《算法图解-python.pdf》,读者不仅可以学习到算法的基本知识,还可以了解到如何运用Python语言实现这些算法。这对于刚开始学习算法和Python编程的读者来说是非常有帮助的。无论是计算机科学专业的学生,还是对算法感兴趣的爱好者,都可以从这本书中受益匪浅。 总之,《算法图解-python.pdf》是一本很好的算法入门书籍,以图解和Python编程为特色,适合各类读者学习和参考。通过阅读和实践,读者可以提高算法设计和编程实现的能力,为解决实际问题提供有效的思路和方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值