基本算法介绍以及代码实现(python)

常见算法介绍

在这里插入图片描述

1.线性搜索

def linear_search(arr, target):
    for i, element in enumerate(arr):
        if element == target:
            return i
    return -1

2.二分搜索

# 闭区间写法
def binary_search1(nums, target):
    left, right = 0, len(nums) - 1  # 闭区间 [left, right]
    while left <= right:  # 区间不为空
        # 循环不变量:
        # nums[left-1] < target
        # nums[right+1] >= target
        mid = (left + right) // 2
        if nums[mid] < target:
            left = mid + 1  # 范围缩小到 [mid+1, right]
        else:
            right = mid - 1  # 范围缩小到 [left, mid-1]
    return left

3.冒泡排序

def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
    return arr
 
# 示例使用
array = [64, 34, 25, 12, 22, 11, 90]
sorted_array = bubble_sort(array)
print("Sorted array is:", sorted_array)

4.快速排序

def quicksort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quicksort(left) + middle + quicksort(right)
 
# 示例使用
example_list = [3,6,8,10,1,2,1,4,7,5]
sorted_list = quicksort(example_list)
print(sorted_list)  # 输出: [1, 1, 2, 3, 4, 5, 6, 7, 8, 10]

5.归并排序

def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left = arr[:mid]
    right = arr[mid:]
    left = merge_sort(left)
    right = merge_sort(right)
    return merge(left, right)
 
def merge(left, right):
    result = []
    i, j = 0, 0
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result += left[i:]
    result += right[j:]
    return result
 
# 使用示例
arr = [5, 3, 4, 1, 2]
sorted_arr = merge_sort(arr)
print(sorted_arr)  # 输出: [1, 2, 3, 4, 5]

6.插入排序

def insertion_sort(arr):
    for i in range(len(arr)):
        pre_index = i - 1
        current = arr[i]
        while pre_index >= 0 and arr[pre_index] > current:
            arr[pre_index + 1] = arr[pre_index]
            pre_index -= 1
        arr[pre_index + 1] = current
    return arr
 
# 示例使用
example_list = [10, 5, 3, 8, 2, 6]
sorted_list = insertion_sort(example_list)
print(sorted_list)  # 输出: [2, 3, 5, 6, 8, 10]

7.选择排序

def selection_sort(arr):
    for i in range(len(arr)):
        # 寻找最小元素的索引
        min_idx = i
        for j in range(i+1, len(arr)):
            if arr[j] < arr[min_idx]:
                min_idx = j
        
        # 交换当前元素与找到的最小元素
        arr[i], arr[min_idx] = arr[min_idx], arr[i]
 
# 示例使用选择排序
example_list = [64, 25, 12, 22, 11]
selection_sort(example_list)
print("Sorted array:", example_list)

8.Dijkstra

import heapq
 
def dijkstra(graph, start, end=None):
    if end is None:
        end = max(graph)
    path = {node: [] for node in graph}
    distance = {node: float('inf') for node in graph}
    distance[start] = 0
    visited = set()
 
    q = [(0, start)]
 
    while q:
        _, node = heapq.heappop(q)
        if node not in visited:
            visited.add(node)
            for neighbor, cost in graph[node].items():
                if cost + distance[node] < distance[neighbor]:
                    distance[neighbor] = cost + distance[node]
                    path[neighbor] = path[node] + [neighbor]
                    heapq.heappush(q, (distance[neighbor], neighbor))
 
    return path, distance
 
# 示例图
graph = {
    'A': {'B': 10, 'C': 30},
    'B': {'C': 10, 'D': 20},
    'C': {'D': 40},
    'D': {'E': 10},
    'E': {'F': 20},
    'F': {'D': 10, 'E': 40}
}
 
# 使用函数
path, distance = dijkstra(graph, 'A', 'E')
 
print("Path: ", path)
print("Distance: ", distance)

9.动态规划

def fibonacci_dp(n):
    if n <= 1:
        return n
 
    memo = [0] * (n + 1)  # 创建一个长度为n+1的列表用于存储计算过的值
    memo[1] = 1
 
    for i in range(2, n + 1):
        memo[i] = memo[i - 1] + memo[i - 2]  # 更新子问题的解
 
    return memo[n]  # 返回最终问题的解
 
# 使用示例
n = 10
print(fibonacci_dp(n))  # 输出为55

10.深度优先搜索

graph = {
    'A': ['B', 'C'],
    'B': ['D', 'E'],
    'C': ['F'],
    'D': [],
    'E': ['F'],
    'F': []
}
 
def dfs_recursive(node, visited=None):
    if visited is None:
        visited = set()
    visited.add(node)
    print(node)
    for neighbor in graph[node]:
        if neighbor not in visited:
            dfs_recursive(neighbor, visited)
 
# 从节点'A'开始进行深度优先搜索
dfs_recursive('A')

11.广度优先搜索

from collections import deque
 
