Sort the list (bubble, select, insert, fast, heap, merge, Hill) List sorting (bubble, select, insert, fast, heap, merge, Hill)

Sort the list (bubble, select, insert, fast, heap, merge, Hill)

 

A. List query

"" " 
Requirements: query from the list specified element
Input: list element to be queried
output: index element or elements to find

methods:
1. sequential search
2. binary search (list in ascending order)
" ""
# 顺序查找
def linear_search(data_set, value):
    for i in range(len(data_set)):
        if data_set[i] == value:
            return i
    return


print(linear_search([12, 3, 4, 5, 3, 6, 7], 3))
# 二分查找
def bin_search(data_set, value):
    left = 0
    right = len(data_set) - 1
    while left <= right:
        mid = (left + right) // 2
        if data_set[mid] == value:
            return mid
        elif data_set[mid] > value:
            right = mid - 1
        elif data_set[mid] < value:
            left = mid + 1


print(bin_search(sorted([12, 3, 4, 5, 3, 6, 7]), 3))
# 二分查找(递归版)
def bin_search_rec(data_set, value, left, right):
    if left <= right:
        mid = (left + right) // 2
        if data_set[mid] == value:
            return mid
        elif data_set[mid] > value:
            return bin_search_rec(data_set, value, left, mid - 1)
        elif data_set[mid] < value:
            return bin_search_rec(data_set, value, mid + 1, right)


print(bin_search_rec(sorted([12, 3, 4, 5, 3, 6, 7]), 3, 0, 6))

Second, the list is sorted

Reference blog: http://blog.csdn.net/mrlevo520/article/details/77829204

"" " 
Method:
1. Bubble Sort (stabilization)
2. Selection Sort
3. insertion sort (stabilization)
4. Quick Sort
The heap sort
6. merge sort (stable)
7. Shell sort
" ""
# #################################### 计时装饰器 ####################################
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
Timer decorator
Bubble sort # 1 
# principle: from a start index position 0, the size of the comparison index values 0 and 1, the value of the index to be 0, then the switch places. Then comparing the index values 1 and 2, a trip down to the end of the maximum change over again compared.
# I: Run
# j: hand position
# time complexity: O (n2)
def bubble_sort (li):
     for i in range (len (li) - 1 ):
         for j in range (len (li) - 1 - i):
             if li [j]> li [j + 1 ]: 
                li [j ], li [j + 1] = li [j + 1 ], li [j] 


li = [12, 3, 4, 5, 3, 6, 7 ] 
bubble_sort (li) 
print (li)

# Bubbling optimization
# perform no exchange trip, then an ordered list, sorted end

def bubble_sort_op(li):
    for i in range(len(li) - 1):
        exchange = False
        for j in range(len(li) - 1 - i):
            if li[j] > li[j + 1]:
                li[j], li[j + 1] = li[j + 1], li[j]
                exchange = True
        if not exchange:
            return


2. Select the sort #
# Principle: starting from index position 0, position 1 is compared with the value, the smaller the index value is recorded, and then comparing the values 1 and 2, in terms of the value exchange trip position 0 and the smallest index. 1 compares the index at the beginning of a trip.
# Key: disordered regions, the minimum value of the index
# I: Run
# J: pointer
# time complexity: O (n2)

def select_sort(li):
    for i in range(len(li) - 1):
        min_index = i
        for j in range(i + 1, len(li)):
            if li[j] < li[min_index]:
                min_index = j
        if min_index != i:
            li[i], li[min_index] = li[min_index], li[i]
# Writing II: distinction and bubble sort, the number of trips to the region last. 
DEF select_sort (Li):
     for I in Range (len (Li)):
         for J in Range (len (Li) - I):
             IF Li [I]> Li [I + J]: 
                Li [I], Li [ I + J] Li = [I + J], Li [I] 

Li = [12 is,. 3,. 4,. 5,. 3,. 6,. 7 ] 
select_sort (Li) 
Print (Li)

Write pictures described here

Insertion sort # 3 
# principle: each step is a row of data to be inserted into the appropriate size according to their position in the sorted data, until full insertion is completed.
# Starting at index 1, the value stored as a temporary element value is relatively ordered regions, encounters the first temporary value is greater than the value in the table is the value of j, the value of the temporary insertion position to j, value sequentially backward behind.
# Key: a default sequence 0-th element is ordered, the interpolated values, pop the original value
# I: Run
# J: pointer
# time complexity: O (n2)

