Python基于比较的排序

排序是算法学习中最基本的问题。

1.平均时间复杂度均为O(N2)的排序

1.1 插入排序

插入排序对少量元素的排序非常有效。工作机制就像打牌一样,为了将牌插入到已排好序的牌中,需要将牌与手中的牌从右向左进行比较。

def insertionSort(alist):
    n=len(alist)
    for i in xrange(1,n):
        key=alist[i]
        j=i-1
        while j>=0 and alist[j]>=key:
            alist[j+1]=alist[j]
            j-=1
        alist[j+1]=key
    return alist

1.2 冒泡排序

冒泡排序通过重复的交换相邻的两个反序元素来将最大元素置于数组末尾。

def bubbleSort(alist):
    n=len(alist)
    for i in xrange(n-2,0,-1):
        for j in xrange(i+1):
            if alist[j]>alist[j+1]:
                alist[j],alist[j+1]=alist[j+1],alist[j]
    return alist

1.3 选择排序

首先找出序列中的最大元素,与最后一个元素交换位置,然后找出次大元素,与倒数第二个元素交换位置,以此类推。

def selectionSort(alist):
    n=len(alist)
    for i in xrange(n-1,0,-1):
        posofMax=0
        for j in xrange(1,i+1):
            if alist[j]>=alist[posofMax]:
                posofMax=j
        a[posofMax],a[i]=a[i],a[posofMax]
    return alist

1.4 希尔排序

SHELL排序通过比较相距一定间隔的元素来工作。各趟排序随着算法的进行而减小,直到只比较相邻元素的最后一趟为止。

使用希尔增量(ht=N/2,hk=hk+1/2)时希尔排序的最坏运行时间为Θ(N2),使用Hibbard增量(1,3,7,...,2k-1)的希尔排序的最坏运行时间为Θ(N3/2)。

def shellSort(alist):
    n=len(alist)/2
    while n>0:
        gapinsertionSort(alist,n)
        n=n/2
    return alist
def gapinsertionSort(alist,gap):
    n=len(alist)
    for i in xrange(gap):
        for j in xrange(i+gap,n,gap):
            key=alist[j]
            x=j-gap
            while x>=0 and a[x]>=key:
                a[x+gap]=a[x]
                x-=gap
            a[x+gap]=key

2.平均时间复杂度均为O(NlogN)的排序

2.1 合并排序

合并排序基本的操作是合并两个已排序的表。它是递归算法的一个很好的实例。合并排序需要花费将数据拷贝到临时数组再拷贝回来这样一些附加的工作。

def mergeSort(alist):
    if len(alist)>1:
        q=len(alist)/2
        left=alist[:q]
        right=alist[q:]
        mergeSort(left)
        mergeSort(right)
        i=0
        j=0
        k=0
        while i<len(left) and j<len(right):
            if left[i]<right[j]:
                alist[k]=left[i]
                i+=1
            else:
                alist[k]=right[j]
                j+=1
            k+=1
        while i<len(left):
            alist[k]=left[i]
            i+=1
            k+=1
        while j<len(right):
            alist[k]=right[j]
            j+=1
            k+=1
    return alist

  合并排序的另一种非递归实现

def mergeSort(alist):
    n=len(alist)
    i=1
    while i<n:
        start=0
        t=start+i-1
        end=start+2*i-1
        while end<n:
            merge(alist,start,t,end)
            start=end+1
            t=start+i-1
            end=start+2*i-1
        if t<n-1:
            merge(alist,start,t,n-1)
        i=i*2
    return alist     

def merge(alist,start,t,end):
    left=alist[start:t+1]
    right=alist[t+1:end+1]
    i=0
    j=0
    k=start
    while i<len(left) and j<len(right):
        if left[i]<right[j]:
            alist[k]=left[i]
            i+=1
        else:
            alist[k]=right[j]
            j+=1
        k+=1
    while i<len(left):
        alist[k]=left[i]
        i+=1
        k+=1
    while j<len(right):
        alist[k]=right[j]
        j+=1
        k+=1

 2.2 堆排序

建立最大堆后将最大元素与堆最后的单元互换,堆大小缩小一,然后执行根的下滤操作找出第二大的元素。

def heapSort(alist):
    n=len(alist)
    buildMaxHeap(alist)
    for i in xrange(n-1,0,-1):
        alist[i],alist[0]=alist[0],alist[i]
        perDown(alist,0,i-1)
    return alist
def buildMaxHeap(alist):
    n=len(alist)
    for i in xrange(n/2-1,-1,-1):
        perDown(alist,i,n-1)
def perDown(alist,start,end):
    left=start*2+1
    right=left+1
    large=start
    if left<=end and alist[left]>alist[start]:
        large=left
    if right<=end and alist[right]>alist[large]:
        large=right
    if large!=start:
        alist[large],alist[start]=alist[start],alist[large]
        perDown(alist,large,end)

2.3 快速排序

快速排序是在实践中最快的已知排序算法,像合并排序一样也是一种分治的递归算法。

1.如果元素个数为0或1,则返回。

2.取数组中任一元素v,称之为枢纽元。

3.将数组分为2个不相交的部分,一部分元素小于v,另一部分大于v。

4.对两部分分别递归的使用快速排序。

下图取第一个元素为枢纽元v,leftmark从第二个元素开始,rightmark从倒数第一个元素开始。

当leftmark在rightmark左边时,将leftmark右移,移过小于v的元素,将rightmark左移,移过大于v的元素,当leftmark,rightmark停止时,

将leftmark和rightmark元素互换,直到leftmark到rightmark右边为止。

def quickSort(alist):
    n=len(alist)
    _quickSort(alist,0,n-1)
    return alist
def _quickSort(alist,s,e):
    if s<e:
        v=alist[s]
        i=s+1
        j=e
        while True:
            while i<=j and alist[i]<=v:
                i+=1
            while j>=i and alist[j]>v:
                j-=1
            if i<j:
                alist[i],alist[j]=alist[j],alist[i]
            else:
                break
        alist[s],alist[j]=alist[j],alist[s]
        _quickSort(alist,s,j-1)
        _quickSort(alist,i,e)

Python基于比较的排序

时间: 2024-11-29 07:32:11

Python基于比较的排序的相关文章

Python 基于字典里的指定key进行排序

对下面列表基于age进行排序items = [{'age': 28, 'name': 'Tom'}, {'age': 25, 'name': 'Jack'}, {'age': 18, 'name': 'Alex'}] 方法一:sorted(items,key=lambda item: item['age']) 方法二:from operator import itemgettersorted(items,key=itemgetter('age')) 备注:以上两个方法同样适用于 max().mi

Python list列表的排序

当我们从数据库中获取一写数据后,一般对于列表的排序是经常会遇到的问题,今天总结一下python对于列表list排序的常用方法: 第一种:内建函数sort() 这个应该是我们使用最多的也是最简单的排序函数了,可以直接对列表进行排序 用法: list.sort(func=None, key=None, reverse=False(or True)) 对于reverse这个bool类型参数,当reverse=False时:为正向排序:当reverse=True时:为方向排序.当然默认为False. 执

漫谈python中的搜索/排序

在数据结构那一块,搜索有顺序查找/二分查找/hash查找,而排序有冒泡排序/选择排序/插入排序/归并排序/快速排序.如果遇到数据量和数组排列方式不同,基于时间复杂度的考虑,可能需要用到混合算法.如果用C语言自己写,是一个很头疼且门槛很高的过程,python却用很简单的方式,让这类算法人人可用. 排序的话,python采用了一个sort函数,这个函数用的是一个适应性强的.稳定的.自然的归并算法,名为timsort.而查找,用字典,时间复杂度可以降低到O(1),而字典的实现方式,则是利用了hash函

python 十大经典排序算法

python 十大经典排序算法 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.常见的内部排序算法有:插入排序.希尔排序.选择排序.冒泡排序.归并排序.快速排序.堆排序.基数排序等.用一张图概括: 关于时间复杂度: 平方阶 (O(n2)) 排序 各类简单排序:直接插入.直接选择和冒泡排序. 线性对数阶 (O(nlog2n)) 排序 快速排序.堆排序和归并排序. O(n1+§)) 排序,§

非基于比较的排序算法之一:计数排序

计数排序(Counting sort)是一种稳定的排序算法.计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值小于等于i的元素的个数.然后根据数组C来将A中的元素排到正确的位置. 限制:所有值得取值范围不能太大,并且需要知道确切的取值范围.本算法需要的辅助空间要求较高. 当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 Θ(n + k).计数排序不是比较排序,排序的速度快于任何比较排序算法. 现在给出C#实现的计数排序(counting sort) public vo

php基于左右值排序的无限分类算法

PHP无限分类[左右值]算法 <?php /** * 基于左右值排序的无限分类算法 * 数据库结果为 CREATE TABLE om_catagory ( CatagoryID int(10) unsigned NOT NULL auto_increment, Name varchar(50) default '', Lft int(10) unsigned NOT NULL default '0', Rgt int(10) unsigned NOT NULL default '0', PRIM

python实现分治法排序

# -*- coding: utf-8 -*- """ Created on Wed May 14 16:14:50 2014 @author: lifeix """ def merge(a, start, mid, end): if start == end: return a if mid == 0: return a temp1 = a[start:mid] m1 = len(temp1)/2 print temp1,'----',m1 n

数据库结果为 基于左右值排序的无限分类算法

<?php /**     * 基于左右值排序的无限分类算法     * 数据库结果为 CREATE TABLE om_catagory (      CatagoryID int(10) unsigned NOT NULL auto_increment,     Name varchar(50) default '',      Lft int(10) unsigned NOT NULL default '0',      Rgt int(10) unsigned NOT NULL defau

python基于mysql实现的简单队列以及跨进程锁

在我们做多进程应用开发的过程中,难免会遇到多个进程访问同一个资源(临界资源)的状况,必须通过加一个全局性的锁,来实现资源的同步访问(同一时间只能有一个进程访问资源). 举个例子: 假设我们用mysql来实现一个任务队列,实现的过程如下: 1. 在Mysql中创建Job表,用于储存队列任务,如下: create table jobs( id auto_increment not null primary key, message text not null, job_status not null