算法与数据结构python代码笔记

在b站上跟着左程云老师的课程学,这里简单记录一下每次课程学的代码。本人超级新手,很期待和大家共同讨论!

一、入门

1、二进制与位运算

#下面我们设计一个将十进制数转换成二进制的代码,要求二进制位数不超过32位
#import numpy as np
def print_binary(num):
    result = '' #为使最终输出结果为一列字符串
    for i in range(31,-1,-1):
        a = num & (1 << i)
        if a == 0:
            result +='0'
        else:
            result +='1'
    print(result)

自己摸的,看起来不是很简洁。

#chatgpt给的写法
def print_binary(num):
    for i in range(31, -1, -1):
        # 下面这句写法,可以改成 :
        # print("1" if (num & (1 << i)) != 0 else "0", end="")
        # 但不可以改成 :
        # print("1" if (num & (1 << i)) == 1 else "0", end="")
        # 因为num如果第i位有1,那么(num & (1 << i))是2的i次方,而不一定是1
        # 比如,num = 0010011
        # num的第0位是1,第1位是1,第4位是1
        # (num & (1<<4)) == 16(不是1),说明num的第4位是1状态
        print("1" if (num & (1 << i)) != 0 else "0", end="")
    print()

# 示例用法
num = -19
print_binary(num)

print(..., end='')表示用''替代换行符'\n',从而使最终输出一串字符串,最后的print()输入一个'\n',使得即便连续调用print_binary(),也不会出现一大串数字。

2、三傻排序:选择、冒泡与插入

选择排序:

def swap(arr, i, j):
    arr[i], arr[j] = arr[j], arr[i]   

#选择排序
def selection_sort(arr):
    if arr is None or len(arr) < 2:   
        return
    
    for i in range(len(arr) - 1):
        min_index = i
        for j in range(i + 1, len(arr)):
            if arr[j] < arr[min_index]:
                min_index = j
        swap(arr, i, min_index)

冒泡排序:

#冒泡排序, 自编版
def swap(arr, i, j):
    arr[i], arr[j] = arr[j], arr[i]

def bubbleSort(arr):
    if arr == None or len(arr) < 2:
        return

    for i in range(len(arr)-1):
        for j in range(len(arr)-i-1):
            if arr[j] > arr[j+1]:
                swap(arr, j, j+1)
    print(arr)


#冒泡排序, chatgpt版
def swap(arr, i, j):
    arr[i], arr[j] = arr[j], arr[i]

def bubble_sort(arr):
    if arr is None or len(arr) < 2:
        return
    
    for end in range(len(arr) - 1, 0, -1):
        for i in range(end):
            if arr[i] > arr[i + 1]:
                swap(arr, i, i + 1)

插入排序:

#插入排序, 自编版
def swap(arr, i, j):
    arr[i], arr[j] = arr[j], arr[i]

def insertionSort(arr):
    if arr == None or len(arr)<2:
        return

    for i in range(1, len(arr)):
        for j in range(i-1, -1, -1):
            if arr[j+1] < arr[j]:
                swap(arr, j, j+1)
            else:
                break
    print(arr)



#插入排序, chatgpt版
def swap(arr, i, j):
    arr[i], arr[j] = arr[j], arr[i]

def insertion_sort(arr):
    if arr is None or len(arr) < 2:
        return
    
    for i in range(1, len(arr)):
        j = i - 1
        while j >= 0 and arr[j] > arr[j + 1]:
            swap(arr, j, j + 1)
            j -= 1

3、检验利器:对数器

#下面以上节的三傻排序为例写一个对数器,本质思想是生成随机数组对多种代码跑出来的结果进行对比

