令人惊艳的高效算法盘点(附示例)

news2024/12/24 22:01:06

令人惊艳的高效算法盘点(附示例)

在计算机科学领域,算法是解决问题的基石。有些算法,因为其高效性和惊人表现,令人瞩目。本文将为你介绍一些令人惊艳的高效算法,让我们一起来领略这些算法的魅力吧!
在这里插入图片描述

1. 快速排序(Quick Sort)

快速排序是一种高效的排序算法,由英国计算机科学家托尼·霍尔(Tony Hoare)于1960年代发明。快速排序使用分治策略(Divide-and-Conquer),将一个大的问题分解成若干个小问题来解决。其主要步骤如下:

  1. 选择基准元素(Pivot)。
  2. 将数组中的元素分为两部分,一部分是小于基准元素的,另一部分是大于基准元素的。
  3. 对两个子数组分别进行快速排序。
  4. 合并排序后的子数组。

快速排序的平均时间复杂度为O(n*log(n)),在实际应用中表现优异。它不需要额外的存储空间,因此在空间复杂度方面也表现出色。

这是一个快速排序的Python演示:

def quick_sort(arr):
    """
    快速排序函数
    :param arr: 待排序数组
    :return: 排序后的数组
    """
    if len(arr) < 2:
        return arr

    pivot = arr[0]  # 取第一个元素作为基准值
    left = [i for i in arr[1:] if i <= pivot]  # 找出小于等于基准值的元素
    right = [i for i in arr[1:] if i > pivot]  # 找出大于基准值的元素

    return quick_sort(left) + [pivot] + quick_sort(right)  # 递归调用并合并结果


# 测试
arr = [3, 5, 4, 2, 1]
sorted_arr = quick_sort(arr)
print(sorted_arr)  # 输出 [1, 2, 3, 4, 5]

在快速排序中,我们选择一个基准值(通常是数组的第一个元素),将数组分为两部分,左边的元素都小于等于基准值,右边的元素都大于基准值。然后递归地对左右两部分进行排序,最终合并起来就得到了排序后的数组。

2. 归并排序(Merge Sort)

归并排序是另一种高效的排序算法,由约翰·冯·诺依曼(John von Neumann)于1945年发明。归并排序同样采用分治策略。其主要步骤如下:

  1. 将数组分成两个相等的子数组。
  2. 对子数组进行归并排序。
  3. 将排序后的子数组合并成一个有序数组。

归并排序的时间复杂度为O(n*log(n)),与快速排序相同。不过,归并排序需要额外的存储空间,空间复杂度为O(n)。

这是一个归并排序的Python演示:

def merge_sort(arr):
    """
    归并排序函数
    :param arr: 待排序数组
    :return: 排序后的数组
    """
    if len(arr) < 2:
        return arr

    mid = len(arr) // 2  # 找到数组中间的位置
    left_arr = arr[:mid]  # 将数组分为左右两部分
    right_arr = arr[mid:]

    # 递归调用归并排序函数
    left_sorted = merge_sort(left_arr)
    right_sorted = merge_sort(right_arr)

    # 合并两个已排好序的子数组
    sorted_arr = []
    i, j = 0, 0
    while i < len(left_sorted) and j < len(right_sorted):
        if left_sorted[i] <= right_sorted[j]:
            sorted_arr.append(left_sorted[i])
            i += 1
        else:
            sorted_arr.append(right_sorted[j])
            j += 1

    sorted_arr += left_sorted[i:]  # 将剩余的元素加入到已排好序的数组中
    sorted_arr += right_sorted[j:]

    return sorted_arr


# 测试
arr = [3, 5, 4, 2, 1]
sorted_arr = merge_sort(arr)
print(sorted_arr)  # 输出 [1, 2, 3, 4, 5]

在归并排序中,我们将数组递归地划分为两个子数组,直到每个子数组只包含一个元素。然后将相邻的子数组合并并排序。最终,所有子数组都被合并成一个有序的数组。归并排序具有稳定性和适用于链表等数据结构的特点。

3. 动态规划(Dynamic Programming)

动态规划是一种解决优化问题的通用方法,尤其适用于具有重叠子问题和最优子结构的问题。动态规划通过将问题分解为若干个子问题来解决,同时将子问题的答案存储起来,避免了重复计算。

