八大经典排序算法——Python(PS:二分查找)

一、冒泡排序(交换排序)  

# BubbleSort - Using bubble sort method for a chaotic sequence in ascending order, request the first to come up to the minimum.

class Solution(object):
    def bubbleSort(self, nums):
        size = len(nums)
        for i in range(0, size - 1):
            j = size - 1
            while j > 0:
                if nums[j] < nums[j - 1]:
                    nums[j - 1], nums[j] = nums[j], nums[j - 1]
                j -= 1
        return nums

if __name__ == "__main__":
    s = Solution()
    print(s.bubbleSort(nums=[35, 80, 21, 54, 11, 45, 92, 39]))

二、选择排序  

# SelectionSort - Using the selection method for a chaotic sequence in ascending order.

def SelectSort(a):
    for i in range(0, len(a) - 1):    # 外层循环 找i次最小值
        min = i               # 此处记录最小值位置,不能改变数列中的数值
        for j in range(i + 1, len(a) - 1):    # 内层循环 找到最小值
            if a[j] < a[min]:
                min = j      # 变量 j 更新并记录最小值位置
        p = a[i]      # 变量 p 储存最小值(把第一个最小值放入的位置的那个原有值记录在temp里)
        a[i] = a[min]   # 将最小值覆盖到那个位置里
        a[min] = p    # 再把p里保存的最小值更新到未排数列的第一个
    return a

print(SelectSort(a=[35, 80, 21, 54, 11, 45, 92, 39]))

三、插入排序  

# InsertSort - Using insertion sort method for a chaotic sequence in ascending order.

class Solution(object):
    def insertionSort(self, nums):
        size = len(nums)
        for i in range(1, size):
            if nums[i] < nums[i - 1]:
                temp = nums[i]
                j = i        # 记下未排序第一个的位置
                while j > 0 and temp < nums[j - 1]:
                    nums[j] = nums[j - 1]
                    j -= 1
                nums[j] = temp   # 插入待排序的数字
        return nums

if __name__ == "__main__":
    s = Solution()
    print(s.insertionSort(nums=[35, 80, 21, 54, 11, 45, 92, 39]))

四、希尔排序——(插入排序的改进)

#!/usr/bin/env python
# coding:utf-8

def shellSort(nums):
    # 设定步长
    step = len(nums)/2
    while step > 0:
        for i in range(step, len(nums)):
            # 类似插入排序, 当前值与指定步长之前的值比较, 符合条件则交换位置
            while i >= step and nums[i-step] > nums[i]:
                nums[i], nums[i-step] = nums[i-step], nums[i]
                i -= step
        step = step/2
    return nums

if __name__ == '__main__':
    nums = [9,3,5,8,2,7,1]
    print shellSort(nums)

五、快速排序——(冒泡排序的改进)

    过程:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序(递归实现)。

一趟快速排序的算法是:

1)设置两个变量low、high,排序开始的时候:low=0,high=len(a)-1;

2)以第一个数组元素作为关键数据,赋值给key,即key=a[low];

3)从j开始向前搜索,即由后开始向前搜索(high--),找到第一个小于key的值a[high],将a[high]和a[low]互换;

4)从i开始向后搜索,即由前开始向后搜索(low++),找到第一个大于key的a[low],将a[low]和a[high]互换;

5)重复第3、4步,直到low=high;

       (3,4步中,没找到符合条件的值,即3中a[high]不小于key,4中a[low]不大于key的时候改变high、low的值,使得high=high-1,low=low+1,直至找到为止。找到符合条件的值,

进行交换的时候low, high指针位置不变。另外,low==high这一过程一定正好是low+或high-完成的时候,此时令循环结束)。

# QuickSort - Using quick sort method for a chaotic sequence in ascending order.


def partition(a, left, right):   # 定义分区函数,第一遍排序
    low = left
    high = right
    key = a[low]
    while low < high:
        while low < high and a[high] >= key:    # 因为基准 key 从左开始,所以第一遍从右开始遍历
            high -= 1
        a[low] = a[high]
        while low < high and a[low] <= key:
            low += 1
        a[high] = a[low]
        a[low] = key                       # 每一次循环结束记录一次基准 key 的位置,防止 key 值丢失
    return low