#自编版对数器
import numpy as np
#N:生成随机数组的最大长度,V:随机数组的元素取值范围[0,V),test_times:测试次数
def Validator(N, V, test_times):
    print('测试开始')
    for i in range(test_times):
        n = np.random.randint(N)+1 #生成一个随机长度,范围是1~N
        arr = np.random.randint(V, size = n) #生成随机数组,元素取值范围[0,V)中的整数
        arr1 = arr
        arr2 = arr
        arr3 = arr
        selection_sort(arr1)
        bubble_sort(arr2)
        insertion_sort(arr3)
        if (arr1 == arr2).all() & (arr1 == arr3).all():
            continue
        else:
            print('测试出错')
            break
    print('测试结束')


#chatgpt版
import random

def random_array(n, v):
    return [random.randint(1, v) for _ in range(n)]

def copy_array(arr):
    return arr[:]

def same_array(arr1, arr2):
    return arr1 == arr2

# 测试
N = 20
V = 100
test_times = 500
print("测试开始")
for i in range(test_times):
    n = random.randint(0, N - 1)
    arr = random_array(n, V)
    arr1 = copy_array(arr)
    arr2 = copy_array(arr)
    arr3 = copy_array(arr)
    selection_sort(arr1)
    bubble_sort(arr2)
    insertion_sort(arr3)
    if not same_array(arr1, arr2) or not same_array(arr1, arr3):
        print("出错了!")
        # 可以添加更多的调试信息,以便进一步分析问题
print("测试结束")

4、二分搜索

1) 在有序数组中找num

import random

def right(arr, num): #傻瓜式找法,一个一个找
    for i in arr:
        if i == num:
            return True
    return False

def exist(arr, num):
    if arr is None or len(arr) == 0:
        return False
    l = 0  #搜索左边界
    r = len(arr) - 1  #搜索右边界
    while l <= r:
        m = (l + r) // 2 #找到位置中位数
        if arr[m] == num:
            return True
        elif arr[m] > num: #如果中位数比num大,则要在左边找,所以右边界r = m-1
            r = m - 1
        else:  #如果中位数比num小,则要在右边找,所以左边界l = m+1
            l = m + 1
    return False

def random_array(n, v): #随机生成一个取值范围为0~V的规模为n的数组
    return [random.randint(1, v) for _ in range(n)]

# 测试
N = 100
V = 1000
test_time = 500
print("测试开始")
for i in range(test_time):
    n = random.randint(0, N - 1)
    arr = random_array(n, V) 
    arr.sort()  #保证输入的数组是有序的
    num = random.randint(1, V)  #随机生成num
    if right(arr, num) != exist(arr, num):
        print("出错了!")
print("测试结束")

2)在有序数组中找>=num的最左位置

#仍用对数器来检验

#暴力解
def right(arr, num):
    for i in range(len(arr)):
        if num <= arr[i]:
            return i
    return -1

#二分法
def findleft(arr, num):
    ans = -1
    l = 0
    r = len(arr)-1
    while l<=r:
        m = l + ((r-l)//2)
        if arr[m] < num:
            l = m+1
        else:
            ans = m
            r = m-1
    return ans

#对数器测试
import random

def random_array(n, v): #随机生成一个取值范围为0~V的规模为n的数组
    return [random.randint(0, v) for _ in range(n)]

# 测试
N = 100
V = 1000
test_time = 500
print("测试开始")
for i in range(test_time):
    n = random.randint(1, N - 1)
    arr = random_array(n, V) 
    arr.sort()  #保证输入的数组是有序的
    num = random.randint(1, V)  #随机生成num
    if right(arr, num) != findleft(arr, num):
        print("出错了!")
print("测试结束")

3)寻找峰值

def findPeakPosition(arr):
    n = len(arr)
    if n == 1:
        return 0
    if arr[0] > arr[1]:
        return 0
    if arr[-1] > arr[-2]:
        return n-1
    #下面进入二分过程
    l,r = 1, n-2
    while l <= r:
        m = l + ((r-l)>>1)
        if (arr[m-1] < arr[m]) & (arr[m+1] < arr[m]):
            return m
        elif arr[m-1] > arr[m]:
            r = m-1
        else:
            l = m+1   

p.s. leetcode上竟有时间复杂度更低的解法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值