GUI(图形用户界面)比程序更能帮助您理解。在本文中,我们将使用JavaScript可视化“快速排序”。我们将看到如何使用Lomuto分区对数组进行分区,然后如何获得最终排序的数组。我们还将可视化快速排序的时间复杂度。
参考:
- 快速排序
- Lomuto分区
- JavaScript中的异步函数
方法:
- 首先,我们将使用Math.random()函数生成一个随机数组。
- 不同的颜色用于指示比较哪个元素,左分区,右分区和数据透视元素。
- 由于该算法执行操作非常快,因此已使用setTimeout()函数来减慢该过程。
- 可以通过按“ Ctrl + R”键来生成新数组。
- 使用快速排序()函数使用lometo_partition进行排序()函数
例子:
下面是可视化快速排序算法的程序。
index.html
Quick Sort (Lometo Partition)
style.css
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
.header {
font-size: 20px;
text-align: center;
}
#array {
background-color: white;
height: 278px;
width: 598px;
margin: auto;
position: relative;
margin-top: 64px;
}
.block {
width: 28px;
background-color: #6b5b95;
position: absolute;
bottom: 0px;
transition: 0.2s all ease;
}
.block_id {
position: absolute;
color: black;
margin-top: -20px;
width: 100%;
text-align: center;
}
.block_id2 {
position: absolute;
color: black;
margin-top: 22px;
width: 100%;
text-align: center;
}
.block2 {
width: 28px;
background-color: darkgray;
position: absolute;
transition: 0.2s all ease;
}
.block_id3 {
position: absolute;
color: black;
margin-top: 1px;
width: 100%;
text-align: center;
}
#count {
height: 20px;
width: 598px;
margin: auto;
}
script.js
var container = document.getElementById("array");
// Function to generate the array of blocks
function generatearray() {
for (var i = 0; i < 20; i++) {
// Return a value from 1 to 100 (both inclusive)
var value = Math.ceil(Math.random() * 100);
// Creating element div
var array_ele = document.createElement("div");
// Adding class 'block' to div
array_ele.classList.add("block");
// Adding style to div
array_ele.style.height = `${value * 3}px`;
array_ele.style.transform = `translate(${i * 30}px)`;
// Creating label element for displaying
// size of particular block
var array_ele_label =
document.createElement("label");
array_ele_label.classList.add("block_id");
array_ele_label.innerText = value;
// Appending created elements to index.html
array_ele.appendChild(array_ele_label);
container.appendChild(array_ele);
}
}
// Function to generate indexes
var count_container =
document.getElementById("count");
function generate_idx() {
for (var i = 0; i < 20; i++) {
// Creating element div
var array_ele2 = document.createElement("div");
// Adding class 'block2' to div
array_ele2.classList.add("block2");
// Adding style to div
array_ele2.style.height = `${20}px`;
array_ele2.style.transform = `translate(${i * 30}px)`;
// Adding indexes
var array_ele_label2 =
document.createElement("label");
array_ele_label2.classList.add("block_id3");
array_ele_label2.innerText = i;
// Appending created elements to index.html
array_ele2.appendChild(array_ele_label2);
count_container.appendChild(array_ele2);
}
}
async function lometo_partition(l, r, delay = 700) {
var blocks = document.querySelectorAll(".block");
// Storing the value of pivot element
var pivot =
Number(blocks[r].childNodes[0].innerHTML);
var i = l - 1;
blocks[r].style.backgroundColor = "red";
document.
getElementsByClassName("range")[0].innerText = `[${l},${r}]`;
for (var j = l; j <= r - 1; j++) {
// To change background-color of the
// blocks to be compared
blocks[j].style.backgroundColor = "yellow";
// To wait for 700 milliseconds
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, delay)
);
var value =
Number(blocks[j].childNodes[0].innerHTML);
// To compare value of two blocks
if (value < pivot) {
i++;
var temp1 = blocks[i].style.height;
var temp2 = blocks[i].childNodes[0].innerText;
blocks[i].style.height = blocks[j].style.height;
blocks[j].style.height = temp1;
blocks[i].childNodes[0].innerText =
blocks[j].childNodes[0].innerText;
blocks[j].childNodes[0].innerText = temp2;
blocks[i].style.backgroundColor = "orange";
if (i != j) blocks[j].style.backgroundColor = "pink";
//To wait for 700 milliseconds
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, delay)
);
} else blocks[j].style.backgroundColor = "pink";
}
// Swapping the ith with pivot element
i++;
var temp1 = blocks[i].style.height;
var temp2 = blocks[i].childNodes[0].innerText;
blocks[i].style.height = blocks[r].style.height;
blocks[r].style.height = temp1;
blocks[i].childNodes[0].innerText =
blocks[r].childNodes[0].innerText;
blocks[r].childNodes[0].innerText = temp2;
blocks[r].style.backgroundColor = "pink";
blocks[i].style.backgroundColor = "green";
// To wait for 2100 milliseconds
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, delay * 3)
);
document.getElementsByClassName("range")[0].innerText = "";
for (var k = 0; k < 20; k++)
blocks[k].style.backgroundColor = "#6b5b95";
return i;
}
// Asynchronous QuickSort function
async function QuickSort(l, r, delay = 100) {
if (l < r) {
// Storing the index of pivot element after partition
var pivot_idx = await lometo_partition(l, r);
// Recursively calling quicksort for left partition
await QuickSort(l, pivot_idx - 1);
// Recursively calling quicksort for right partition
await QuickSort(pivot_idx + 1, r);
}
}
// Calling generatearray function
generatearray();
// Calling generate_idx function
generate_idx();
// Calling QuickSort function
QuickSort(0, 19);
style.css
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
.header {
font-size: 20px;
text-align: center;
}
#array {
background-color: white;
height: 278px;
width: 598px;
margin: auto;
position: relative;
margin-top: 64px;
}
.block {
width: 28px;
background-color: #6b5b95;
position: absolute;
bottom: 0px;
transition: 0.2s all ease;
}
.block_id {
position: absolute;
color: black;
margin-top: -20px;
width: 100%;
text-align: center;
}
.block_id2 {
position: absolute;
color: black;
margin-top: 22px;
width: 100%;
text-align: center;
}
.block2 {
width: 28px;
background-color: darkgray;
position: absolute;
transition: 0.2s all ease;
}
.block_id3 {
position: absolute;
color: black;
margin-top: 1px;
width: 100%;
text-align: center;
}
#count {
height: 20px;
width: 598px;
margin: auto;
}
script.js
var container = document.getElementById("array");
// Function to generate the array of blocks
function generatearray() {
for (var i = 0; i < 20; i++) {
// Return a value from 1 to 100 (both inclusive)
var value = Math.ceil(Math.random() * 100);
// Creating element div
var array_ele = document.createElement("div");
// Adding class 'block' to div
array_ele.classList.add("block");
// Adding style to div
array_ele.style.height = `${value * 3}px`;
array_ele.style.transform = `translate(${i * 30}px)`;
// Creating label element for displaying
// size of particular block
var array_ele_label =
document.createElement("label");
array_ele_label.classList.add("block_id");
array_ele_label.innerText = value;
// Appending created elements to index.html
array_ele.appendChild(array_ele_label);
container.appendChild(array_ele);
}
}
// Function to generate indexes
var count_container =
document.getElementById("count");
function generate_idx() {
for (var i = 0; i < 20; i++) {
// Creating element div
var array_ele2 = document.createElement("div");
// Adding class 'block2' to div
array_ele2.classList.add("block2");
// Adding style to div
array_ele2.style.height = `${20}px`;
array_ele2.style.transform = `translate(${i * 30}px)`;
// Adding indexes
var array_ele_label2 =
document.createElement("label");
array_ele_label2.classList.add("block_id3");
array_ele_label2.innerText = i;
// Appending created elements to index.html
array_ele2.appendChild(array_ele_label2);
count_container.appendChild(array_ele2);
}
}
async function lometo_partition(l, r, delay = 700) {
var blocks = document.querySelectorAll(".block");
// Storing the value of pivot element
var pivot =
Number(blocks[r].childNodes[0].innerHTML);
var i = l - 1;
blocks[r].style.backgroundColor = "red";
document.
getElementsByClassName("range")[0].innerText = `[${l},${r}]`;
for (var j = l; j <= r - 1; j++) {
// To change background-color of the
// blocks to be compared
blocks[j].style.backgroundColor = "yellow";
// To wait for 700 milliseconds
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, delay)
);
var value =
Number(blocks[j].childNodes[0].innerHTML);
// To compare value of two blocks
if (value < pivot) {
i++;
var temp1 = blocks[i].style.height;
var temp2 = blocks[i].childNodes[0].innerText;
blocks[i].style.height = blocks[j].style.height;
blocks[j].style.height = temp1;
blocks[i].childNodes[0].innerText =
blocks[j].childNodes[0].innerText;
blocks[j].childNodes[0].innerText = temp2;
blocks[i].style.backgroundColor = "orange";
if (i != j) blocks[j].style.backgroundColor = "pink";
//To wait for 700 milliseconds
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, delay)
);
} else blocks[j].style.backgroundColor = "pink";
}
// Swapping the ith with pivot element
i++;
var temp1 = blocks[i].style.height;
var temp2 = blocks[i].childNodes[0].innerText;
blocks[i].style.height = blocks[r].style.height;
blocks[r].style.height = temp1;
blocks[i].childNodes[0].innerText =
blocks[r].childNodes[0].innerText;
blocks[r].childNodes[0].innerText = temp2;
blocks[r].style.backgroundColor = "pink";
blocks[i].style.backgroundColor = "green";
// To wait for 2100 milliseconds
await new Promise((resolve) =>
setTimeout(() => {
resolve();
}, delay * 3)
);
document.getElementsByClassName("range")[0].innerText = "";
for (var k = 0; k < 20; k++)
blocks[k].style.backgroundColor = "#6b5b95";
return i;
}
// Asynchronous QuickSort function
async function QuickSort(l, r, delay = 100) {
if (l < r) {
// Storing the index of pivot element after partition
var pivot_idx = await lometo_partition(l, r);
// Recursively calling quicksort for left partition
await QuickSort(l, pivot_idx - 1);
// Recursively calling quicksort for right partition
await QuickSort(pivot_idx + 1, r);
}
}
// Calling generatearray function
generatearray();
// Calling generate_idx function
generate_idx();
// Calling QuickSort function
QuickSort(0, 19);
输出: