冒泡排序 最好O(n)平均O(n^2) 选择排序O(n2) 插入排序O(n2)

LOWB 三人组

  • 分清有序区跟无序区

冒泡排序

  • 思路:

    首先,列表每两个相邻的数,如果前边的比后边的大,那么交换和两个数....

  • 冒泡排序优化

    如果一趟没有发生任何交换 那么证明列表已经是有序的了

import random
from cal_time import cal_time  # 计算时间的 装饰器

@cal_time
def bubble_sort(li):
    for i in range(len(li)-1): # i表示第i趟
        # 第i趟无序区位置【0,n-i-1】
        for j in range(len(li)-i-1):
            if li[j] > li[j+1]:
                li[j], li[j+1] = li[j+1], li[j]

# 优化
@cal_time
def bubble_sort_2(li):
    for i in range(len(li)-1): # i表示第i趟
        # 第i趟无序区位置【0,n-i-1】
        exchange = False # 如果一趟没有发生任何交换 那么证明列表已经是有序的了  可以结束循环了
        for j in range(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

# 最好情况 O(n)
# 平均情况 O(n^2)
# 最坏情况 O(n^2)


# li = [6,8,9,7,5,1,4,2,3,0]
li = list(range(10000))
#random.shuffle(li)
bubble_sort_2(li)

选择排序

  • 思路:
    • 一趟便利记录最小的数,放到第一个位置;
    • 再一趟便利记录剩余列表中最小的数,继续放置;
    • 选出最小的数?
import random
from cal_time import cal_time

# 获取最小值的函数
def find_min(li):
    min_num = li[0]  # 
    for i in range(1, len(li)):
        if li[i] < min_num:
            min_num = li[i]
    return min_num

# 找最小值的下标
def find_min_pos(li):
    min_pos = 0
    for j in range(1, len(li)):
        if li[j] < li[min_pos]:
            min_pos = j
    return min_pos

# 选择排序
@cal_time
def select_sort(li):
    for i in range(len(li)-1): # 第i趟
        # 第i趟 无序区【i, len(li)-1】
        # 找无序区最小数位置,和无序区第一个数交换
        min_pos = i  # 最小值的下标
        for j in range(i+1, len(li)):
            if li[j] < li[min_pos]:
                min_pos = j
        li[min_pos], li[i] = li[i], li[min_pos]
        # print(li)

# li = [5,7,8,4,1,6,2,9,3,0]
# print(li)
li = list(range(10000))
random.shuffle(li)
select_sort(li)
# 时间复杂度: O(n2)
# 空间复杂度:
  • 优化
def select_sort(li):
    count = len(li)
    for i in range(count // 2):
        min_index = i
        if li[min_index] > li[min_index + 1]:
            li[min_index + 1], li[min_index] = li[min_index], li[min_index + 1]
        max_index = count - i - 1
        for j in range(i + 1, count - i):
            if li[min_index] > li[j]:
                min_index = j
            if li[max_index] < li[j]:
                max_index = j
        if min_index != i:
            li[i], li[min_index] = li[min_index], li[i]
        if max_index != count - i - 1:
            li[count - i - 1], li[max_index] = li[max_index], li[count - i - 1]

插入排序

  • 思路:

    列表被分为有序区和无序区两个部分.最初有序区只有一个元素

    每次从无序区选择一个元素,插入到有序区的位置,直到无序区变空.

import random
from cal_time import cal_time

@cal_time
def insert_sort(li):
    for i in range(1, len(li)):  # i表示第i趟,还表示摸到的牌的位置
        tmp = li[i]  # 取出要判断的数值
        j = i - 1  # 被判断的数值位置
        # and 前边为退出循环条件  后边为 逻辑判断
        while j >= 0 and li[j] > tmp:  # and 左右不能换
            li[j + 1] = li[j]  # 前面的数大于后面的数 将数值向后移动一位
            j -= 1  # 判断的位置向前移动一位  会出现 负数  加循环终止条件
        li[j + 1] = tmp  # 将取出的数值放回空缺的位置


# li = [5,7,8,4,1,6,2,9,3,0]
# print(li)
li = list(range(10000))
random.shuffle(li)
insert_sort(li)

# 时间复杂度: O(n2)
# 空间复杂度:

# def test(li):
#     i = 0
#     # i < len(li) 判断是否 索引越界
#     while i < len(li) and li[i] > 0:
#         i += 1
#     if i < len(li):
#         return li[i]
#     else:
#         return None
#
# li = [3,5,7,8,9,5]
# print(test(li))


# 补充:布尔语句的短路功能

# 0 and 7
# 2 and 1
# 1 and 0
# 0 or 4
# 3 or 5


# def foo(x):
#     x <= 0 or print('abc')
#
# foo(4)


posted @ 2019-04-22 12:51  拐弯  阅读(320)  评论(0编辑  收藏  举报