经典的动态规划问题包括背包问题(Knapsack Problem)、最长公共子序列(Longest Common Subsequence)和最短路径问题(Shortest Path Problem)。动态规划在很多领域都有着广泛的应用,例如人工智能、运筹学、生物信息学等。

这是一个动态规划的Python演示。下面以背包问题为例进行演示:

def knapsack(weights, values, capacity):
    """
    动态规划求解背包问题
    :param weights: 物品重量列表
    :param values: 物品价值列表
    :param capacity: 背包容量
    :return: 最大价值和及所选物品的编号列表
    """
    n = len(weights)  # 物品数量
    dp = [[0] * (capacity + 1) for _ in range(n + 1)]  # 创建动态规划表

    for i in range(1, n + 1):
        for j in range(1, capacity + 1):
            if j < weights[i - 1]:  # 当前物品放不进背包
                dp[i][j] = dp[i - 1][j]
            else:  # 可以放进背包,比较放和不放的价值大小,选择最优解
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weights[i - 1]] + values[i - 1])

    # 回溯查找所选物品的编号
    selected_items = []
    j = capacity
    for i in range(n, 0, -1):
        if dp[i][j] > dp[i - 1][j]:
            selected_items.append(i - 1)
            j -= weights[i - 1]

    return dp[n][capacity], selected_items[::-1]


# 测试
weights = [2, 3, 4, 5]
values = [3, 4, 5, 6]
capacity = 8
max_value, selected_items = knapsack(weights, values, capacity)
print(max_value)  # 输出 11
print(selected_items)  # 输出 [0, 2, 3]

在动态规划中,我们将问题分解为一系列子问题,并存储每个子问题的解。然后通过组合这些子问题的解来获得原始问题的解。在背包问题中,我们创建一个二维表,其中行表示物品,列表示容量。我们使用递归公式来填充表格,该公式基于以下两种情况:当前物品可以放入背包或不可放入背包。最后,我们回溯表格以找到所选物品的编号列表。

4. 深度优先搜索(Depth-First Search, DFS)和广度优先搜索(Breadth-First Search, BFS)

深度优先搜索和广度优先搜索是图遍历算法,分别采用栈(Stack)和队列(Queue)作为辅助数据结构。他们的时间复杂度分别为O(V+E),其中V是顶点数,E是边数。

深度优先搜索从图的某一顶点出发,沿着一条路径深入遍历,直至无法继续为止,然后回溯到上一个顶点,继续遍历其他路径。广度优先搜索从图的某一顶点出发,先访问所有相邻的顶点,然后按照访问顺序继续访问下一层的顶点。

这两种算法在图论、人工智能和网络科学等领域有着广泛的应用。

下面是深度优先搜索和广度优先搜索的Python演示。首先是深度优先搜索DFS:

def dfs(graph, start, visited=None):
    """
    深度优先搜索函数
    :param graph: 图的邻接表表示
    :param start: 起始节点
    :param visited: 记录已访问节点的集合
    :return: 从起始节点开始遍历得到的节点序列
    """
    if visited is None:
        visited = set()
    visited.add(start)
    for next_node in graph[start] - visited:
        dfs(graph, next_node, visited)
    return visited


# 测试
graph = {'A': set(['B', 'C']),
         'B': set(['A', 'D', 'E']),
         'C': set(['A', 'F']),
         'D': set(['B']),
         'E': set(['B', 'F']),
         'F': set(['C', 'E'])}
print(dfs(graph, 'A'))

在DFS中,我们递归地访问每个未访问的邻居节点,并将其标记为已访问。当无法访问新的未访问邻居节点时,我们回溯并继续访问其他未访问的节点。最终,我们得到从起始节点开始的遍历路径。

接下来是广度优先搜索BFS:

from collections import deque


def bfs(graph, start):
    """
    广度优先搜索函数
    :param graph: 图的邻接表表示
    :param start: 起始节点
    :return: 从起始节点开始遍历得到的节点序列
    """
    visited, queue = set(), deque([start])
    visited.add(start)
    while queue:
        node = queue.popleft()
        for next_node in graph[node] - visited:
            visited.add(next_node)
            queue.append(next_node)
    return visited


# 测试
graph = {'A': set(['B', 'C']),
         'B': set(['A', 'D', 'E']),
         'C': set(['A', 'F']),
         'D': set(['B']),
         'E': set(['B', 'F']),
         'F': set(['C', 'E'])}