def bfs(graph, start, target):
    visited = set()  # 访问过的节点集合
    queue = deque([(start, [start])])  # 使用队列进行BFS搜索
 
    while queue:
        (vertex, path) = queue.popleft()
        if vertex not in visited:
            visited.add(vertex)
            if vertex == target:
                return path
            for neighbor in graph[vertex]:
                if neighbor not in visited:
                    queue.append((neighbor, path + [neighbor]))
    return None
 
# 示例图
graph = {
    'A': ['B', 'C'],
    'B': ['A', 'D', 'E'],
    'C': ['A', 'F'],
    'D': ['B'],
    'E': ['B', 'F'],
    'F': ['C', 'E']
}
 
# 使用BFS搜索从节点'A'到节点'F'的路径
path = bfs(graph, 'A', 'F')
print(path)  # 输出: ['A', 'B', 'E', 'F']

12.最小生成树

import networkx as nx
 
def prim(G, root=None):
    if root is None:
        root = list(G.nodes)[0]
    tree = nx.Graph()
    tree.add_node(root)
    used = {root}
    available = set(G.nodes) - used
    
    while available:
        (u, v), edge_data = min(((u, v), G[u][v]) for u in used for v in available if (u, v) in G.edges)
        available.remove(v)
        used.add(v)
        tree.add_node(v)
        tree.add_edge(u, v, **edge_data)
    
    return tree
 
# 示例:使用以下无向图
edges = [(1, 2, 7), (1, 3, 5), (1, 4, 3), (2, 3, 8), (2, 5, 2),
         (3, 4, 6), (3, 5, 9), (4, 5, 4), (4, 6, 12), (5, 6, 15)]
G = nx.Graph(edges)
 
# 找到最小生成树
min_spanning_tree = prim(G)
 
# 打印最小生成树的边
print(min_spanning_tree.edges(data=True))

13.拓扑排序

from collections import defaultdict
 
def topological_sort(graph):
    # 初始化
    in_degree = {u: 0 for u in graph}
    for u in graph:
        for v in graph[u]:
            in_degree[v] += 1
    
    q = [u for u in graph if in_degree[u] == 0]  # 初始化入度为0的节点
    sorted_order = []
    
    while q:
        u = q.pop()
        sorted_order.append(u)
        for v in graph[u]:
            in_degree[v] -= 1
            if in_degree[v] == 0:
                q.append(v)
    
    if len(sorted_order) != len(graph):
        return None  # 图中有环,不存在拓扑排序
    return sorted_order
 
# 示例使用
graph = defaultdict(list)
graph['A'].append('B')
graph['A'].append('C')
graph['B'].append('D')
graph['C'].append('D')
graph['D'].append('E')
 
sorted_order = topological_sort(graph)
if sorted_order:
    print('拓扑排序:', sorted_order)  # 输出: 拓扑排序: ['A', 'C', 'B', 'D', 'E']
else:
    print('图中有环,不能进行拓扑排序')

14.贪心算法

def greedy_box_packing(items, max_weight):
    """
    使用贪婪算法进行装箱问题求解
    :param items: 物品列表,每个物品是一个元组,包含两个元素:物品的重量和价值
    :param max_weight: 背包的最大重量
    :return: 背包内物品的总价值
    """
    items.sort(key=lambda x: x[1]/x[0], reverse=True)  # 根据单位重量价值排序
    total_value = 0
    current_weight = 0
 
    for weight, value in items:
        if current_weight + weight <= max_weight:  # 当前重量加上物品的重量不超过背包最大重量
            total_value += value
            current_weight += weight
 
    return total_value
 
# 示例使用
items = [(10, 20), (50, 30), (15, 15), (20, 10)]  # 每个元组中,第一个数字是物品的重量,第二个数字是物品的价值
max_weight = 50
print(greedy_box_packing(items, max_weight))  # 输出背包内可以容纳的最大价值

15.递归算法

def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n-1)
 
def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)
 
# 使用方法
print(factorial(5))  # 计算5的阶乘
print(fibonacci(10))  # 计算斐波那契数列第10项的值

16.字符串匹配

def kmp_search(pattern, text):
    # 计算next数组
    next = [0 for _ in range(len(pattern))]
    j = 0
    for i in range(1, len(pattern)):
        while j > 0 and pattern[i] != pattern[j]:
            j = next[j-1]
        if pattern[i] == pattern[j]:
            j += 1
        next[i] = j
    
    # 使用next数组进行匹配
    j = 0
    for i in range(len(text)):
        while j > 0 and text[i] != pattern[j]:
            j = next[j-1]
        if text[i] == pattern[j]:
            j += 1
        if j == len(pattern):
            return i - (j - 1)  # 返回匹配的起始索引
    return -1  # 如果找不到匹配,返回-1
 
# 示例使用
pattern = "ABABD"
text = "BABABCABABCD"
index = kmp_search(pattern, text)
print(f"Pattern found at index {index}")  # 输出匹配的起始索引

17.图像处理

#图像滤波、边缘检测、图像分割
#以下是图像滤波算法
import numpy as np
import cv2
 
