【金九银十】笔试通关 + 小学生都能学会的快速排序
        【摘要】 快速排序(Quick Sort)是一种高效的排序算法,采用分治法(Divide and Conquer)策略来对数组进行排序。它的核心思想是通过一趟排序将待排序的数组分成两部分,其中一部分的所有元素比另一部分的所有元素都要小,然后递归地对这两部分分别进行快速排序,直到整个序列有序。
    
    
    
    算法原理
快速排序(Quick Sort)是一种高效的排序算法,采用分治法(Divide and Conquer)策略来对数组进行排序。它的核心思想是通过一趟排序将待排序的数组分成两部分,其中一部分的所有元素比另一部分的所有元素都要小,然后递归地对这两部分分别进行快速排序,直到整个序列有序。
步骤如下
- 选择基准(Pivot): 从数组中选择一个元素作为基准(通常选择第一个元素、最后一个元素或中间元素)。
 - 分区(Partition): 将数组重新排列,所有小于基准的元素放在基准的左边,所有大于基准的元素放在基准的右边。
 - 递归排序: 对基准左边的子数组和右边的子数组分别进行快速排序。
 - 组合结果: 递归结束后,整个数组就已经排好序。
 
实例分析
假设我们要对以下数组进行快速排序:
[3, 6, 8, 10, 1, 2, 1]
步骤如下:
- 选择基准: 选择第一个元素 
3作为基准。 - 分区: 重新排列数组,使得比 
3小的元素在其左边,比3大的元素在其右边。结果可能是[1, 2, 1, 3, 6, 8, 10]。 - 递归排序: 现在对 
[1, 2, 1]和[6, 8, 10]分别进行快速排序。 - 对 
[1, 2, 1]选择1作为基准,重新排列得到[1, 1, 2]。 - 对 
[6, 8, 10]选择6作为基准,重新排列得到[6, 8, 10]。 - 组合结果: 最终结果为 
[1, 1, 2, 3, 6, 8, 10]。 

动态实现
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Quick Sort Visualization</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4;
            margin: 0;
            padding: 20px;
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        h2 {
            color: #333;
            margin-bottom: 20px;
        }
        #array-container {
            display: flex;
            justify-content: center;
            align-items: flex-end;
            height: 300px;
            margin-bottom: 20px;
            border: 1px solid #ccc;
            background-color: #fff;
            padding: 30px;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
        }
        .array-bar {
            display: flex;
            justify-content: center;
            align-items: flex-end;
            margin: 0 2px;
            background-color: teal;
            border-radius: 4px;
            position: relative;
            transition: height 0.3s;
        }
        .array-bar p {
            margin: 0;
            color: rgb(228, 28, 28);
            font-weight: bold;
            font-size: 14px;
            position: absolute;
            bottom: -20px;
        }
        button {
            padding: 10px 20px;
            font-size: 16px;
            color: #fff;
            background-color: teal;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.3s;
        }
        button:hover {
            background-color: #005f5f;
        }
    </style>
</head>
<body>
    <h2>Quick Sort Visualization</h2>
    <div id="array-container"></div>
    <button onclick="quickSort(array, 0, array.length - 1)">Start Quick Sort</button>
    <script>
        // Initial Array
        let array = [3, 6, 8, 10, 1, 2, 1];
        const container = document.getElementById("array-container");
        // Function to create bars for visualization
        function createBars(array) {
            container.innerHTML = '';
            for (let i = 0; i < array.length; i++) {
                const bar = document.createElement('div');
                bar.className = 'array-bar';
                bar.style.height = `${array[i] * 20}px`;
                bar.style.width = '40px';
                const number = document.createElement('p');
                number.textContent = array[i];
                bar.appendChild(number);
                container.appendChild(bar);
            }
        }
        // Quick Sort Implementation
        async function quickSort(arr, low, high) {
            if (low < high) {
                let pi = await partition(arr, low, high);
                await quickSort(arr, low, pi - 1);
                await quickSort(arr, pi + 1, high);
            }
            createBars(arr);
        }
        async function partition(arr, low, high) {
            let pivot = arr[high];
            let i = low - 1;
            for (let j = low; j < high; j++) {
                if (arr[j] < pivot) {
                    i++;
                    [arr[i], arr[j]] = [arr[j], arr[i]];
                    createBars(arr);
                    await new Promise(resolve => setTimeout(resolve, 300));
                }
            }
            [arr[i + 1], arr[high]] = [arr[high], arr[i + 1]];
            createBars(arr);
            await new Promise(resolve => setTimeout(resolve, 300));
            return i + 1;
        }
        // Initialize bars
        createBars(array);
    </script>