print(bfs(graph, 'A'))

在BFS中,我们使用一个队列来存储当前要访问的节点,并依次访问每个节点的未访问邻居节点。当我们访问新的邻居节点时,我们将其标记为已访问并将其添加到队列中。最终,我们得到从起始节点开始的遍历路径。

5. Dijkstra算法(迪杰斯特拉算法)

Dijkstra算法是一种解决单源最短路径问题的高效算法,由荷兰计算机科学家艾兹格·戴科斯彻(Edsger W. Dijkstra)于1956年发明。Dijkstra算法可以在有向图和无向图中找到从源顶点到所有其他顶点的最短路径。其主要步骤如下:

  1. 初始化距离表,将源顶点的距离设为0,其他顶点的距离设为无穷大。
  2. 从距离表中选择距离最小的未访问顶点。
  3. 更新该顶点的所有相邻顶点的距离。
  4. 重复步骤2和3,直到所有顶点都被访问。

Dijkstra算法的时间复杂度为O(V^2),但使用优先队列(Priority Queue)的实现可以将时间复杂度降低到O(V+E*log(V))。

这是一个Dijkstra算法的Python演示:

import heapq


def dijkstra(graph, start):
    """
    Dijkstra算法函数
    :param graph: 图的邻接表表示
    :param start: 起始节点
    :return: 从起始节点到各个节点的最短路径和距离
    """
    distances = {node: float('inf') for node in graph}  # 初始化距离为无穷大
    distances[start] = 0  # 起始节点到自身的距离为0
    pq = [(0, start)]  # 使用堆来存储当前待处理的节点

    while pq:
        (min_distance, current_node) = heapq.heappop(pq)  # 弹出当前最小距离的节点
        if min_distance > distances[current_node]:  # 如果已经处理过该节点,则跳过
            continue
        for neighbor, weight in graph[current_node].items():
            distance = min_distance + weight  # 计算起始节点到邻居节点的距离
            if distance < distances[neighbor]:  # 如果找到了更短的路径,则更新距离并加入堆中
                distances[neighbor] = distance
                heapq.heappush(pq, (distance, neighbor))

    return distances


# 测试
graph = {'A': {'B': 5, 'C': 1},
         'B': {'A': 5, 'C': 2, 'D': 1},
         'C': {'A': 1, 'B': 2, 'D': 4, 'E': 8},
         'D': {'B': 1, 'C': 4, 'E': 3, 'F': 6},
         'E': {'C': 8, 'D': 3},
         'F': {'D': 6}}
distances = dijkstra(graph, 'A')
print(distances)  # 输出 {'A': 0, 'B': 5, 'C': 1, 'D': 6, 'E': 9, 'F': 12}

在Dijkstra算法中,我们使用一个堆来维护当前待处理的节点,并从中选择距离最小的节点。我们递归地处理每个未访问的邻居节点,在找到从起始节点到目标节点的最短路径后,我们将距离更新为已知最短距离。最终,我们得到从起始节点到各个节点的最短路径和距离。

6. A* 搜索算法(A *Search Algorithm)

A* 搜索算法是一种启发式搜索算法,用于解决路径规划和图搜索问题。A *算法结合了广度优先搜索和深度优先搜索的优点,使用启发式函数(Heuristic Function)来估计从当前顶点到目标顶点的距离,从而减少搜索空间。

A* 算法在游戏编程、人工智能、机器人导航等领域有着广泛的应用。其时间复杂度取决于启发式函数的选择,理想情况下,可以达到O(b *d),其中b是分支因子,d是最优解的深度。

这是一个A*搜索算法的Python演示:

import heapq

def heuristic(node, goal):
    """
    估价函数,返回当前节点到目标节点的曼哈顿距离
    :param node: 当前节点
    :param goal: 目标节点
    :return: 曼哈顿距离
    """
    (x1, y1) = node
    (x2, y2) = goal
    return abs(x1 - x2) + abs(y1 - y2)


