基础算法(python语言)

目录

排序

        冒泡排序

        选择排序

        插入排序

        希尔排序

        快速排序

        归并排序

        计数排序

        基数排序

        桶排序


前言:

       写的程序肯定还可以优化,但是主要是实现功能,算法优化应该就是数学上的问题,暂不处理

        如果逻辑看不懂可以上看这个网站:https://visualgo.net/zh(有图解)

排序

        冒泡排序

# 冒泡排序
'''
逻辑:
    比较相邻的两个元素。如果第一个比第二个大则交换他们的位置(升序排列,降序则反过来)。
    从列表的开始一直到结尾,依次对每一对相邻元素都进行比较
    从每个位置开始都要比较一轮
'''

array = [1, 2, 5, 4, 71, 3, 9, 6, 15, 2]

for i in range(len(array) - 1):
    # 每经历一轮,每轮中就有i个元素排列好
    mark = 0  # 标记为0就说明已经排列好
    for j in range(len(array) - 1 - i):
        if array[j] > array[j + 1]:
            mark += 1
            array[j], array[j + 1] = array[j + 1], array[j]
        else:
            continue
    if not mark:
        break

print(array)

        选择排序

# 选择排序
'''
逻辑
    1、 选取第一个元素,依次与后面元素进行比较,如果大于(小于)这个元素,就将二者位置交换,继续向后比较,直到最后一个元素
    2、 重复比较每一个元素
'''

array = [1, 2, 5, 4, 7, 3, 9, 6, 15, 2]

for i in range(len(array) - 1):
    for j in range(i + 1, len(array)):
        if array[i] > array[j]:
            array[i], array[j] = array[j], array[i]
        else:
            continue

print(array)

        插入排序

# 插入排序
'''
逻辑:
    1、将数组分为无序区和有序区
    2、依次向无序区放入元素,要保证,放入元素时要放入合适的位置(即排好序)
    3、直到将所有元素放入有序区就排序完成
'''

array = [1, 2, 5, 4, 7, 3, 9, 6, 15, 2]

for i in range(len(array)):
    for j in range(i + 1):
        if array[j] > array[i]:
            array[j], array[i] = array[i], array[j]

print(array)

        希尔排序

# 希尔排序
'''
希尔排序也就是 插入排序的升级版
    因为插入排序对即将排好和元素数量较少的数组排序快,
    所以需要对数组进行一些处理,使排序的速度加快,
    而希尔排序就是解决这一问题的

逻辑
    1、将数组内元素分组,开始以数组len的一半为步长,1与len + 1一组...等;
    2、将每组内元素进行排序;
    3、再以开始步长的一半为步长,进行分组排序...
    4、到步长为1时,对数组排序也就是插入排序。
'''


def hill(array):
    step = len(array) // 2  # 设置初始步长  分组
    while step > 0:  # 终止条件
        for i in range(step, len(array)):
            while i >= step and array[i] > array[i - step]:  # 每组进行排序   当 i 小于步长时, 也就是到每组第一个元素,无需再比较啦
                array[i], array[i - step] = array[i - step], array[i]
                i -= step
        step //= 2  # 缩短步长
    return array


arr = [1, 2, 9, 5, 0, 10]
print(hill(arr))

        快速排序

# 快速排序
'''
逻辑
    1、 将第一个数的位置确定,保证这个数左边的小于(大于)它,右边的大于(小于)它
    2、 在分别对左边右边里的数重复上面操作,直到剩最后一个数

    伪代码:(从大到小)
                首先,保存第一个数的值
                在l小于r时:
                    首先先让右下标与第一个数的值比较
                    如果右下标大于第一个数的值
                        右下标向右移动一位
                        再次让右下标比较
                    否则
                        将右下标的值赋给左下标

                    接着让左下标与第一个数的值比较
                    如果左下标小于第一个数的值
                        左下标向左移动一位
                        再次让左下标比较
                    否则
                        将左下标的值赋给右下标

                (到这里第一个数的位置已经确定)
                将第一个数左边的进行排序
                将第一个数右边的进行排序

                :return
'''


def Quickpai(array, l, r):  # array : 数组   l: 要排序的开始下标  r: 要排序的终止下标
    if l >= r:
        return array
    end = r  # 保存终止下标
    # 由于Python交换两个变量的值无需借助其他变量,所以就没有保存第一个数的值
    while l < r:
        while l < r and array[r] >= array[l]:
            r -= 1
        array[l], array[r] = array[r], array[l]
        while l < r and array[l] < array[r]:
            l += 1
        array[l], array[r] = array[r], array[l]

    # 对第一个数左边进行排序
    Quickpai(array, 0, l - 1)
    # 对第一个数右边进行排序
    Quickpai(array, l + 1, end)


array = [10, 2, 5, 4, 7, 3, 9, 6, 15, 2, 50, 24, 10, 0, 35]
Quickpai(array, 0, len(array) - 1)
print(array)

        归并排序

# 归并排序
'''
逻辑
    1、分组,将所有元素分成若干个含有2(1)个元素的组
    2、每组元素进行排序
    3、将小组两两合并
    4、最终将所有组合并为初始的数组,排序完成

    递归
'''


def merge(a, b):
    c = []
    h = j = 0
    while j < len(a) and h < len(b):  # 使用j、h确定分组内元素个数
        if a[j] < b[h]:
            c.append(a[j])
            j += 1
        else:
            c.append(b[h])
            h += 1

    if j == len(a):
        for i in b[h:]:   # 如果一个分组内元素都已经存入c中,则另一个直接存入
            c.append(i)
    else:
        for i in a[j:]:
            c.append(i)

    return c


def merge_sort(lists):
    middle = len(lists) // 2
    if len(lists) <= 1:
        return lists
    left = merge_sort(lists[:middle])
    right = merge_sort(lists[middle:])
    return merge(left, right)


a = [14, 2, 34, 43, 21, 19, 1, 9]
print(merge_sort(a))

        计数排序

# 计数排序
'''
逻辑
    1、 找出最大值与最小值
    2、 统计最大值与最小值之间每一个数的个数
    3、 依次将每个数存入列表,个数为几,则每个元素存几个
'''

arr = [1, 2, 0, 6, 5, 7, 4, 7, 3, 9, 10, 10, 2, 5, 7, 9, 6]


# 找出最大值和最小值
def Limit(array):
    count = []  # 存放每个元素个数
    max = arr[0]
    min = arr[0]
    for ar in arr:
        if max < ar:
            max = ar
        if min > ar:
            min = ar
    # 统计每个元素的个数
    for i in range(min, max + 1):
        number = 0
        for ar in arr:
            if ar == i:
                number += 1
        count.append(number)
    return count, min


# 将元素依次存入arr中
def Save(count, min):
    new_arr = []
    for c in count:
        for i in range(0, c):
            new_arr.append(min)
        min += 1
    return new_arr


print(Save(Limit(arr)[0], Limit(arr)[1]))

        基数排序

# 基数排序
'''
逻辑 (使用二维数组进行实现更容易理解)
    1、 分10个桶 0 - 9
    2、 根据个位数向桶中放元素(如果个位数等于桶号)
    3、 依次按照桶顺序将元素取出(取出顺序不作要求)
    4、 根据十位数向桶中放数据(如果十位数等于桶号)
    5、 依次按照桶顺序将元素以先进先出取出
'''


# 个位放 按放入桶的顺序取数据
def ge_in(array):
    ge_arr = [i for i in range(0, 10)]
    # 保存数组
    save_arr = []
    for ge in ge_arr:
        for arr in array:
            if ge == arr % 10:
                save_arr.append(arr)
    return save_arr


# 十位数
def shi_in(array):
    shi_arr = [i for i in range(0, 10)]
    # 保存数组
    save_arr = []
    for shi in shi_arr:
        for arr in array:
            if shi == arr // 10:
                save_arr.append(arr)
    return save_arr


if __name__ == "__main__":
    arr = [2, 21, 15, 30, 42, 0, 11, 16, 19]
    arr = ge_in(arr)
    arr = shi_in(arr)
    print(arr)

        桶排序

# 桶排序
'''
最快:每个桶内元素一样时
最慢:所有元素在一个桶内
在空间允许下,桶越多速度越快

逻辑
    每个桶内元素只有一个:
        1、创建一个(最大值-最小值)大小的数组,每个元素都是0
        2、如果对应的位置有元素,则让该位置元素加1
        3、依次判断数组内的该元素是否为0,不为0则输出对应的值,再将该元素减1
    每个桶内只有一个元素(与直接对数组进行排序差不多,排序时使用其他排序...)
    每个桶内有多个元素:
        1、创建一个(最大值-最小值)/n 向上取整大小的数组(这样采取二维数组进行更为方便)每个元素均为一个数组
        2、数组的每个元素数组代表的则是上一个元素的最大值+1 - 最小值 + (元素下表 + 1) * 3,第一个数组开头则是最小值。依次将所以元素放入对应的元素数组中
        3、对每个元素数组内元素进行排序(排序方法可自己随意选取)
        4、依次输出所有元素
'''
import random

# 每个桶内元素只有一个

def BucketPai(arrs):
    # 找出最大与最小值
    min = max =  arrs[0]
    for arr in arrs:
        if arr > max:
            max = arr
        elif arr < min:
            min = arr
    # 记录每个元素的个数
    result_arr = []
    for i in range(min, max + 1):
        number = 0  #  记录个数
        for arr in arrs:
            if arr == i:
                number += 1
        result_arr.append(number)
    # 将每个元素按照个数依次存入结果数组
    result = []
    for number in result_arr:
        for num in range(number):
            result.append(min)
        min += 1
    return result

if __name__ == "__main__":
    arr = [random.randint(1, 666) for i in range(666)]
    result = BucketPai(arr)
    print(result)

如内容有误,还望提醒。 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值