def simple_linear_filter(image, kernel_size, sigma=None):
    """
    应用简单线性滤波器
    :param image: 输入图像
    :param kernel_size: 滤波器的大小
    :param sigma: 控制滤波器的标准差,如果为None,则标准差自动计算
    :return: 滤波后的图像
    """
    if sigma is None:
        # 根据核大小自动计算sigma值
        sigma = np.floor(kernel_size / 2)
    
    # 创建滤波器核
    kernel = np.ones((kernel_size, kernel_size), dtype=np.float32)
    
    # 应用高斯滤波作为预处理步骤
    blurred_image = cv2.GaussianBlur(image, (kernel_size, kernel_size), sigma)
    
    # 进行线性滤波
    linear_filtered_image = cv2.filter2D(blurred_image, -1, kernel)
    
    return linear_filtered_image
 
# 读取图像
image = cv2.imread('input_image.jpg')
 
# 应用滤波器
filtered_image = simple_linear_filter(image, 5, sigma=1)
 
# 显示结果
cv2.imshow('Filtered Image', filtered_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

18.哈希

import hashlib
 
def md5_hash(text):
    # 创建一个MD5哈希对象
    md5 = hashlib.md5()
    # 添加要哈希的数据
    md5.update(text.encode('utf-8'))
    # 返回十六进制字符串
    return md5.hexdigest()
 
# 使用函数
text = "Hello, World!"
hash_value = md5_hash(text)
print(hash_value)  # 输出: b10a8db164e0754105b7a99be72e3fe5

19.最大流算法

class MaxFlow:
    def __init__(self, n):
        # 初始化图的节点数和相关属性
        self.n = n
        self.g = [[0 for _ in range(n)] for _ in range(n)]
        self.parent = [None for _ in range(n)]
 
    def add_edge(self, from_node, to_node, capacity):
        # 添加一条边
        self.g[from_node][to_node] = capacity
 
    def max_flow(self, s, t):
        # 找到从s到t的最大流
        flow = 0
        while True:
            self.parent = [None for _ in range(self.n)]
            self.augment = [0 for _ in range(self.n)]
            self.queue = []
            self.queue.append(s)
            self.parent[s] = -1
            found = False
            while self.queue:
                u = self.queue.pop(0)
                if u == t:
                    found = True
                    break
                for v in range(self.n):
                    if self.g[u][v] > 0 and self.parent[v] is None:
                        self.queue.append(v)
                        self.parent[v] = u
            if not found:
                break
            else:
                min_flow = float('Inf')
                for u in range(t, s, -1):
                    min_flow = min(min_flow, self.g[self.parent[u]][u])
                for u in range(t, s, -1):
                    self.g[self.parent[u]][u] -= min_flow
                    self.g[u][self.parent[u]] += min_flow
                flow += min_flow
        return flow
 
# 使用示例
max_flow_instance = MaxFlow(6)  # 创建一个有6个节点的MaxFlow对象
max_flow_instance.add_edge(0, 1, 10)
max_flow_instance.add_edge(0, 2, 10)
max_flow_instance.add_edge(1, 2, 4)
max_flow_instance.add_edge(1, 3, 10)
max_flow_instance.add_edge(2, 4, 10)
max_flow_instance.add_edge(3, 4, 10)
max_flow_instance.add_edge(3, 5, 10)
max_flow_instance.add_edge(4, 5, 9)
max_flow = max_flow_instance.max_flow(0, 5)  # 找到从节点0到节点5的最大流
print(max_flow)  # 输出最大流的值

20.PageRank

import numpy as np
 
def normalize(vector):
    norm = np.linalg.norm(vector)
    if norm == 0:
        return vector
    return vector / norm
 
def calculate_page_rank(graph, damping_factor=0.85, epsilon=1e-5, max_iterations=1000):
    # 初始化PageRank向量,所有节点都有相同的初始排名
    page_rank = np.full(len(graph), 1.0 / len(graph))
    previous_page_rank = np.zeros(len(graph))
 
    for _ in range(max_iterations):
        # 更新每个节点的PageRank值
        for node_index in range(len(graph)):
            contributions = np.array([damping_factor / len(graph[node_index][1]) 
                                      + (1 - damping_factor) * (previous_page_rank[neighbor] / len(graph[neighbor][1])) 
                                      for neighbor in graph[node_index][1]])
            page_rank[node_index] = sum(contributions)
        
        # 如果收敛,则退出循环
        if np.sum(np.abs(page_rank - previous_page_rank)) < epsilon:
            break
        previous_page_rank = page_rank.copy()
 
    return normalize(page_rank)
 
# 示例用法
# 假设graph是一个字典,其中键是节点索引,值是一个元组(出度列表, 入度列表)
# 例如: {0: ([1, 2], [3]), 1: ([3], [0, 2]), ...}
graph = {...}  # 构建你的图结构
page_rank = calculate_page_rank(graph)
 
# 输出PageRank向量
print(page_rank)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值