DEF insert_sort (Li):
     for I in Range (. 1 , len (Li)):
         for J in Range (I):
             IF Li [I] < Li [J]: 
                li.insert (J, Li [I])   # first come first than their numbers, and quickly brake, stopping at that, so i chose to insert 
                li.pop (i + 1)   # because the previous insert operation, the number of digits plus the back, this position has been insert to go ahead, so pop pop 
                BREAK 


Li = [12 is,. 3,. 4,. 5,. 3,. 6,. 7 ] 
insert_sort (Li) 
Print (Li)

Write pictures described here

# 4. 快速排序
# 原理:从数列中取出一个值,区分过程,将比这个值大的放在它的右边,将比这个值小的放在它的左边,再最左右两个区域重复这个过程,直到各个区域只有一个数。
# 时间复杂度:O(nlogn)
# 最坏的情况:每次的取值为最大值或最小值,造成分区不均匀。性能解决插入排序,时间复杂度为O(n2)。
# pivot:枢

def quick_sort(li):
    if len(li) < 2:
        return li
    else:
        pivot = li[0]
        less = [i for i in li[1:] if i < pivot]
        greater = [j for j in li[1:] if j > pivot]
        return quick_sort(less) + [pivot] + quick_sort(greater)

print(quick_sort([1, 5, 2, 6, 9, 3]))

Write pictures described here

# 5. 堆排序
# 堆是一棵顺序存储的完全二叉树。
# 其中每个结点的关键字都不大于其孩子结点的关键字,这样的堆称为小根堆。
# 其中每个结点的关键字都不小于其孩子结点的关键字,这样的堆称为大根堆。
# 原理:
# 1. 多次调整建立堆,得到堆顶为最大元素
# 2. 取出堆顶,将最后一个元素放到堆顶,经过一次调整重新变成堆。
# 3. 重复建堆,取堆顶元素。
# 时间复杂度:O(nlogn)

def sift(li, left, right):
    i = left
    j = 2 * i + 1
    tmp = li[i]
    while j <= right:
        if j + 1 <= right and li[j] < li[j + 1]:
            j = j + 1
        if tmp < li[j]:
            li[i] = li[j]
            i = j
            j = 2 * i + 1
        else:
            break
    li[i] = tmp