</body>
</html>

代码分析
async function quickSort(arr, low, high) {
    if (low < high) {
        let pi = await partition(arr, low, high);
        await quickSort(arr, low, pi - 1);
        await quickSort(arr, pi + 1, high);
    }
    createBars(arr);
}
quickSort(arr, low, high) 函数
参数说明:
- `arr`: 需要排序的数组。
- `low`: 数组的起始索引(即子数组的第一个元素的索引)。
- `high`: 数组的结束索引(即子数组的最后一个元素的索引)。功能:这是快速排序的主函数,使用递归方法对数组进行排序。首先判断 low 是否小于 high,以确保子数组至少有两个元素需要排序。如果 low >= high,则函数返回,不进行任何操作。核心逻辑:let pi = await partition(arr, low, high);:调用 partition 函数,将数组 arr 分区,并返回分区点 pi(pivot index)。await quickSort(arr, low, pi - 1);:递归地对分区点 pi 左边的子数组进行排序。await quickSort(arr, pi + 1, high);:递归地对分区点 pi 右边的子数组进行排序。createBars(arr);:每次排序步骤完成后,重新渲染数组,以更新可视化效果。
async function partition(arr, low, high) {
    let pivot = arr[high];
    let i = low - 1;
    for (let j = low; j < high; j++) {
        if (arr[j] < pivot) {
            i++;
            [arr[i], arr[j]] = [arr[j], arr[i]];
            createBars(arr);
            await new Promise(resolve => setTimeout(resolve, 300));
        }
    }
    [arr[i + 1], arr[high]] = [arr[high], arr[i + 1]];
    createBars(arr);
    await new Promise(resolve => setTimeout(resolve, 300));
    return i + 1;
}
partition(arr, low, high) 函数
- 参数说明:
arr: 需要分区的数组。low: 子数组的起始索引。high: 子数组的结束索引。
 - 功能:
- 这是快速排序的核心部分,负责将数组 
arr按基准点pivot分成两个部分:左侧部分小于pivot,右侧部分大于pivot。 
 - 这是快速排序的核心部分,负责将数组 
 - 核心逻辑:
let pivot = arr[high];:选择数组中最后一个元素作为基准点(pivot)。let i = low - 1;:i指向的是比pivot小的元素的最后一个位置。for (let j = low; j < high; j++):遍历数组从low到high-1位置的所有元素。if (arr[j] < pivot):如果当前元素arr[j]小于pivot,则将其与i+1位置的元素交换,并将i加 1。这样就能保证所有小于pivot的元素都移动到左侧。createBars(arr);:每次元素交换后,更新可视化条形图,显示当前排序状态。await new Promise(resolve => setTimeout(resolve, 300));:添加延迟效果,让可视化过程更清晰。
return i + 1;:返回新的基准点索引,将其用于后续递归调用。
 
createBars(array) 函数
function createBars(array) {
    container.innerHTML = '';
    for (let i = 0; i < array.length; i++) {
        const bar = document.createElement('div');
        bar.className = 'array-bar';
        bar.style.height = `${array[i] * 20}px`;
        bar.style.width = '40px';
        const number = document.createElement('p');
        number.textContent = array[i];
        bar.appendChild(number);
        container.appendChild(bar);
    }
}
- 功能:
- 该函数用于根据数组中的元素动态创建对应的条形图,展示数组的排序状态。
 
 - 核心逻辑:
container.innerHTML = '';:清空容器中的现有内容,为新条形图腾出空间。for (let i = 0; i < array.length; i++):遍历数组中的每个元素,为其创建一个条形图。const bar = document.createElement('div');:为数组中的每个元素创建一个div元素,用于表示条形图。bar.style.height =${arrayi * 20}px;:根据数组元素的值设置条形图的高度。const number = document.createElement('p');:创建一个p元素,用于显示条形图下方的数字。bar.appendChild(number);:将数字添加到条形图中。container.appendChild(bar);:将条形图添加到容器中,显示在页面上。
 
通过这些函数的配合,快速排序算法能够不仅高效地对数组进行排序,还能实时地动态展示排序过程,使算法的执行过程更加直观。
            【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
                cloudbbs@huaweicloud.com
                
            
        
        
        
        
        
        
        - 点赞
 - 收藏
 - 关注作者
 
            
           
评论(0)