简单算法 (二分查找、冒泡排序、快速排序,斐波那契数列。。。等)

二分查找

普通

def BinarySearch(nums,x):
    '''
        nums: 列表数组
        x: 目标数字
    '''
    left,right = 0,len(nums)-1
    while left <= right:
        mid = (left+right)//2
        if nums[mid] == x:
            return mid
        if nums[mid] < x:
            left = mid+1
        else:
            right = mid-1
    #如果不存在返回-1
    return -1

递归方式

# 如果目标数字在集合中返回下标,否则返回-1
def numsearch(arr, x, start=0, end=None):
    end = len(arr)-1 if end == None else end
    if start <= end:
        mid = start + (end - start) // 2
        if arr[mid] == x:
            return mid
        elif arr[mid] > x:
            return numsearch(arr, x, start=start, end=mid - 1)
        else:
            return numsearch(arr, x, start=mid + 1, end=end)
    else:
        return -1

arr = [11,22,44,33,55,66]
result = numsearch(arr,44)
print(result)

冒泡排序

原理:比较两个相邻的元素,将值大的元素交换到右边,第一轮比完后最后一个数一定是最大值,最后一个数无需再进行比较,第二轮过后倒数第二个数一定是第二大的值,无需再进行比较,以此类推

def sort(arr):
    num = len(arr)
    for i in range(num):
        for j in range(num-1-i):
            if arr[j]>arr[j+1]:
                arr[j],arr[j+1]=arr[j+1],arr[j]
    return arr

选择排序

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
重复第二步,直到所有元素均排序完毕。

def selectionSort(arr):
    for i in range(len(arr) - 1):
        # 记录最小数的索引
        minIndex = i
        for j in range(i + 1, len(arr)):
            if arr[j] < arr[minIndex]:
                minIndex = j
        # i 不是最小数时,将 i 和最小数进行交换
        if i != minIndex:
            arr[i], arr[minIndex] = arr[minIndex], arr[i]
    return arr

快速排序

1、

def quick_sort(b):
    """快速排序"""
    if len(b) < 2:
        return arr
    # 选取基准,随便选哪个都可以,选中间的便于理解
    mid = arr[len(b) // 2]
    # 定义基准值左右两个数列
    left, right = [], []
    # 从原始数组中移除基准值
    b.remove(mid)
    for item in b:
        # 大于基准值放右边
        if item >= mid:
            right.append(item)
        else:
            # 小于基准值放左边
            left.append(item)
    # 使用迭代进行比较
    return quick_sort(left) + [mid] + quick_sort(right)

2、

def partition(arr,low,high): 
    i = ( low-1 )         # 最小元素索引
    pivot = arr[high]     
  
    for j in range(low , high): 
  
        # 当前元素小于或等于 pivot 
        if   arr[j] <= pivot: 
          
            i = i+1 
            arr[i],arr[j] = arr[j],arr[i] 
  
    arr[i+1],arr[high] = arr[high],arr[i+1] 
    return ( i+1 ) 
  
 
# arr[] --> 排序数组
# low  --> 起始索引
# high  --> 结束索引
  
# 快速排序函数
def quickSort(arr,low,high): 
    if low < high: 
  
        pi = partition(arr,low,high) 
  
        quickSort(arr, low, pi-1) 
        quickSort(arr, pi+1, high) 
  
arr = [10, 7, 8, 9, 1, 5] 
n = len(arr) 
quickSort(arr,0,n-1) 
print ("排序后的数组:") 
for i in range(n): 
    print ("%d" %arr[i])

堆排序

堆(定义):(二叉)堆数据结构是一个数组对象,可以视为一棵完全二叉树。如果根结点的值大于(小于)其它所有结点,并且它的左右子树也满足这样的性质,那么这个堆就是大(小)根堆。


斐波那契数列

在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)

def recur_fibo(n):
   """递归函数
   输出斐波那契数列"""
   if n <= 1:
       return n
   else:
       return recur_fibo(n-1) + recur_fibo(n-2)

平衡点

假如一个数组中的元素,其前面的部分等于后面的部分,那么这个点的位序就是平衡点.
比如一个列表 numbers = [1,3,5,7,8,25,4,20],25前面的总和为24,25后面的总和也是24,25这个点就是平衡点;
思路:平衡点两边的数求和相等,也就是sum(lsit)减去这个数之后再除以2等于这个数某一边的数求和,可以用一个变量来累加这个数左边的那一部分序列。

numbers = [2,1,8,4,10,30,55,25,25,5]

def cal(arr):
    num = sum(arr)
    my_num = 0
    for i in arr:
        if my_num ==(num-i)/2:
            return i
        else:
            my_num+=i
    return -1
rr = cal(numbers)
print(rr)

反转单向链表

https://leetcode-cn.com/problems/reverse-linked-list/solution/dong-hua-yan-shi-206-fan-zhuan-lian-biao-by-user74/

# 递归方法
class ListNode(object):
    def __init__(self, val):
        self.val = val
        self.next = None

def nodeRe(head):
    if not head or not head.next:
        return head
    newhead = nodeRe(head.next)
    head.next.next = head
    head.next = None
    return newhead


a = ListNode(1)
a.next = ListNode(2)
a.next.next = ListNode(3)
a.next.next.next = ListNode(4)
s = nodeRe(a)
print(s)
print(s.val, s.next.val, s.next.next.val)

# 双指针迭代,循环
# 我们可以申请两个指针,第一个指针叫 pre,最初是指向 null 的。
# 第二个指针 cur 指向 head,然后不断遍历 cur。
# 每次迭代到 cur,都将 cur 的 next 指向 pre,然后 pre 和 cur 前进一位。
# 都迭代完了(cur 变成 null 了),pre 就是最后一个节点了。

class Solution(object):
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        # 申请两个节点,pre和 cur,pre指向None
        pre = None
        cur = head
        # 遍历链表,while循环里面的内容其实可以写成一行
        # 这里只做演示,就不搞那么骚气的写法了
        while cur:
            # 记录当前节点的下一个节点
            tmp = cur.next
            # 然后将当前节点指向pre
            cur.next = pre
            # pre和cur节点都前进一位
            pre = cur
            cur = tmp
        return pre
posted @ 2021-09-02 16:41  kopok  阅读(88)  评论(0编辑  收藏  举报