📜  在JavaScript中合并排序可视化

📅  最后修改于: 2021-04-17 17:21:59             🧑  作者: Mango

GUI(图形用户界面)可帮助用户更好地理解程序。在本文中,我们将使用JavaScript可视化合并排序。我们将看到排序后如何拆分和合并数组以获得最终排序后的数组。

参考:

  • 合并排序
  • HTML中的画布
  • JavaScript中的异步函数

方法:

  • 首先,我们将使用数学生成随机数组。 random()函数。
  • 画布的属性用于制作矩形栏和动画。
  • 不同的颜色用于指示哪些数组被分割和合并。
  • 使用JavaScript mergeSort()函数执行排序。
  • 该算法执行操作非常快,已使用timeout()函数来减慢该过程。

未排序清单:

排序列表:

index.html:以下是可视化“合并排序”算法的程序。

HTML


  

    
        

  

    

        Merge Sort Visualizer using JS

       

Array is not sorted      

                        


Javascript
// Canvas variables
var canvas, canvaswidth, canvasheight, ctrl;
  
// Call canvasElements() to store height width
// in above canvas variables
canvasElements();
  
// 3 array are declared
  
//1) arr is for storing array element 
//2) itmd for storing intermediate values
//3) visited is for element which has been sorted
var arr = [], itmd = [], visited = []
  
  
// Length of unsorted array
var len_of_arr = 40;
  
// Store random value in arr[]
for (var i = 0; i < len_of_arr; i++) {
    arr.push(Math.round(Math.random() * 250) )
}
  
// Initialize itmd and visited array with 0
for (var i = 0; i < len_of_arr; i++) {
    itmd.push(0)
    visited.push(0)
}
  
// Merging of two sub array
// https://www.geeksforgeeks.org/merge-two-sorted-arrays/
function mergeArray(start, end) {
    let mid = parseInt((start + end) >> 1);
    let start1 = start, start2 = mid + 1
    let end1 = mid, end2 = end
      
    // Initial index of merged subarray
    let index = start
  
    while (start1 <= end1 && start2 <= end2) {
        if (arr[start1] <= arr[start2]) {
            itmd[index] = arr[start1]
            index = index + 1
            start1 = start1 + 1;
        }
        else if(arr[start1] > arr[start2]) {
            itmd[index] = arr[start2]
            index = index + 1
            start2 = start2 + 1;
        }
    }
  
    // Copy the remaining elements of
    // arr[], if there are any
    while (start1 <= end1) {
        itmd[index] = arr[start1]
        index = index + 1
        start1 = start1 + 1;
    }
  
    while (start2 <= end2) {
        itmd[index] = arr[start2]
        index = index + 1
        start2 = start2 + 1;
    }
  
    index = start
    while (index <= end) {
        arr[index] = itmd[index];
        index++;
    }
}
  
// Function for showing visualization 
// effect
function drawBars(start, end) {
  
    // Clear pervious unsorted bars
    ctrl.clearRect(0, 0, 1000, 1500)
  
    // Styling of bars
    for (let i = 0; i < len_of_arr; i++) {
  
        // Changing styles of bars
        ctrl.fillStyle = "black"
        ctrl.shadowOffsetX = 2
        ctrl.shadowColor = "chocolate";
        ctrl.shadowBlur = 3;
        ctrl.shadowOffsetY =5;
         
          
        // Size of rectangle of bars
        ctrl.fillRect(25 * i, 300 - arr[i], 20, arr[i])
          
        if (visited[i]) {
            ctrl.fillStyle = "#006d13"
            ctrl.fillRect(25 * i, 300 - arr[i], 20, arr[i])
            ctrl.shadowOffsetX = 2
        }
    }
  
    for (let i = start; i <= end; i++) {
        ctrl.fillStyle = "orange"
        ctrl.fillRect(25 * i, 300 - arr[i], 18, arr[i])
        ctrl.fillStyle = "#cdff6c"
        ctrl.fillRect(25 * i,300, 18, arr[i])
        visited[i] = 1
    }
}
  
// Waiting interval between two bars
function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
  
  
// Merge Sorting
const mergeSort = async (start, end) => {
    if (start < end) {
        let mid = parseInt((start + end) >> 1)
        await mergeSort(start, mid)
        await mergeSort(mid + 1, end)
        await mergeArray(start, end)
        await drawBars(start, end)
  
        // Waiting time is 800ms
        await timeout(800)
    }
}
  
// canvasElements function for storing
// width and height in canvas variable
function canvasElements() {
    canvas = document.getElementById("Canvas")
    canvas.width = canvas.height = 1000
    canvaswidth = canvas.width
    canvasheight = canvas.height
    ctrl = canvas.getContext("2d")
}
  
// Asynchronous MergeSort function 
const performer = async () => {
    await mergeSort(0, len_of_arr - 1)
    await drawBars()
  
    // Code for change title1 text 
    const title1_changer = document.querySelector(".title1")
    title1_changer.innerText = "Array is completely sorted"
}
performer()


mergeSort.js :以下是上述HTML代码中使用的“ mergeSort.js”文件的内容。

Java脚本

// Canvas variables
var canvas, canvaswidth, canvasheight, ctrl;
  
// Call canvasElements() to store height width
// in above canvas variables
canvasElements();
  
// 3 array are declared
  
//1) arr is for storing array element 
//2) itmd for storing intermediate values
//3) visited is for element which has been sorted
var arr = [], itmd = [], visited = []
  
  
// Length of unsorted array
var len_of_arr = 40;
  
// Store random value in arr[]
for (var i = 0; i < len_of_arr; i++) {
    arr.push(Math.round(Math.random() * 250) )
}
  
// Initialize itmd and visited array with 0
for (var i = 0; i < len_of_arr; i++) {
    itmd.push(0)
    visited.push(0)
}
  
// Merging of two sub array
// https://www.geeksforgeeks.org/merge-two-sorted-arrays/
function mergeArray(start, end) {
    let mid = parseInt((start + end) >> 1);
    let start1 = start, start2 = mid + 1
    let end1 = mid, end2 = end
      
    // Initial index of merged subarray
    let index = start
  
    while (start1 <= end1 && start2 <= end2) {
        if (arr[start1] <= arr[start2]) {
            itmd[index] = arr[start1]
            index = index + 1
            start1 = start1 + 1;
        }
        else if(arr[start1] > arr[start2]) {
            itmd[index] = arr[start2]
            index = index + 1
            start2 = start2 + 1;
        }
    }
  
    // Copy the remaining elements of
    // arr[], if there are any
    while (start1 <= end1) {
        itmd[index] = arr[start1]
        index = index + 1
        start1 = start1 + 1;
    }
  
    while (start2 <= end2) {
        itmd[index] = arr[start2]
        index = index + 1
        start2 = start2 + 1;
    }
  
    index = start
    while (index <= end) {
        arr[index] = itmd[index];
        index++;
    }
}
  
// Function for showing visualization 
// effect
function drawBars(start, end) {
  
    // Clear pervious unsorted bars
    ctrl.clearRect(0, 0, 1000, 1500)
  
    // Styling of bars
    for (let i = 0; i < len_of_arr; i++) {
  
        // Changing styles of bars
        ctrl.fillStyle = "black"
        ctrl.shadowOffsetX = 2
        ctrl.shadowColor = "chocolate";
        ctrl.shadowBlur = 3;
        ctrl.shadowOffsetY =5;
         
          
        // Size of rectangle of bars
        ctrl.fillRect(25 * i, 300 - arr[i], 20, arr[i])
          
        if (visited[i]) {
            ctrl.fillStyle = "#006d13"
            ctrl.fillRect(25 * i, 300 - arr[i], 20, arr[i])
            ctrl.shadowOffsetX = 2
        }
    }
  
    for (let i = start; i <= end; i++) {
        ctrl.fillStyle = "orange"
        ctrl.fillRect(25 * i, 300 - arr[i], 18, arr[i])
        ctrl.fillStyle = "#cdff6c"
        ctrl.fillRect(25 * i,300, 18, arr[i])
        visited[i] = 1
    }
}
  
// Waiting interval between two bars
function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
  
  
// Merge Sorting
const mergeSort = async (start, end) => {
    if (start < end) {
        let mid = parseInt((start + end) >> 1)
        await mergeSort(start, mid)
        await mergeSort(mid + 1, end)
        await mergeArray(start, end)
        await drawBars(start, end)
  
        // Waiting time is 800ms
        await timeout(800)
    }
}
  
// canvasElements function for storing
// width and height in canvas variable
function canvasElements() {
    canvas = document.getElementById("Canvas")
    canvas.width = canvas.height = 1000
    canvaswidth = canvas.width
    canvasheight = canvas.height
    ctrl = canvas.getContext("2d")
}
  
// Asynchronous MergeSort function 
const performer = async () => {
    await mergeSort(0, len_of_arr - 1)
    await drawBars()
  
    // Code for change title1 text 
    const title1_changer = document.querySelector(".title1")
    title1_changer.innerText = "Array is completely sorted"
}
performer()

输出: