1.算法

# by luffycity.com
# def func4(n):
#     if n > 0:
#         func4(n-1)
#         print(n)
#
# def text(n):
#     if n > 0:
#         print("抱着",end='')
#         text(n-1)
#         print("的我", end='')
#     else:
#         print("我的小鲤鱼",end='')
#
# text(5)

def hanoi(n, A, B, C):
    if n > 0:
        # n个盘子从A经过B移动到C
        hanoi(n-1, A, C, B)
        print("%s->%s" % (A, C))
        hanoi(n-1, B, A, C)

hanoi(4, "A", "B", "C")
汉诺塔代码

 

 

 

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
def binary_search(li, val):
    low = 0
    high = len(li) - 1
    while low <= high:
        mid = (low + high) // 2
        if li[mid] > val:
            high = mid - 1
        elif li[mid] < val:
            low = mid + 1
        else:
            return mid
    else:
        return None
时间复杂度:O(logn)
@cal_time
def linear_search(li, val):
    try:
        i = li.index(val)
        return i
    except:
        return None
时间复杂度:O(n)

li = list(range(0, 10000000, 2))
print(binary_search(li, 9000006))
print(linear_search(li, 9000006))
列表查找法代码
def bin_search_rec(data_set, value, low, high):
    if low <= high:
        mid = (low + high) // 2
        if data_set[mid] == value:
            return mid 
        elif data_set[mid] > value:
            return bin_search_rec(data_set, value, low, mid-1)
        else:
            return bin_search_rec(data_set, value, mid+1, high)
    else:
        return 
递归版的二分查找

 

# by luffycity.com

from cal_time import cal_time

@cal_time
def bubble_sort(li):
    for i in range(0, len(li)-1):
        # i表示第i趟 有序区有i个数
        for j in range(0, len(li)-i-1):
            if li[j] > li[j+1]:
                li[j], li[j+1] = li[j+1], li[j]
冒泡的时间复杂度:O(n^2)
冒泡排序的优化
如果冒泡排序中执行一趟而没有交换,则列表已经是有序状态,可以直接结束算法。

@cal_time
def bubble_sort_2(li):
    for i in range(0, len(li)-1):
        # i表示第i趟 有序区有i个数
        exchange = False
        for j in range(0, len(li)-i-1):
            if li[j] > li[j+1]:
                li[j], li[j+1] = li[j+1], li[j]
                exchange = True
        if not exchange:
            return

import random

li = list(range(10000))
#random.shuffle(li)
bubble_sort_2(li)
print(li)
冒泡的代码

 

# by luffycity.com

from cal_time import cal_time

@cal_time
def select_sort(li):
    for i in range(len(li)-1):
        # 第i趟:有序区li[0:i] 无序区li[i:n]
        min_loc = i
        for j in range(i+1, len(li)):
            if li[min_loc] > li[j]:
                min_loc = j
        li[min_loc], li[i] = li[i], li[min_loc]

import random

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

时间复杂度:O(n^2)
选择排序代码

from cal_time import cal_time

@cal_time
def insert_sort(li):
    for i in range(1, len(li)):
        # i既表示趟数,也表示摸到的牌的下标
        j = i - 1
        tmp = li[i]
        while j >= 0 and li[j] > tmp:
            li[j+1] = li[j]
            j -= 1
        li[j+1] = tmp


import random

li = list(range(10000))
random.shuffle(li)
insert_sort(li)
print(li)
时间复杂度:O(n^2)
优化空间:应用二分法来查找插入点
插入排序代码

小结:冒泡排序,插入排序,选择排序 --- 时间复杂度:O(n^2)   空间复杂度:O(1)

 

# by luffycity.com

from cal_time import cal_time
import random


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)

# 1 2 3 4 5
def partition(li, left, right):
    i = random.randint(left,  right)
    li[left] , li[i] = li[i], li[left]
    tmp = li[left]
    while left < right:
        # 从右边找比tmp小的数
        while left < right and li[right] >= tmp:
            right -= 1
        li[left] = li[right]
        # 从左边找比tmp大的数
        while left < right and li[left] <= tmp:
            left += 1
        li[right] = li[left]
    li[left] = tmp
    return left

@cal_time
def sys_sort(li):
    li.sort()

import random
import copy
import sys

sys.setrecursionlimit(1000000000)

li = list(range(100000,1,-1))
li.sort()
# random.shuffle(li)
# li1 = copy.deepcopy(li)
quick_sort(li)
#sys_sort(li)
快速排序的代码

# by luffycity.com

from cal_time import cal_time

def sift(li, low, high):
    tmp = li[low] # 原省长
    i = low
    j = 2 * i + 1
    while j <= high:    # 第二种跳出条件: j > high
        if j < high and li[j+1] > li[j]: # 如果右孩子存在并且大于左孩子
            j += 1
        if tmp < li[j]:
            li[i] = li[j]
            i = j
            j = 2 * i + 1
        else:   # 第一种跳出条件:li[j] <= tmp
            break
    li[i] = tmp

@cal_time
def heap_sort(li):
    n = len(li)
    # 1. 建堆
    for i in range(n // 2 - 1, -1, -1): # 最后一个非叶子节点的位置是n//2-1
        sift(li, i, n-1)
    # 2. 挨个出数
    for i in range(n-1, -1, -1): # i 表示此时堆的high位置
        li[0], li[i] = li[i], li[0] # 退休+棋子
        sift(li, 0, i-1)

import random


li = list(range(100000))
random.shuffle(li)
heap_sort(li)
print(li)
堆的排序代码

 

# by luffycity.com

def merge(li, low, mid, high):
    i = low
    j = mid + 1
    li_tmp = []
    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(low, high+1):
        li[i] = li_tmp[i-low]


def merge_sort(li, low, high):
    if low < high:  # 至少两个元素
        mid = (low + high) // 2
        print(li[low:mid + 1], li[mid + 1:high + 1])
        merge_sort(li, low, mid)
        merge_sort(li, mid+1, high)
        print(li[low:mid+1], li[mid+1:high+1])
        merge(li, low, mid, high)
        print(li[low:high + 1])

li = [10,4,6,3,8,2,5,7]
merge_sort(li, 0, len(li)-1)
一次归并代码

 

 

posted @ 2018-07-01 19:45  liang哥哥  阅读(99)  评论(0)    收藏  举报