def a_star(graph, start, goal):
    """
    A*搜索算法函数
    :param graph: 迷宫地图
    :param start: 起始节点
    :param goal: 目标节点
    :return: 路径和距离
    """
    frontier = [(heuristic(start, goal), start)]  # 使用堆来存储当前待处理的节点队列
    visited = set()  # 记录已访问过的节点
    distance = {start: 0}  # 记录起始节点到当前节点的距离
    parent = {start: None}  # 记录每个节点的父节点

    while frontier:
        (_, current_node) = heapq.heappop(frontier)
        if current_node == goal:  # 找到目标节点时,回溯路径并计算距离
            path = []
            while current_node is not None:
                path.append(current_node)
                current_node = parent[current_node]
            path.reverse()
            return sum(distance[node] for node in path), path

        visited.add(current_node)
        for neighbor in graph[current_node]:
            if neighbor not in visited:
                distance_to_neighbor = distance[current_node] + 1  # 当前节点到邻居节点的距离为1
                if neighbor not in distance or distance_to_neighbor < distance[neighbor]:
                    distance[neighbor] = distance_to_neighbor
                    priority = distance_to_neighbor + heuristic(neighbor, goal)  # 优先级等于已走步数+曼哈顿距离
                    heapq.heappush(frontier, (priority, neighbor))
                    parent[neighbor] = current_node

    return None


# 测试
graph = {(0, 0): [(0, 1), (1, 0)],
         (0, 1): [(0, 0), (0, 2), (1, 1)],
         (0, 2): [(0, 1), (1, 2)],
         (1, 0): [(0, 0), (1, 1), (2, 0)],
         (1, 1): [(0, 1), (1, 0), (1, 2), (2, 1)],
         (1, 2): [(0, 2), (1, 1), (2, 2)],
         (2, 0): [(1, 0), (2, 1)],
         (2, 1): [(1, 1), (2, 0), (2, 2)],
         (2, 2): [(1, 2), (2, 1)]}
start = (0, 0)
goal = (2, 2)
distance, path = a_star(graph, start, goal)
print(distance)  # 输出 4
print(path)  # 输出 [(0, 0), (1, 0), (1, 1), (1, 2), (2, 2)]

在A*搜索算法中,我们使用一个堆来维护当前待处理的节点,并从中选择优先级最高的节点。我们使用估价函数来估计从当前节点到目标节点的距离,并通过已知的最短路径长度和这个估计值来确定每个节点的优先级。我们递归地处理每个邻居节点,在找到从起始节点到目标节点的最短路径后,回溯路径并计算距离。最终,我们得到从起始节点到目标节点的最短路径和距离。

7. K-Means聚类算法

K-Means是一种无监督学习算法,用于将数据集划分为K个聚类。K-Means算法通过迭代更新质心(Centroid)来最小化每个聚类内部的平方误差和。其主要步骤如下:

  1. 随机选择K个数据点作为初始质心。
  2. 将每个数据点分配到最近的质心所在的聚类。
  3. 更新质心为每个聚类的均值。
  4. 重复步骤2和3,直到质心不再发生变化。

K-Means算法在数据挖掘、图像处理、市场分析等领域有着广泛的应用。其时间复杂度为O(n * I * K),其中n是数据点的数量,I是迭代次数,K是聚类数目。

这是一个K-Means聚类算法的Python演示:

import random


def euclidean_distance(x, y):
    """
    计算两个向量之间的欧几里得距离
    :param x: 向量x
    :param y: 向量y
    :return: 欧几里得距离
    """
    return sum((xi - yi) ** 2 for xi, yi in zip(x, y)) ** 0.5


def kmeans(data, k):
    """
    K-Means聚类算法函数
    :param data: 数据集
    :param k: 聚类个数
    :return: 聚类结果和每个簇的中心点坐标
    """
    # 随机初始化中心点
    centers = random.sample(data, k)
    while True:
        # 初始化k个空簇
        clusters = [[] for _ in range(k)]
        for point in data:
            # 对于每个数据点,计算其到每个中心点的欧几里得距离,并将其归到距离最近的簇中
            distances = [euclidean_distance(point, center) for center in centers]
            nearest_center_index = distances.index(min(distances))
            clusters[nearest_center_index].append(point)

        new_centers = []
        for cluster in clusters:
            if not cluster:
                # 如果某个簇为空,则随机选择一个数据点作为新的中心点
                new_centers.append(random.choice(data))
            else:
                # 计算该簇中所有数据点的平均值,并将其作为新的中心点
                new_centers.append([sum(feature) / len(cluster) for feature in zip(*cluster)])

        # 如果新中心点与旧中心点相同,则结束迭代
        if new_centers == centers:
            break
        else:
            centers = new_centers

    return clusters, centers