def heap_sort(li):
    n = len(li)
    for i in range(n // 2 - 1, -1, -1):  # 建立堆
        sift(li, i, n - 1)
    for i in range(n - 1, -1, -1):  # 挨个出数
        li[0], li[i] = li[i], li[0]
        sift(li, 0, i - 1)


li = [6, 8, 1, 9, 3, 0, 7, 2, 4, 5]
heap_sort(li)
print(li)

Write pictures described here

# 6.归并排序
# 原理:用分割的方法将序列分割成一个个已经排好序的序列,再利用归并的方法将一个个子序列合并成排序好的序列。
# 关键点:递归分解,归并
# 时间复杂度:O(nlogn)

def merge(left, right):
    result = []
    while left and right:
        result.append(left.pop(0) if left[0] <= right[0] else right.pop(0))
    while left:
        result.append(left.pop(0))
    while right:
        result.append(right.pop(0))
    # if left:
    #     result.extend(left)
    # if right:
    #     result.extend(right)

    return result


def merge_sort(li):
    if len(li) <= 1:
        return li
    mid_index = len(li) // 2
    left = merge_sort(li[:mid_index])  # 递归拆解的过程
    right = merge_sort(li[mid_index:])
    return merge(left, right)  # 合并的过程


print(merge_sort([1, 5, 2, 6, 9, 3]))

Write pictures described here

# 一般情况下,就运行时间而言:
# 快速排序 < 归并排序 < 堆排序
# 三种排序算法的缺点:

# 快速排序:极端情况下排序效率低
# 归并排序:需要额外的内存开销
# 堆排序:在快的排序算法中相对较慢


# 7. 希尔排序
# 原理:一种分组插入排序算法。每次按照gap间隔的分组,对每组进行插入排序。
# 关键点:gap——间隙
# 时间复杂度:O((1+τ)n) ≈≈ O(1.3n)

def shell_sort(li):
    n = len(li)
    gap = n // 2  # 初始步长
    while gap > 0:
        for i in range(gap, n):
            temp = li[i]  # 每个步长进行插入排序
            j = i - gap
            # 插入排序
            while j >= 0 and li[j] > temp:
                li[j + gap] = li[j]
                j -= gap
            li[j + gap] = temp

        gap = gap // 2  # 得到新的步长

    return li

print(shell_sort([1, 5, 2, 6, 9, 3]))
 
 
 

一. 列表查询

"""
要求:从列表中查询指定元素
输入:列表,待查询元素
输出:元素下标或未查找到元素

方法:
1. 顺序查找
2. 二分查找(列表为升序)
"""
# 顺序查找
def linear_search(data_set, value):
    for i in range(len(data_set)):
        if data_set[i] == value:
            return i
    return


print(linear_search([12, 3, 4, 5, 3, 6, 7], 3))
# 二分查找
def bin_search(data_set, value):
    left = 0
    right = len(data_set) - 1
    while left <= right:
        mid = (left + right) // 2
        if data_set[mid] == value:
            return mid
        elif data_set[mid] > value:
            right = mid - 1
        elif data_set[mid] < value:
            left = mid + 1


print(bin_search(sorted([12, 3, 4, 5, 3, 6, 7]), 3))
# 二分查找(递归版)
def bin_search_rec(data_set, value, left, right):
    if left <= right:
        mid = (left + right) // 2
        if data_set[mid] == value:
            return mid
        elif data_set[mid] > value:
            return bin_search_rec(data_set, value, left, mid - 1)
        elif data_set[mid] < value:
            return bin_search_rec(data_set, value, mid + 1, right)


print(bin_search_rec(sorted([12, 3, 4, 5, 3, 6, 7]), 3, 0, 6))

二、列表排序

参考博客:http://blog.csdn.net/mrlevo520/article/details/77829204

"""
方法:
1. 冒泡排序  (稳定)
2. 选择排序
3. 插入排序  (稳定)
4. 快速排序
5. 堆排序
6. 归并排序  (稳定)
7. 希尔排序
"""
# #################################### 计时装饰器 ####################################
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
计时器装饰器
# 1. 冒泡排序
# 原理:从索引为0的位置开始,比较索引0和1的值的大小,索引0的值大,则互换位置。再比较索引1和2的值,一趟下来,最大值换到末尾,再从头比较。
# i: 趟
# j: 指针位置
# 时间复杂度:O(n2)
def bubble_sort(li):
    for i in range(len(li) - 1):
        for j in range(len(li) - 1 - i):
            if li[j] > li[j + 1]:
                li[j], li[j + 1] = li[j + 1], li[j]


li = [12, 3, 4, 5, 3, 6, 7]
bubble_sort(li)
print(li)

# 冒泡优化
# 执行一趟没有交换,则说明列表有序,结束排序

def bubble_sort_op(li):
    for i in range(len(li) - 1):
        exchange = False
        for j in range(len(li) - 1 - i):
            if li[j] > li[j + 1]:
                li[j], li[j + 1] = li[j + 1], li[j]
                exchange = True
        if not exchange:
            return


# 2. 选择排序
# 原理:从索引位置0开始,与位置1的值比较,记录较小值的索引,再比较1和2的值,一趟下来讲位置0和最小索引的值交换。下一趟从索引1开始比较。
# 关键点:无序区,最小值索引
# i:趟
# j:指针
# 时间复杂度:O(n2)

def select_sort(li):
    for i in range(len(li) - 1):
        min_index = i
        for j in range(i + 1, len(li)):
            if li[j] < li[min_index]:
                min_index = j
        if min_index != i:
            li[i], li[min_index] = li[min_index], li[i]
# 写法二:注意与冒泡排序的区分,趟数区到最后一位。
def select_sort(li):
    for i in range(len(li)):
        for j in range(len(li) - i):
            if li[i] > li[i + j]:
                li[i], li[i + j] = li[i + j], li[i]

li = [12, 3, 4, 5, 3, 6, 7]
select_sort(li)
print(li)

Write pictures described here

# 3. 插入排序
# 原理:是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕。
# 从索引1开始,取值存为一个临时值与有序区的元素比较,遇到第一个比临时值大的值,此值的下表为j,将临时值插入到j的位置,其后面的值依次后移。
# 关键点:默认序列中的第0个元素是有序的,插入值后,pop出原来的值
# i:趟
# j:指针
# 时间复杂度:O(n2)

def insert_sort(li):
    for i in range(1, len(li)):
        for j in range(i):
            if li[i] < li[j]:
                li.insert(j, li[i])  # 首先碰到第一个比自己大的数字,赶紧刹车,停在那,所以选择insert
                li.pop(i + 1)  # 因为前面的insert操作,所以后面位数+1,这个位置的数已经insert到前面去了,所以pop弹出
                break


li = [12, 3, 4, 5, 3, 6, 7]
insert_sort(li)
print(li)

Write pictures described here

# 4. 快速排序
# 原理:从数列中取出一个值,区分过程,将比这个值大的放在它的右边,将比这个值小的放在它的左边,再最左右两个区域重复这个过程,直到各个区域只有一个数。
# 时间复杂度:O(nlogn)
# 最坏的情况:每次的取值为最大值或最小值,造成分区不均匀。性能解决插入排序,时间复杂度为O(n2)。
# pivot:枢

def quick_sort(li):
    if len(li) < 2:
        return li
    else:
        pivot = li[0]
        less = [i for i in li[1:] if i < pivot]
        greater = [j for j in li[1:] if j > pivot]
        return quick_sort(less) + [pivot] + quick_sort(greater)

print(quick_sort([1, 5, 2, 6, 9, 3]))

Write pictures described here

# 5. 堆排序
# 堆是一棵顺序存储的完全二叉树。
# 其中每个结点的关键字都不大于其孩子结点的关键字,这样的堆称为小根堆。
# 其中每个结点的关键字都不小于其孩子结点的关键字,这样的堆称为大根堆。
# 原理:
# 1. 多次调整建立堆,得到堆顶为最大元素
# 2. 取出堆顶,将最后一个元素放到堆顶,经过一次调整重新变成堆。
# 3. 重复建堆,取堆顶元素。
# 时间复杂度:O(nlogn)

def sift(li, left, right):
    i = left
    j = 2 * i + 1
    tmp = li[i]
    while j <= right:
        if j + 1 <= right and li[j] < li[j + 1]:
            j = j + 1
        if tmp < li[j]:
            li[i] = li[j]
            i = j
            j = 2 * i + 1
        else:
            break
    li[i] = tmp


def heap_sort(li):
    n = len(li)
    for i in range(n // 2 - 1, -1, -1):  # 建立堆
        sift(li, i, n - 1)
    for i in range(n - 1, -1, -1):  # 挨个出数
        li[0], li[i] = li[i], li[0]
        sift(li, 0, i - 1)


li = [6, 8, 1, 9, 3, 0, 7, 2, 4, 5]
heap_sort(li)
print(li)

Write pictures described here

# 6.归并排序
# 原理:用分割的方法将序列分割成一个个已经排好序的序列,再利用归并的方法将一个个子序列合并成排序好的序列。
# 关键点:递归分解,归并
# 时间复杂度:O(nlogn)

def merge(left, right):
    result = []
    while left and right:
        result.append(left.pop(0) if left[0] <= right[0] else right.pop(0))
    while left:
        result.append(left.pop(0))
    while right:
        result.append(right.pop(0))
    # if left:
    #     result.extend(left)
    # if right:
    #     result.extend(right)

    return result


def merge_sort(li):
    if len(li) <= 1:
        return li
    mid_index = len(li) // 2
    left = merge_sort(li[:mid_index])  # 递归拆解的过程
    right = merge_sort(li[mid_index:])
    return merge(left, right)  # 合并的过程


print(merge_sort([1, 5, 2, 6, 9, 3]))

Write pictures described here

# 一般情况下,就运行时间而言:
# 快速排序 < 归并排序 < 堆排序
# 三种排序算法的缺点:

# 快速排序:极端情况下排序效率低
# 归并排序:需要额外的内存开销
# 堆排序:在快的排序算法中相对较慢


# 7. 希尔排序
# 原理:一种分组插入排序算法。每次按照gap间隔的分组,对每组进行插入排序。
# 关键点:gap——间隙
# 时间复杂度:O((1+τ)n) ≈≈ O(1.3n)

def shell_sort(li):
    n = len(li)
    gap = n // 2  # 初始步长
    while gap > 0:
        for i in range(gap, n):
            temp = li[i]  # 每个步长进行插入排序
            j = i - gap
            # 插入排序
            while j >= 0 and li[j] > temp:
                li[j + gap] = li[j]
                j -= gap
            li[j + gap] = temp

        gap = gap // 2  # Get the new step size 

    return Li 

Print (shell_sort ([. 1,. 5, 2,. 6,. 9,. 3]))

Guess you like

Origin www.cnblogs.com/taosiyu/p/11265516.html