基础算法

 

- 测试执行时间的装饰器:

import time


def cal_time(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        result = func(*args, **kwargs)
        t2 = time.time()
        print("%s running time: %s secs." % (func.__name__, t2-t1))
        return result
    return wrapper
cal_time

 

 

 

冒泡排序

- 基础版:

import random
from timewrap import cal_time

@cal_time
def bubble_sort(li):
    for i in range(len(li)-1): # i表示第i趟
        for j in range(len(li)-i-1): # j表示箭头位置
            if li[j] > li[j+1]:
                li[j], li[j+1] = li[j+1], li[j]


li = list(range(1000))
random.shuffle(li)
bubble_sort(li)
print(li)

 

- 优化版:

import random
from timewrap import cal_time


@cal_time
def bubble_sort_2(li):
    for i in range(len(li)-1): # i表示第i趟
        exchange = False
        for j in range(len(li)-i-1): # j表示箭头位置
            if li[j] > li[j+1]:
                li[j], li[j+1] = li[j+1], li[j]
                exchange = True
        if not exchange:
            return


li = list(range(1000))
random.shuffle(li)
bubble_sort_2(li)

 

 

选择排序

import random
from timewrap import cal_time


@cal_time
def select_sort(li):
    for i in range(len(li) - 1):  # i表示第i趟
        # 无序区的范围 [i, len(li))
        min_pos = i
        for j in range(i + 1, len(li)):
            if li[j] < li[min_pos]:
                min_pos = j
        li[i], li[min_pos] = li[min_pos], li[i]


li = list(range(10000))
random.shuffle(li)
print(li)
select_sort(li)
print(li)

 

插入排序

-

import random
from timewrap import cal_time

# 何时插入? 1. j位置的值小于tmp  2.j=-1   li[j+1]=tmp

@cal_time
def insert_sort(li):
    for i in range(1, len(li)):
        j = i-1
        tmp = li[i]
        while j >= 0 and li[j] > tmp:
            li[j+1] = li[j]
            j -= 1
        li[j+1] = tmp
        # print(li)

li = list(range(10000))
random.shuffle(li)
print(li)
insert_sort(li)
print(li)

 

快速排序

- 原理:

  - 随机找到一个数,让其到排序后的索引处(让一个数先归位);并且让小于他的数到左边,大于他的数到右边

  - 递归上面的步骤

 

- 使用前提:

  大于两个元素

 

- 代码:

import sys
import random
from timewrap import cal_time

sys.setrecursionlimit(1100)

def _quick_sort(li, left, right):
    if left < right: # 至少两个元素
        mid = partition(li, left, right)
        _quick_sort(li, left, mid-1)
        _quick_sort(li, mid+1, right)


@cal_time
def quick_sort(li):
    _quick_sort(li, 0, len(li)-1)


def partition(li, left, right):
    i = random.randint(left, right)
    li[left], li[i] = li[i], li[left]
    tmp = li[left]
    while left < right:
        while left < right and li[right] >= tmp:
            right -= 1
        li[left] = li[right]
        while left < right and li[left] <= tmp:
            left += 1
        li[right] = li[left]
    li[left] = tmp
    return left


li = list(range(100000, -1, -1))
random.shuffle(li)
quick_sort(li)
print(li)

 

堆排序

 -

import random
from timewrap import cal_time


def sift(li, low, high):
    # low 表示根位置 high 表示最后元素的位置
    tmp = li[low]
    i = low  # i指向空位
    j = 2 * i + 1  # j指向孩子
    # 把tmp写回来有两种条件 1. tmp > li[j]  2. j位置没有值 (也就是i已经是叶子了)
    while j <= high:  # 对应退出条件2
        if j + 1 <= high and li[j + 1] > li[j]:  # 如果右孩子存在且右孩子更大
            j += 1
        if li[j] > tmp:
            li[i] = li[j]
            i = j
            j = 2 * i + 1
        else:  # 对应退出条件1
            break
    li[i] = tmp


@cal_time
def heap_sort(li):
    n = len(li)
    # 1. 建立堆
    for low in range(n // 2 - 1, -1, -1):
        sift(li, low, n - 1)
    # print(li)
    # 2. 挨个出数 退休-棋子-调整
    for high in range(n - 1, -1, -1):
        li[0], li[high] = li[high], li[0]
        sift(li, 0, high - 1)
        # print(li)


li = list(range(100000))
random.shuffle(li)
print(li)
heap_sort(li)
print(li)

 

归并排序

 -

import random
from timewrap import cal_time


def merge(li, low, mid, high):
    li_tmp = []
    i = low
    j = mid + 1
    while i <= mid and j <= high:
        if li[i] <= li[j]:
            li_tmp.append(li[i])
            i += 1
        else:
            li_tmp.append(li[j])
            j += 1
    while i <= mid:
        li_tmp.append(li[i])
        i += 1
    while j <= high:
        li_tmp.append(li[j])
        j += 1
    for i in range(len(li_tmp)):
        li[i + low] = li_tmp[i]


def _merge_sort(li, low, high):
    if low < high:  # 2个元素及以上
        mid = (low + high) // 2
        _merge_sort(li, low, mid)
        _merge_sort(li, mid + 1, high)
        merge(li, low, mid, high)


@cal_time
def merge_sort(li):
    _merge_sort(li, 0, len(li) - 1)


li = list(range(100000))
random.shuffle(li)
merge_sort(li)

 

posted @ 2018-12-11 17:34  浮生凉年  阅读(140)  评论(0编辑  收藏  举报