# 测试
data = [[1, 2], [3, 4], [7, 8], [9, 10], [11, 12], [13, 14]]
k = 2
clusters, centers = kmeans(data, k)
print(clusters)  # 输出 [[(1, 2), (3, 4)], [(7, 8), (9, 10), (11, 12), (13, 14)]]
print(centers)  # 输出 [[2.0, 3.0], [10.0, 11.0]]

在K-Means聚类算法中,我们首先随机初始化k个中心点。然后对于每个数据点,计算其到所有中心点的欧几里得距离,并将其归到距离最近的簇中。接着,计算每个簇中所有数据点的平均值,并将其作为该簇的新中心点。重复以上步骤,直到新中心点与旧中心点相同,算法结束。最终,我们得到了k个簇以及每个簇的中心点坐标。

以上仅列举了部分令人惊艳的高效算法,计算机科学领域还有许多其他值得关注的算法。这些算法为我们解决实际问题提供了强大的工具,让我们对计算机科学的发展充满信心。希望这篇博客能激发你对算法的兴趣,鼓励你深入学习,并在实践中应用这些算法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/615137.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cesium 热力图

var points []; var width 600; var height 400; var max 100; // 热力图经纬度范围 var latMin 28.364807; var latMax 40.251095; var lonMin 94.389228; var lonMax 108.666357; // 根据热力图图片范围&#xff0c;生成随机热力点和强度值 for (var i 0; i < 30…

淘宝618每日一猜6月6日答案-甄嬛在横店哪里参加的选秀?

淘宝6月6日每日一猜答案是什么&#xff1f;&#xff0c;接下来也会给大家来介绍一下6月6日淘宝大赢家每日一猜的答案。 淘宝每日一猜6月6日答案分享 活动问题&#xff1a;甄嬛在横店哪里参加的选秀 活动答案&#xff1a;【交泰殿】 还有打开手机淘宝&#xff0c;搜索“能省就…

2.MySQL数据库基础

文章目录 &#x1f4e4;1. 数据库的操作&#x1f4e4;&#x1f431;1.1 查看(显示)当前的数据库&#x1f431;&#x1f436;1.2 创建数据库&#x1f436;&#x1f42d;1.3 使用(选中)数据库&#x1f42d;&#x1f439;1.4 删除数据库&#x1f439; ✉️2. 常用数据类型✉️&…

