📅  最后修改于: 2023-12-03 14:49:48.353000             🧑  作者: Mango
快速排序是一种快速、高效的排序算法,常用于大量数据的排序场景中。Hoare分区是快速排序算法的核心思想之一,它实现了将数组划分为两部分的操作,以此实现快速排序。
在本文中,我们将介绍如何使用JavaScript编写Hoare分区的快速排序算法,并通过可视化的方法展示它的执行过程。
快速排序算法的基本思路是选择一个支点(pivot),将数组分成两个部分,其中左边的部分元素值均小于支点,右边的部分元素值均大于支点。然后再对左右两边的数组递归地进行同样的操作,直到数组长度为1。
Hoare分区是一种同时从左右两边遍历数组的分区方式,它的核心思想是将数组分成两部分时不进行数据交换,而是通过左右指针的移动实现。
下面是使用JavaScript实现Hoare分区的快速排序算法的代码:
function quickSort(items, left, right) {
var index;
if (items.length > 1) {
index = hoarePartition(items, left, right);
if (left < index - 1) {
quickSort(items, left, index - 1);
}
if (index < right) {
quickSort(items, index, right);
}
}
return items;
}
function hoarePartition(items, left, right) {
var pivot = items[Math.floor((right + left) / 2)],
i = left,
j = right;
while (i <= j) {
while (items[i] < pivot) {
i++;
}
while (items[j] > pivot) {
j--;
}
if (i <= j) {
swap(items, i, j);
i++;
j--;
}
}
return i;
}
function swap(items, leftIndex, rightIndex) {
var temp = items[leftIndex];
items[leftIndex] = items[rightIndex];
items[rightIndex] = temp;
}
函数quickSort
是快速排序算法的主函数,它接受三个参数:待排序的数组、数组的左侧索引和右侧索引。在quickSort
函数中,我们首先选择数组中的支点,然后通过hoarePartition
函数对数组进行划分,最后对划分后的左右两部分递归调用quickSort
函数,直到数组长度为1。
函数hoarePartition
是Hoare分区的核心函数,它接受三个参数:待分区的数组、数组的左侧索引和右侧索引。在hoarePartition
函数中,我们以支点的值为界限,从数组两端同时开始遍历,如果发现左侧元素大于支点,右侧元素小于支点,则交换这两个元素的位置,重复这个过程直到左右两端都结束遍历。
函数swap
是用来交换数组中两个元素的位置的。
为了让读者更好地理解快速排序算法的执行过程,我们可以通过可视化的方式展示它的执行过程。下面是使用JavaScript和HTML/CSS实现的一个简单的快速排序算法的可视化示例:
<!DOCTYPE html>
<html>
<head>
<title>Quick Sort Visualization</title>
<style type="text/css">
#container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.bar {
height: 30px;
margin: 0 1px;
background-color: gray;
transition: height 0.2s;
}
</style>
</head>
<body>
<button onclick="startVisualization()">Start Visualization</button>
<button onclick="reset()">Reset</button>
<div id="container"></div>
<script type="text/javascript">
var numbers = [];
var barContainer = document.getElementById("container");
var bars = [];
var delay = 100;
function startVisualization() {
reset();
var input = document.createElement("input");
var sortButton = document.createElement("button");
input.type = "number";
input.value = 20;
sortButton.textContent = "Sort";
sortButton.onclick = function() {
var count = parseInt(input.value);
generateRandomNumbers(count);
drawBars();
quickSort(numbers, 0, numbers.length - 1);
};
barContainer.insertBefore(input, barContainer.firstChild);
barContainer.insertBefore(sortButton, barContainer.firstChild);
}
function reset() {
numbers = [];
barContainer.innerHTML = "";
bars = [];
}
function generateRandomNumbers(count) {
numbers = [];
for (var i = 0; i < count; i++) {
numbers.push(Math.round(Math.random() * 100));
}
}
function drawBars() {
for (var i = 0; i < numbers.length; i++) {
var bar = document.createElement("div");
bar.className = "bar";
bar.style.width = (100 / numbers.length) + "%";
bar.style.height = (numbers[i] * 3) + "px";
bars.push(bar);
barContainer.appendChild(bar);
}
}
function quickSort(items, left, right) {
var index;
if (items.length > 1) {
index = hoarePartition(items, left, right);
for (var i = 0; i < items.length; i++) {
bars[i].style.height = (items[i] * 3) + "px";
bars[i].style.backgroundColor = "gray";
}
setTimeout(function() {
bars[index].style.backgroundColor = "green";
if (left < index - 1) {
quickSort(items, left, index - 1);
}
if (index < right) {
quickSort(items, index, right);
}
}, delay);
}
return items;
}
function hoarePartition(items, left, right) {
var pivot = items[Math.floor((right + left) / 2)],
i = left,
j = right;
while (i <= j) {
while (items[i] < pivot) {
i++;
}
while (items[j] > pivot) {
j--;
}
if (i <= j) {
swap(items, i, j);
swapBars(i, j);
i++;
j--;
}
}
return i;
}
function swap(items, leftIndex, rightIndex) {
var temp = items[leftIndex];
items[leftIndex] = items[rightIndex];
items[rightIndex] = temp;
}
function swapBars(leftIndex, rightIndex) {
var temp = bars[leftIndex].style.height;
bars[leftIndex].style.height = bars[rightIndex].style.height;
bars[leftIndex].style.backgroundColor = "red";
bars[rightIndex].style.height = temp;
bars[rightIndex].style.backgroundColor = "red";
}
</script>
</body>
</html>
我们首先在页面中添加了两个按钮:一个用来开始可视化,一个用来重置可视化。在点击开始可视化按钮时,会动态添加一个输入框和一个排序按钮,用来输入数组长度和开始排序。
在quickSort
函数中,我们在每次进行Hoare分区操作前,将当前数组的元素值和可视化元素的高度进行同步。然后,我们使用setTimeout
函数来模拟算法的执行过程,以便让用户能够观察到算法的过程。
在swapBars
函数中,我们用来交换可视化元素的高度和背景色。
为了更好地演示算法的过程,我们将可视化元素的背景色设置为灰色,当某个元素从数组中被选中时,将其背景色变为绿色,当其位置确定后,将其背景色变为红色。
在本文中,我们介绍了如何使用JavaScript编写Hoare分区的快速排序算法,并通过可视化的方式展示了它的执行过程。这种方法可以帮助读者更好地理解算法的思想、实现和执行过程。希望读者能够在日常开发中运用这种算法,提高程序的效率。