def QuickSort(a, left, right):            # 定义递归函数
    if left < right:                      # !!!判断条件很重要,很容易忽略
        p = partition(a, left, right)
        QuickSort(a, left, p - 1)
        QuickSort(a, p + 1, right)
    return a

a = [35, 80, 21, 54, 11, 45, 92, 39]
print(QuickSort(a, 0, len(a) - 1))

六、归并排序(递归)

def merge(left,right):  
    result=[]  
    i,j=0,0  
    while i<len(left) and j<len(right):  
        if left[i]<=right[j]:  
            result.append(left[i])  
            i+=1  
        else:  
            result.append(right[j])  
            j+=1  
    result+=left[i:]  
    result+=right[j:]  
    return result  

def mergesort(seq):  
    if len(seq)<=1:  
        return seq  
    mid=int(len(seq)/2)  
    left=mergesort(seq[:mid])  
    right=mergesort(seq[mid:])  
    return merge(left,right)

if __name__=='__main__':  
    seq=[4,5,7,9,7,5,1,0,7,-2,3,-99,6]  
    print(mergesort(seq))

七、堆排序—— (选择排序的改进)

#coding: utf-8 
#!/usr/bin/python   
import random
import math

#随机生成0~100之间的数值
def get_andomNumber(num):  
    lists=[]  
    i=0  
    while i<num:  
        lists.append(random.randint(0,100))  
        i+=1
    return lists


# 调整堆
def adjust_heap(lists, i, size):
    lchild = 2 * i + 1
    rchild = 2 * i + 2
    max = i
    if i < size / 2:
        if lchild < size and lists[lchild] > lists[max]:
            max = lchild
        if rchild < size and lists[rchild] > lists[max]:
            max = rchild
        if max != i:
            lists[max], lists[i] = lists[i], lists[max]
            adjust_heap(lists, max, size)

# 创建堆
def build_heap(lists, size):
    for i in range(0, (int(size/2)))[::-1]:
        adjust_heap(lists, i, size)

# 堆排序
def heap_sort(lists):
    size = len(lists)
    build_heap(lists, size)
    for i in range(0, size)[::-1]:
        lists[0], lists[i] = lists[i], lists[0]
        adjust_heap(lists, 0, i)
    return lists


a = get_andomNumber(10)
print("排序之前:%s" %a)

b = heap_sort(a)

print("排序之后:%s" %b)

八、桶排序(bucket sort & bin sort)

# BucketSort - Using the Bucket Sort method for a chaotic sequence in ascending order.

def BucketSort(a):
    b = [0] * max(a)    #预先设定的列表,全部置零
    result = []
    for num in a:       #遍历成绩,相应得分位置+1
        b[num - 1] += 1      #a的值成为b的索引,此时标记b中不为空的位置
    for i in range(0, len(b)):   #遍历生成的列表
        for j in range(0, b[i]):
            result.append(i + 1)
    return result

print(BucketSort(a=[35, 80, 21, 54, 11, 45, 92, 39]))

PS:

排序算法稳定性:

        假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。

        稳定的排序算法:基数排序、冒泡排序、直接插入排序、折半插入排序、归并排序

        不稳定的排序算法:堆排序、快速排序、希尔排序、直接选择排序

 排序算法复杂度:

                                          

PS——二分查找(binary_search)

def binary_search(a, key):
    if not a:
        return 0
    time = 0
    low = 0
    high = len(a) - 1
    while low <= high:
        time += 1
        mid = int((low + high) / 2)
        if a[mid] == key:
            print("times: %s" % time)
            return mid
        elif a[mid] > key:
            high = mid - 1
        else:
            low = mid + 1
    return False

if __name__ == '__main__':
    LIST = [1, 5, 7, 8, 22, 54, 99, 123, 200, 222, 444]
    result = binary_search(LIST, 200)
    print(result)
原文地址:https://www.cnblogs.com/llw1121/p/6838357.html