【电能质量扰动】基于ML和DWT的电能质量扰动分类方法研究(Matlab实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

团队管理之性能实施团队日志7

从具体技术问题看流程和管理的问题 今天上午9&#xff1a;38在微信群里看到团队内做脚本调试的同事小w和一个开发的对话。 是说发了一个报文&#xff0c;结果失败了。于是就问这个项目组A的开发小a&#xff0c;小a一看&#xff0c;这不是项目组B的错吗&#xff1f; 这时是10&a…

java4.5 掌握Spring Boot多环境配置

一、使用Profile文件进行多环境配置 &#xff08;一&#xff09;创建Spring Boot项目 &#xff08;二&#xff09;创建多环境配置文件 1、全局配置文件改名 2、模拟开发环境 在resources里创建配置文件 - application-dev.yaml 3、模拟测试环境 在resources里创建配置文件…

chatgpt赋能python:Python中的填充(Padding)

Python中的填充&#xff08;Padding&#xff09; 在Python编程中&#xff0c;填充&#xff08;Padding&#xff09;是一种常用的技术。填充通常用于将字符串、列表或其他类型的数据添加到另一个数据结构中&#xff0c;以达到特定的格式或长度。本文将介绍如何在Python中使用填…

leetcode652. 寻找重复的子树(java)

寻找重复的子树 leetcode652. 寻找重复的子树题目描述 解题思路代码演示二叉搜索树专题 leetcode652. 寻找重复的子树 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/find-duplicate-subtrees 题目描述 给你一棵二叉树的…

关于nginx使用中的bug

一&#xff1a; 报错&#xff1a;nginx: [emerg] WSASocketW() failed (10022: An invalid argumentwas supplied) 像使用WinSCP一样进行项目部署&#xff0c;把自己的电脑当做服务器放前端压缩包dist&#xff0c;让内网-局域网内所有人可访问前端页面 首先把nginx的文件夹放…

【5种灵活有效方式】如何从死机手机中恢复内部数据?

我的手机掉在地上&#xff0c;现在无法开机。我丢失了所有联系人、图片和重要文件。无奈之下&#xff0c;我需要恢复数据。但是如何从死机中恢复内部数据呢&#xff1f; 我们使用移动设备的最重要原因之一是打电话和发送消息。但有时&#xff0c;我们使用相同的设备来保存记忆…

【剑指offer专项突破版】数组篇——‘‘C‘‘

文章目录 前言一 . 排序数组中两个数字的和题目分析思路分析法①代码——双指针法②代码——二分查找 二. 数组中和为 0 的三个数题目分析问题转换代码 三. 和大于等于 target 的最短子数组题目分析思路分析代码 四. 乘积小于 K 的子数组题目分析思路分析代码 五. 和为 k 的子数…

如何用知识星球年入50万

使用知识星球年入50万的话&#xff0c;那么你的社群收费必须超过60万&#xff0c;因为星球会有20%的手续费。 年入50万并不是一笔小数目&#xff0c;那么一定少不了优质的内容以及引流渠道&#xff0c;这二者缺一不可。 优质的内容和引流的渠道都需要题主自己去把控&#xff…

阿里云OpenSearch重磅推出LLM问答式搜索产品,助力企业高效构建对话式搜索服务

阿里云OpenSearch重磅推出LLM智能问答版&#xff0c;面向行业搜索场景&#xff0c;提供企业专属问答搜索服务。 智能问答版基于内置的LLM大模型提供问答能力&#xff0c;一站式快速搭建问答搜索系统。 目前OpenSearch LLM智能问答版已开始邀测&#xff08;https://page.aliyu…

卡尔曼滤波与组合导航原理(六)信息Kalman滤波与信息融合

文章目录 一、信息滤波1、模型2、信息滤波公式改写3、IKF公式汇总4、KF与IKF的对偶关系 二、信息融合1、信息融合方法2、信息融合推导Kalman滤波 一、信息滤波 1、模型 函数模型 { X k Φ k / k − 1 X k − 1 Γ k − 1 W k − 1 Z k H k X k V k \left\{\begin{array}…

djangoo配置与运行

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

【UEFI】BIOS 阶段全局变量类型

BIOS的几个阶段需要不同阶段的数据传递&#xff0c;下面介绍4个全局变量。 1 固件存储介绍 本规范描述了应该如何在非易失性存储器中存储和访问文件。固件实现必须支持标准的PI固件卷和固件文件系统格式&#xff08;下文所述&#xff09;&#xff0c;但可能支持其他存储格式。…

【网页布局形式----浮动】

网页布局形式----浮动 css浮动&#xff1a;一、常见的三种网页布局形式&#xff1a;1.1 网页布局两大准则&#xff1a; 二 、浮动&#xff1a;2.1 浮动语法&#xff1a;2.2 浮动特性&#xff08;重难点&#xff09;&#xff1a;浮动元素通常与标准流的父级元素搭配使用&#xf…

Linux进程虚拟地址空间

文章目录 1. 进程地址空间1.1 存在1.2 初步了解1.2 虚拟地址空间的划分1.3 页表 2. 虚拟地址如何转化成物理地址2.1 二级页表2.2 总结 3. 写时拷贝3.1 原理3.2 解释为什么 pid_t ret fork() 中&#xff0c;ret 会有两个不同的值 4. 为何需要虚拟地址空间 1. 进程地址空间 1.1…

基于python的企业资产管理系统vue+django+flask

开发语言&#xff1a;Python 框架&#xff1a;django/flask Python版本&#xff1a;python3.7.7 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;PyCharm 文章介绍了企业资产管理系统的系统分析部分&#xff0c;包括可行性分析等&#xff0c;系…

基于SpringBoot的CRM客户管理销售团队管理系统(含源码+数据库)

1&#xff09;环境准备 JDK 1.8 以上 MySql 5.7 以上 Tomcat 7.0 以上 maven 3.5.0 Idea 2&#xff09;建立PowerTeam数据库 打开Mysql管理工具(推荐使用Navicat Premium) 执行db.sql脚本 可选操作执行demo_data.sql演示数据脚本 3)将项目导入Idea开发工具中 ​4&#xff09;修…