Javascript 如何制作排序可视化工具?

Javascript 如何制作排序可视化工具?,javascript,reactjs,Javascript,Reactjs,我正在尝试使用react制作排序可视化工具,我还为不同的排序机制(如合并排序、冒泡排序、插入排序和快速排序)准备了算法,但无法直观地实现它 我为冒泡排序制作了可视化工具,但也为此我在堆栈溢出中提出了问题,其中一个家伙用react给出了它的全部逻辑,现在我正试图使合并排序成为可能,花了4天时间来实现它,但我还是被卡住了,感觉如果没有任何帮助,我将无法生存 谁能建议我怎么做 我的App.js文件 import "./styles.css"; import { useState,

我正在尝试使用react制作排序可视化工具,我还为不同的排序机制(如合并排序、冒泡排序、插入排序和快速排序)准备了算法,但无法直观地实现它

我为冒泡排序制作了可视化工具,但也为此我在堆栈溢出中提出了问题,其中一个家伙用react给出了它的全部逻辑,现在我正试图使合并排序成为可能,花了4天时间来实现它,但我还是被卡住了,感觉如果没有任何帮助,我将无法生存

谁能建议我怎么做

我的App.js文件

import "./styles.css";
import { useState, useEffect } from "react";

export default function App() {
  const [arrayForSort, setArrayForSort] = useState([
    70,
    20,
    40,
    90,
    26,
    10,
    80,
    50
  ]);

  const [isSort, setIsSort] = useState(false);

  const fetchArray = arrayForSort.map((element) => {
    return (
      <span className="array-element" key={element}>
        {element}
      </span>
    );
  });

  const beginSort = () => {
    setIsSort(true);
  };

  const mergeSort = (myArray) => {
    let newArray = [...myArray];

    // if array contains nothing or only one element then return the array
    if (myArray.length <= 1) return myArray;

    // find the middle of the array
    const middle = Math.floor(myArray.length / 2);

    // Split the array into two
    const leftArray = myArray.slice(0, middle);
    const rightArray = myArray.slice(middle);

    // recursive function to combine left and right array
    return merge(mergeSort(leftArray), mergeSort(rightArray), newArray);
  };

  const merge = (leftArr, rightArr, originalArray) => {
    let resultArray = [],
      leftIndex = 0,
      rightIndex = 0;

    while (leftIndex < leftArr.length && rightIndex < rightArr.length) {
      if (leftArr[leftIndex] < rightArr[rightIndex]) {
        let newLeftIndex = originalArray.indexOf(leftArr[leftIndex]);
        let newRightIndex = originalArray.indexOf(rightArr[rightIndex]);
        [originalArray[newLeftIndex], originalArray[newRightIndex]] = [
          originalArray[newRightIndex],
          originalArray[newLeftIndex]
        ];
        resultArray.push(leftArr[leftIndex]);
        leftIndex++;
      } else {
        let newLeftIndex = originalArray.indexOf(leftArr[leftIndex]);
        let newRightIndex = originalArray.indexOf(rightArr[rightIndex]);
        [originalArray[newRightIndex], originalArray[newLeftIndex]] = [
          originalArray[newLeftIndex],
          originalArray[newRightIndex]
        ];
        resultArray.push(rightArr[rightIndex]);
        rightIndex++;
      }
    }

    setArrayForSort(originalArray);

    resultArray = resultArray
      .concat(leftArr.slice(leftIndex))
      .concat(rightArr.slice(rightIndex));

    return resultArray;
  };

  useEffect(() => {
    if (isSort) {
      const arr = [...arrayForSort];
      const sortedArray = mergeSort(arr);
      console.log(sortedArray);
      // setArrayForSort(sortedArray);
      setIsSort(false);
    }
  }, [arrayForSort, setArrayForSort, isSort, mergeSort]);

  return (
    <div className="App">
      <h1>Merge Sort</h1>
      <div className="array">{fetchArray}</div>
      <button onClick={beginSort}>SORT</button>
    </div>
  );
}
导入“/styles.css”; 从“react”导入{useState,useffect}; 导出默认函数App(){ 常量[arrayForSort,setArrayForSort]=useState([ 70, 20, 40, 90, 26, 10, 80, 50 ]); 常量[isSort,setIsSort]=useState(false); 常量fetchArray=arrayForSort.map((元素)=>{ 返回( {element} ); }); 常量beginSort=()=>{ setIsSort(真); }; 常量合并排序=(myArray)=>{ 让newArray=[…myArray]; //如果数组不包含任何内容或仅包含一个元素,则返回数组 if(myArray.length){ 让resultArray=[], leftIndex=0, rightIndex=0; while(leftIndex{ if(isSort){ 常量arr=[…数组forsort]; const sortedArray=合并排序(arr); 控制台日志(Darray); //setArrayForSort(SorterDarray); setIsSort(假); } },[arrayForSort,setArrayForSort,isSort,mergeSort]); 返回( 合并排序 {fetchArray} 分类 ); }
这实际上比我最初想象的要复杂。我希望每个单独的“交换”都能显示检测到的合并排序,但我在按照我最初的想法正确地“备份拆分”时遇到了问题

我可能会再次讨论这个问题,但如果我不这么做,这里有一个版本只是稍微调整了您的原始代码。您会注意到更大的拆分只是以正确的顺序“突然”出现,这可能不是您想要的,但希望它有助于理解超时和承诺:


需要明确的是,一切基本上仍在“一次性”中进行,这意味着调用堆栈仍然基本相同,这意味着所有函数仍在互相调用。区别在于
Promise/setTimeout
添加了“暂停,然后运行此”而
async/await
添加了一个“在继续之前等待”,我想如果你真的想炫耀“每次交换”你必须真正分解控制流并添加一些条件步骤。

你能用你当前的代码指出确切的问题吗?还有一个像这段代码这样大的代码沙盒链接可以加快解决你的问题。@LakshyaThakur问题是我可以做算法,它对数组进行排序,但它按o排序当然,我不能跟踪每一个排序步骤的发生。CodeSandBox链接:这对我来说确实很好,至少它比我的坏代码好得多。但是,是的,你是对的,如果它必须显示每个交换,应该有一些条件步骤。另外,在处理这个问题时,我有另一种方法,首先对一次数组,将所有更改存储在另一个数组中,然后根据需要显示更改,但我不知道将所有更改存储在另一个数组中,然后在UI上显示更改是否是一种好的做法。@Siddhesh如果您谈论的是您的原始代码,它一点也没有被破坏,非常可靠的实现就像“一件大事”是你可以用一个
.sort()
替换庞大的while循环(我调整了链接的代码以展示如何实现它)“,我认为这听起来很好。也许有更好的方法可以做到这一点,但这种情况下,你会在6个月后再次思考,并想出比现在好10倍的代码。如果你让它工作并学到了一些东西,那就太棒了!