常用排序算法总结

这种东西,总是忘,还是不熟,也不关心,太笨了,随便总结一下,可能写的还不对,有错请指出

二分查找算法

二分查找又称折半查找
仅适用于已经排好序的顺序表
思路:
1.给定值K
2.与列表中间位置元素的值做比较
3.若相等,则返回该元素的存储位置
若不等,则所查找的元素只能在中间数据之外的前半部分或后半部分,然后缩小范围继续进行同样的查找
4. GOTO 2, 如此反复,直到找到为止,或者找不到返回None

因为二分查找需要方便地定位查找区域,所以适合二分查找的存储结构必须具有随机存储的特性,因此,该查找方法仅适合于线性表的顺序存储结构,不适合链式存储结构,且要求元素按关键字有序排列。

随机存储是?
顺序存储结构和链式存储结构的区别是?

时间复杂度:O(log2N)

优点:效率高
缺点:
1、要将表按关键字排序,排序本身是一种很费时的操作,即使采用高效率的排序也要使用O(nlgn)的时间
2、只适用于顺序存储结构,为保持表的有序性,在顺序结构里插入和删除都必须移动大量的节点。因此,二分查找特别适用于那种一经建立就很少改动、而又经常需要查找的线性表。对那些查找少而又经常需要改动的线性表,可采用链表作存储结构,进行顺序查找,链表上无法实现二分查找。

http://www.cnblogs.com/vincently/p/4290030.html

1.递归

def binarySearch(candidate, sorted_list, left_index, right_index):
    if left_index >= right_index:
        return None
    mid_index = left_index + ( right_index - left_index ) / 2
    mid_value = sorted_list[mid_index]
    if mid_value == candidate:
        return mid_index
    elif candidate < mid_value:
        return binarySearch(candidate, sorted_list, left_index, mid_index)
    elif candidate > mid_value:
        return binarySearch(candidate, sorted_list, mid_index + 1, right_index)

2.循环,推荐这个

def binarySearchV2(candidate, sorted_list):
    left_index = 0
    right_index = len(sorted_list) - 1
    while left_index <= right_index:
        mid_index = left_index + (right_index - left_index) / 2
        mid_value = sorted_list[mid_index]
        if mid_value == candidate:
            return mid_index
        elif mid_value > candidate:
            right_index = mid_index - 1
        elif mid_value < candidate:
            left_index = mid_index + 1
    return None

测试

l = range(30)
print binarySearch(14.5, l, 0, len(l) - 1)
print binarySearchV2(14.5, l)

结果

None
None

冒泡排序

冒泡排序算法的运作如下:(从后往前,下沉)
1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

注意是相邻元素进行大小比较进行移位,不要写成拿头元素和所有元素进行比较!

时间复杂度:
最好的情况:O(n)
最坏的情况:O(n**2)
平均:O(n**2)

1.基础版本

def bubbleSort(mylist):
    size = len(mylist)
    n = 0
    for i in range(size - 1):
        for j in range(size - 1 - i):
            n += 1
            if mylist[j] > mylist[j+1]:
                mylist[j], mylist[j+1] = mylist[j+1], mylist[j]
    print "v1:" , n
    return mylist

2.优化1,记录每轮的交换次数,如果为0则不需要再检查了,直接退出

def bubbleSortV2(mylist):
    size = len(mylist)
    n = 0
    for i in range(size - 1):
        count = 0
        for j in range(size - 1 - i):
            n += 1
            if mylist[j] > mylist[j+1]:
                mylist[j], mylist[j+1] = mylist[j+1], mylist[j]
                count += 1
        if count == 0:
            break
    print "v2:" , n
    return mylist

3.优化2,记录每轮最后一次变更的位置,下次内层循环到这个位置结束即可

def bubbleSortV3(mylist):
    size = len(mylist)
    n = 0
    last_change = size - 1
    for i in range(size - 1):
        change = 0
        for j in range(last_change):
            n += 1
            if mylist[j] > mylist[j+1]:
                change = j
                mylist[j], mylist[j+1] = mylist[j+1], mylist[j]
        last_change = change
    print "v3:" , n
    return mylist

测试

mylist = [12123,3232,3,65,321,542,453,2,5,53,2,3,1,453,1,32,5,43,1,3,542,213,312]
print bubbleSort(mylist)
print bubbleSortV2(mylist)
print bubbleSortV3(mylist)

结果

v1: 253
[1, 1, 1, 2, 2, 3, 3, 3, 5, 5, 32, 43, 53, 65, 213, 312, 321, 453, 453, 542, 542, 3232, 12123]
v2: 22
[1, 1, 1, 2, 2, 3, 3, 3, 5, 5, 32, 43, 53, 65, 213, 312, 321, 453, 453, 542, 542, 3232, 12123]
v3: 22
[1, 1, 1, 2, 2, 3, 3, 3, 5, 5, 32, 43, 53, 65, 213, 312, 321, 453, 453, 542, 542, 3232, 12123]

https://baike.baidu.com/item/%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F/4602306?fr=aladdin

http://blog.csdn.net/bitboss/article/details/51559034

选择排序算法

选择排序的基本思想是:每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。基于此思想的算法主要有简单选择排序、树型选择排序和堆排序。

简单选择排序的基本思想:第1趟,在待排序记录r[1]~r[n]中选出最小的记录,将它与r[1]交换;第2趟,在待排序记录r[2]~r[n]中选出最小的记录,将它与r[2]交换;以此类推,第i趟在待排序记录r[i]~r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。

以下为简单选择排序的存储状态,其中大括号内为无序区,大括号外为有序序列:

初始序列:{49 27 65 97 76 12 38}

  第1趟:12与49交换:12{27 65 97 76 49 38}

  第2趟:27不动 :12 27{65 97 76 49 38}

  第3趟:65与38交换:12 27 38{97 76 49 65}

  第4趟:97与49交换:12 27 38 49{76 97 65}

  第5趟:76与65交换:12 27 38 49 65{97 76}

  第6趟:97与76交换:12 27 38 49 65 76 97 完成

1.代码

def selectSort(mylist):
    for i in range(len(mylist)):
        min_value = mylist[i]
        min_index = i
        for j in range(i + 1, len(mylist)):
            if mylist[j] < min_value:
                min_index = j
                min_value = mylist[j]
        if min_index > i:
            mylist[i], mylist[min_index] = mylist[min_index], mylist[i]
    return mylist

测试

mylist = [12123,3232,3,65,321,542,453,2,5,53,2,3,1,453,1,32,5,43,1,3,542,213,312]
print selectSort(mylist)

插入排序算法

默认序列中的第0个元素是有序的(因为只有一个元素a[0]嘛,自然是有序的);

从下标为1(下标从0开始)的元素开始,取当前下标i位置处的元素a[i]保存到一个临时变量waitInsert里;

对前半部分有序序列的循环遍历,并与waitInsert比较,直到遇到一个比waitInsert大的元素(这里默认是从小到大排序),此时的下标为j,那么现在只要对a[j+1]进行赋值waitInsert即可;

将待插入元素的下标 i 向后推移一个位置;

重复进行第2步到第4步,直到乱序序列中的元素被全部插入到有序序列中;

经过以上5个步骤之后,整体序列必然有序,排序完成。

http://blog.csdn.net/lemon_tree12138/article/details/50968422

1.代码

def insertSort(mylist):
    for i in range(len(mylist) - 1):
        candidate = mylist[i + 1]
        for j in range(0, i + 1):
            if candidate < mylist[j]:
                mylist[j + 1:i + 2] = mylist[j:i + 1]
                mylist[j] = candidate
                break
    return mylist

测试

mylist = [12123,3232,3,65,321,542,453,2,5,53,2,3,1,453,1,32,5,43,1,3,542,213,312]
print insertSort(mylist)

归并排序

http://blog.csdn.net/morewindows/article/details/6678165/
1.代码

def mergeSort(mylist):
    length = len(mylist)
    if length < 2:
        return mylist
    left_list = mergeSort(mylist[0:length/2])
    right_list = mergeSort(mylist[length/2:])
    new_list = []
    n, m = 0, 0
    #合并两个有序列表
    #公共长度
    while n < len(left_list) and m < len(right_list):
        left = left_list[n]
        right = right_list[m]
        if left < right:
            new_list.append(left)
            n += 1
        else:
            new_list.append(right)
            m += 1
    #补漏
    while n < len(left_list):
        new_list.append(left_list[n])
        n += 1
    while m < len(right_list):
        new_list.append(right_list[m])
        m += 1
    return new_list

测试

mylist = [12123,3232,3,65,321,542,453,2,5,53,2,3,1,453,1,32,5,43,1,3,542,213,312]
print mergeSort(mylist)

快速排序

http://blog.csdn.net/morewindows/article/details/6684558

1.这个感觉好像不对诶,不过是这么个思想

def quickSort(mylist):
    if len(mylist) < 2:
        return mylist
    left_list = []
    right_list = []
    first_value = mylist[0]
    for i in mylist[1:]:
        if i < first_value:
            left_list.append(i)
        else:
            right_list.append(i)
    return quickSort(left_list) + [first_value] + quickSort(right_list)

2.标准答案??

def quickSortV2(mylist, low, high):
    if low >= high:
        return mylist
    i = low 
    j = high
    mid = mylist[i]
    while i < j:
        #从后向前找比mid小的
        while i < j and mylist[j] >= mid:
            j = j-1                                                             
        mylist[i] = mylist[j]
        #从前向后找比mid大的
        while i < j and mylist[i] < mid:    
            i = i+1 
        mylist[j] = mylist[i]
    mylist[i] = mid 
    quickSortV2(mylist, low, i-1)
    quickSortV2(mylist, i+1, high)
    return mylist

测试

mylist = [12123,3232,3,65,321,542,453,2,5,53,2,3,1,453,1,32,5,43,1,3,542,213,312]
print quickSort(mylist)
print quickSortV2(mylist, 0, len(mylist)-1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值