学习说明
本文章采用C语言实现八大经典排序算法,分别是冒泡、插入、选择、归并、希尔、快速、堆、基数排序;并采用Vue3结合element-plus与echarts实现在线动画演示排序过程,帮助理解算法原理与对比算法排序效果
C语言实现排序算法
可以查看该篇文章进行了解,也可以在末尾下载源码进行相应学习;本文章着重讲解在线演示的动画系统
C语言控制台版本的演示效果
动态排序网站演示效果
原理演示
性能演示
C语言控制台源码
MySort.h
#include <iostream>
#include <stdio.h>
#include <time.h>
#include <Windows.h>
using namespace std;
#define N 10000
typedef int elementType;
#pragma once
class MySort
{
public:
MySort();
void bubbleSortTest();
void insertSortTest();
void selectSortTest();
void mergeSortTest();
void heapSortTest();
void quickSortTest();
void shellSortTest();
void radixSortTest();
void generateData();
private:
elementType* arr = (elementType*)malloc(sizeof(elementType) * N);
elementType* tempArr = (elementType*)malloc(sizeof(elementType) * N);
elementType** radixSortTempArr;
int maxDigitLength = 0;
int calCount = 0;
void bubbleSort();
void insertSort();
void selectSort();
void mergeSort(int start, int end);
void heapSort();
void quickSort(int low, int high);
void shellSort();
void radixSort();
void merge(int start, int mid, int end);
void heapAdjust(int low, int high);
int partition(int low, int high);
int getmaxLength();
int getDigit(elementType num, int i);
void clearZero();
void initData();
void saveData();
long getCurrentMillSecond();
};
MySort.cpp
#include "MySort.h"
MySort::MySort()
{
radixSortTempArr = (elementType**)malloc(sizeof(elementType) * 10);
if (radixSortTempArr == NULL)
{
cout << "内存不足,空间分配出错";
return;
}
for (int i = 0; i < 10; i++)
{
radixSortTempArr[i] = (elementType*)malloc(sizeof(elementType) * N);
if (radixSortTempArr[i] == NULL)
{
cout << "内存不足,空间分配出错";
return;
}
}
}
void MySort::bubbleSortTest()
{
initData();
long start = getCurrentMillSecond();
bubbleSort();
long end = getCurrentMillSecond();
cout << "冒泡排序耗时:" << (end - start) << endl;
cout << "冒泡排序运算次数:" << calCount << endl;
saveData();
}
void MySort::insertSortTest()
{
initData();
long start = getCurrentMillSecond();
insertSort();
long end = getCurrentMillSecond();
cout << "插入排序耗时:" << (end - start) << endl;
cout << "插入排序运算次数:" << calCount << endl;
saveData();
}
void MySort::selectSortTest()
{
initData();
long start = getCurrentMillSecond();
selectSort();
long end = getCurrentMillSecond();
cout << "选择排序耗时:" << (end - start) << endl;
cout << "选择排序运算次数:" << calCount << endl;
saveData();
}
void MySort::mergeSortTest()
{
initData();
long start = getCurrentMillSecond();
mergeSort(0, N - 1);
long end = getCurrentMillSecond();
cout << "归并排序耗时:" << (end - start) << endl;
cout << "归并排序运算次数:" << calCount << endl;
saveData();
}
void MySort::heapSortTest()
{
initData();
long start = getCurrentMillSecond();
heapSort();
long end = getCurrentMillSecond();
cout << "堆排序耗时:" << (end - start) << endl;
cout << "堆排序运算次数:" << calCount << endl;
saveData();
}
void MySort::quickSortTest()
{
initData();
long start = getCurrentMillSecond();
quickSort(0, N - 1);
long end = getCurrentMillSecond();
cout << "快速排序耗时:" << (end - start) << endl;
cout << "快速排序运算次数:" << calCount << endl;
saveData();
}
void MySort::shellSortTest()
{
initData();
long start = getCurrentMillSecond();
shellSort();
long end = getCurrentMillSecond();
cout << "希尔排序耗时:" << (end - start) << endl;
cout << "希尔排序运算次数:" << calCount << endl;
saveData();
}
void MySort::radixSortTest()
{
initData();
long start = getCurrentMillSecond();
radixSort();
long end = getCurrentMillSecond();
cout << "基数排序耗时:" << (end - start) << endl;
cout << "基数排序运算次数:" << calCount << endl;
saveData();
}
void MySort::generateData()
{
int* arr = (int*)malloc(sizeof(int) * N);
if (arr == NULL)
{
cout << "内存不足,空间分配出错";
return;
}
srand((unsigned int)time(0));
for (int i = 0; i < N; i++)
{
arr[i] = rand() % N + N;
}
FILE* fp = NULL;
errno_t err;
if ((err = fopen_s(&fp, "D:/test.txt", "w")) != 0)
{
cout << "文件写入失败" << endl;
return;
}
for (int i = 0; i < N; i++)
{
fprintf_s(fp, "%d ", arr[i]);
}
fclose(fp);
}
void MySort::bubbleSort()
{
for (int i = 0; i < N; i++)
{
for (int j = 1; j < N - i; j++)
{
if (arr[j] < arr[j - 1])
{
elementType temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
calCount++;
}
}
}
}
void MySort::insertSort()
{
for (int i = 1; i < N; i++)
{
elementType temp = arr[i];
int j = i;
while (j > 0 && temp < arr[j - 1])
{
arr[j] = arr[j - 1];
j--;
calCount++;
}
if (j != i)
{
arr[j] = temp;
}
}
}
void MySort::selectSort()
{
int minIndex;
for (int i = 0; i < N; i++)
{
minIndex = i;
for (int j = i + 1; j < N; j++)
{
if (arr[minIndex] > arr[j])
{
minIndex = j;
}
calCount++;
}
if (minIndex != i)
{
elementType temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
}
void MySort::mergeSort(int start, int end)
{
if (start >= end)
{
return;
}
int mid = (start + end) / 2;
mergeSort(start, mid);
mergeSort(mid + 1, end);
merge(start, mid, end);
}
void MySort::heapSort()
{
for (int i = N / 2; i >= 0; i--)
{
heapAdjust(i, N);
}
for (int i = N - 1; i > 0; i--)
{
elementType temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heapAdjust(0, i - 1);
}
}
void MySort::quickSort(int low, int high)
{
if (low < high)
{
int pivot = partition(low, high);
quickSort(low, pivot - 1);
quickSort(pivot + 1, high);
}
}
void MySort::shellSort()
{
for (int step = N / 2; step >= 1; step /= 2)
{
for (int i = step; i < N; i++)
{
elementType temp = arr[i];
int j = i;
while (j >= step && temp < arr[j - step])
{
arr[j] = arr[j - step];
j -= step;
calCount++;
}
if (j != i)
{
arr[j] = temp;
}
}
}
}
void MySort::radixSort()
{
int i, j, l, digit;
maxDigitLength = getmaxLength();
int index[10]{};
for (i = 1; i <= maxDigitLength; i++)
{
for (j = 0; j < N; j++)
{
digit = getDigit(arr[j], i);
radixSortTempArr[digit][index[digit]++] = arr[j];
calCount++;
}
l = 0;
for (j = 0; j < 10; j++)
{
int tempIndex = 0;
while (index[j] > 0)
{
arr[l++] = radixSortTempArr[j][tempIndex++];
index[j]--;
calCount++;
}
}
}
}
void MySort::merge(int start, int mid, int end)
{
int k = 0;
int i = start;
int j = mid + 1;
while (i <= mid && j <= end)
{
if (arr[i] <= arr[j])
{
tempArr[k++] = arr[i++];
calCount++;
}
else
{
tempArr[k++] = arr[j++];
calCount++;
}
}
while (i <= mid)
{
tempArr[k++] = arr[i++];
calCount++;
}
while (j <= end)
{
tempArr[k++] = arr[j++];
calCount++;
}
for (int i = 0, j = start; i < k; i++, j++)
{
arr[j] = tempArr[i];
}
}
void MySort::heapAdjust(int low, int high)
{
elementType temp = arr[low];
for (int i = 2 * low; i < high; i *= 2)
{
if (i < high && arr[i] < arr[i + 1])
{
i++;
}
if (temp >= arr[i])
{
break;
}
arr[low] = arr[i];
low = i;
calCount++;
}
arr[low] = temp;
}
int MySort::partition(int low, int high)
{
elementType temp = arr[low];
elementType pivot = arr[low];
while (low < high)
{
while (low < high && arr[high] >= pivot)
{
calCount++;
high--;
}
arr[low] = arr[high];
while (low < high && arr[low] <= pivot)
{
calCount++;
low++;
}
arr[high] = arr[low];
}
arr[low] = temp;
return low;
}
int MySort::getmaxLength()
{
int i;
int max = 0;
int count;
elementType temp;
for (i = 0; i < N; i++)
{
count = 0;
temp = arr[i];
while (temp >= 1)
{
temp /= 10;
count++;
}
if (count > max)
{
max = count;
}
}
return max;
}
int MySort::getDigit(elementType num, int i)
{
while (i > 1)
{
num /= 10;
i--;
}
return num % 10;
}
void MySort::clearZero()
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < N; j++)
{
radixSortTempArr[i][j] = 0;
}
}
}
void MySort::initData()
{
calCount = 0;
FILE* fp = NULL;
errno_t err;
if ((err = fopen_s(&fp, "D:/test.txt", "r")) != 0)
{
cout << "文件打开失败" << endl;
return;
}
for (int i = 0; i < N; i++)
{
fscanf_s(fp, "%d ", &arr[i]);
}
fclose(fp);
}
void MySort::saveData()
{
FILE* fp = NULL;
errno_t err;
if ((err = fopen_s(&fp, "D:/sort.txt", "w")) != 0)
{
cout << "文件打开失败" << endl;
return;
}
for (int i = 0; i < N; i++)
{
fprintf_s(fp, "%d ", arr[i]);
}
fclose(fp);
}
long MySort::getCurrentMillSecond()
{
time_t tt;
time(&tt);
SYSTEMTIME t1;
GetSystemTime(&t1);
return (long)tt * 1000 + (long)t1.wMilliseconds;
}
main.cpp
#include "MySort.h"
void printMenu()
{
cout << "***********排序演示及性能测试系统***********" << endl << endl;
cout << "***************1、冒泡排序*****************" << endl << endl;
cout << "***************2、插入排序*****************" << endl << endl;
cout << "***************3、选择排序*****************" << endl << endl;
cout << "***************4、归并排序*****************" << endl << endl;
cout << "***************5、快速排序*****************" << endl << endl;
cout << "***************6、希尔排序*****************" << endl << endl;
cout << "***************7、堆排序*****************" << endl << endl;
cout << "***************8、基数排序*****************" << endl << endl;
cout << "***************9、生成数据*****************" << endl << endl;
cout << "***************10、退出系统*****************";
}
int main()
{
int choice;
MySort mySort;
bool flag = true;
printMenu();
while (flag)
{
cout << endl << endl << "请输入你的选择:";
cin >> choice;
switch (choice)
{
case 1:
mySort.bubbleSortTest();
break;
case 2:
mySort.insertSortTest();
break;
case 3:
mySort.selectSortTest();
break;
case 4:
mySort.mergeSortTest();
break;
case 5:
mySort.quickSortTest();
break;
case 6:
mySort.shellSortTest();
break;
case 7:
mySort.heapSortTest();
break;
case 8:
mySort.radixSortTest();
break;
case 9:
mySort.generateData();
break;
case 10:
flag = false;
break;
default:
break;
}
}
system("pause");
}
在线网站关键代码
PrincipleDisplay.vue
<template>
<div>
<el-button @click="startSort('Bubble')">冒泡排序</el-button>
<el-button @click="startSort('Insert')">插入排序</el-button>
<el-button @click="startSort('Select')">选择排序</el-button>
<el-button @click="startSort('Merge')">归并排序</el-button>
<el-button @click="startSort('Shell')">希尔排序</el-button>
<el-button @click="startSort('Quick')">快速排序</el-button>
<el-button @click="startSort('Heap')">堆排序</el-button>
<el-button @click="startSort('Radix')">基数排序</el-button>
<el-button type="primary" @click="getRandomArray">随机生成数据</el-button>
<el-input placeholder="数据个数" style="width: 120px; margin-left: 10px;" v-model="data.count" />
</div>
<el-input placeholder="数组形式输入数据,按Enter结束输入,按空格划分,如(1 2 3 4 5 9 8 7 6 10)" style="margin-top: 20px;"
v-model="data.inputArr" @keypress.enter="getArrByInput" />
<div id="chartContainer"></div>
</template>
<script>
import { onMounted, reactive } from "vue";
import { bubbleSort, getRandomArr, heapSort, initChart, insertSort, judgeArrSortOverOrNotStart, judgeArrValid, mergeSort, message, quickSort, radixSort, selectSort, shellSort } from '@/utils/api';
export default {
name: "PrincipleDisplay",
setup() {
const data = reactive({
arr: [],
arrData: [11, 3, 5, 7, 9, 2, 4, 6, 8, 10],
count: 30,
inputArr: "",
});
function changeArrToColorArr(arr) {
const colorArr = [];
for (var i = 0; i < arr.length; i++) {
colorArr.push({
value: arr[i],
itemStyle: {
color: '#5470c6'
},
});
}
return colorArr;
}
function startSort(sortType) {
if (!judgeArrSortOverOrNotStart(data.arr)) {
message("数组排序演示还未完成", "info");
return;
}
data.arr = changeArrToColorArr(data.arrData);
switch (sortType) {
case "Bubble":
bubbleSort(data.arr);
break;
case "Insert":
insertSort(data.arr);
break;
case "Select":
selectSort(data.arr);
break;
case "Merge":
mergeSort(data.arr);
break;
case "Shell":
shellSort(data.arr);
break;
case "Quick":
quickSort(data.arr);
break;
case "Heap":
heapSort(data.arr);
break;
case "Radix":
radixSort(data.arr);
break;
default:
break;
}
}
onMounted(() => {
data.arr = changeArrToColorArr(data.arrData);
initChart(data.arr);
});
function getRandomArray() {
if (!judgeArrSortOverOrNotStart(data.arr)) {
message("数组排序演示还未完成", "info");
return;
}
if (data.count > 30) {
message("数组元素个数过多, 展示消耗时间过长", "info");
return;
}
data.arrData = getRandomArr(data.count);
data.arr = changeArrToColorArr(data.arrData);
initChart(data.arr);
}
function getArrByInput() {
if (!judgeArrSortOverOrNotStart(data.arr)) {
message("数组排序演示还未完成", "info");
return;
}
const arr = data.inputArr.split(" ");
if (Array.isArray(arr)) {
if (arr.length < 2) {
message("输入数组元素个数过少", "info");
} else if (!judgeArrValid(arr)) {
message("数组元素差距过大, 绘制图像不直观", "info");
} else {
data.arrData = arr;
data.arr = changeArrToColorArr(data.arrData);
initChart(data.arr);
}
} else {
message("输入数组有误, 不是正确的数组", "info");
}
}
return {
data,
startSort,
getRandomArray,
getArrByInput,
}
},
};
</script>
<style scoped>
#chartContainer {
width: calc(100vw - 80px);
height: calc(100vh - 230px);
position: absolute;
top: 130px;
}
</style>
PerformanceDisplay.vue
<template>
<div>
<el-button @click="getSortPerformance(1000)">1000个数据</el-button>
<el-button @click="getSortPerformance(5000)">5000个数据</el-button>
<el-button @click="getSortPerformance(10000)">10000个数据</el-button>
<el-button @click="getSortPerformance(50000)">50000个数据</el-button>
<el-button @click="getSortPerformance(100000)">100000个数据</el-button>
<el-button @click="getSortPerformance(300000)">300000个数据</el-button>
<el-button @click="getSortPerformance(500000)">500000个数据</el-button>
<el-button @click="getSortPerformance(1000000)">1000000个数据</el-button>
</div>
<div id="squareChartContainer"></div>
<div id="logChartContainer"></div>
</template>
<script>
import { onBeforeMount } from "vue";
import { getEightSortPerformance, getFiveLogSortPerformance } from "@/utils/sort.js"
export default {
name: "PerformanceDisplay",
setup() {
onBeforeMount(() => {
});
function getSortPerformance(count) {
switch (count) {
case 1000:
case 5000:
case 10000:
getEightSortPerformance(count);
break;
case 50000:
case 100000:
case 300000:
case 500000:
case 1000000:
getFiveLogSortPerformance(count);
break;
}
}
return {
getSortPerformance,
};
},
};
</script>
<style scoped>
#squareChartContainer {
width: calc(37.5vw - 60px);
height: calc(100vh - 200px);
position: absolute;
top: 90px;
/* border: 1px black solid; */
}
#logChartContainer {
width: calc(62.5vw - 60px);
height: calc(100vh - 200px);
position: absolute;
top: 90px;
right: 20px;
/* border: 1px black solid; */
}
</style>
api.js
import { ElMessage } from 'element-plus';
import * as echarts from "echarts";
export function message(msg, type) {
ElMessage({
message: msg,
showClose: true,
type: type,
center: true
})
}
export const getRandomArr = (count) => {
const arr = [];
for (var i = 0; i < count; i++) {
arr.push(Math.floor(Math.random() * (count)) + 1);
}
return arr;
}
export const judgeArrValid = (arr) => {
var min = arr[0];
var max = arr[0];
for (var i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
if (arr[i] < min) {
min = arr[i];
}
}
if (max / min > 50) {
return false;
}
return true;
}
export const judgeArrSortOverOrNotStart = (arr) => {
var startFlag = true;
var overFlag = true;
var i;
for (i = 0; i < arr.length; i++) {
if (arr[i].itemStyle.color != "#5470c6") {
overFlag = false;
}
}
for (i = 0; i < arr.length; i++) {
if (arr[i].itemStyle.color != "#a90000") {
startFlag = false;
}
}
return startFlag || overFlag;
}
export const initChart = (arr) => {
const chartDom = document.getElementById("chartContainer");
const myChart = echarts.init(chartDom);
const option = {
xAxis: {
type: "category",
},
yAxis: {
type: "value",
},
series: [
{
data: arr,
type: "bar",
},
],
grid: {
left: "1%",
right: "1%",
bottom: "2%",
containLabel: true,
},
};
option && myChart.setOption(option);
}
const interval = 500;
function sleep() {
return new Promise(resolve => setTimeout(resolve, interval));
}
export const bubbleSort = async (arr) => {
for (var i = 0; i < arr.length; i++) {
for (var j = 1; j < arr.length - i; j++) {
arr[j].itemStyle = {
color: '#a90000'
};
arr[j - 1].itemStyle = {
color: '#a90000'
};
if (arr[j].value < arr[j - 1].value) {
var temp = arr[j].value;
arr[j].value = arr[j - 1].value;
arr[j - 1].value = temp;
}
await sleep();
initChart(arr);
arr[j - 1].itemStyle = {
color: '#5470c6'
};
}
}
arr[0].itemStyle = {
color: '#a90000'
};
}
export const insertSort = async (arr) => {
for (var i = 0; i < arr.length; i++) {
var temp = arr[i].value;
var j = i;
arr[i].itemStyle = {
color: '#a90000'
};
while (j > 0 && temp < arr[j - 1].value) {
arr[j].value = arr[j - 1].value;
j--;
await sleep();
initChart(arr);
}
if (j != i) {
arr[j].value = temp;
}
}
}
export const selectSort = async (arr) => {
var minIndex;
for (var i = 0; i < arr.length; i++) {
minIndex = i;
for (var j = i + 1; j < arr.length; j++) {
if (arr[minIndex].value > arr[j].value) {
minIndex = j;
arr[minIndex].itemStyle = {
color: '#a90000'
};
await sleep();
initChart(arr);
}
}
arr[minIndex].itemStyle = {
color: '#5470c6'
};
if (minIndex != i) {
var temp = arr[minIndex].value;
arr[minIndex].value = arr[i].value;
arr[i].value = temp;
}
arr[i].itemStyle = {
color: '#a90000'
};
}
await sleep();
initChart(arr);
}
export const mergeSort = async (arr) => {
const tempArr = [];
for (var i = 0; i < arr.length; i++) {
tempArr.push(0);
}
mergeSortStart(arr, tempArr, 0, arr.length - 1);
}
async function mergeSortStart(arr, tempArr, start, end) {
if (start >= end) {
return;
}
var mid = Math.floor((start + end) / 2);
await mergeSortStart(arr, tempArr, start, mid);
await mergeSortStart(arr, tempArr, mid + 1, end);
await merge(arr, tempArr, start, mid, end);
await sleep();
initChart(arr);
}
async function merge(arr, tempArr, start, mid, end) {
var k = 0;
var i = start;
var j = mid + 1;
while (i <= mid && j <= end) {
if (arr[i].value <= arr[j].value) {
tempArr[k++] = arr[i++].value;
}
else {
tempArr[k++] = arr[j++].value;
}
}
while (i <= mid) {
tempArr[k++] = arr[i++].value;
}
while (j <= end) {
tempArr[k++] = arr[j++].value;
}
for (i = 0, j = start; i < k; i++, j++) {
arr[j].itemStyle = {
color: '#a90000'
};
arr[j].value = tempArr[i];
}
}
export const shellSort = async (arr) => {
for (var step = arr.length / 2; step >= 1;) {
await recoverColor(arr, "#5470c6");
for (var i = step; i < arr.length; i++) {
var temp = arr[i].value;
var j = i;
while (j >= step && temp < arr[j - step].value) {
arr[j].value = arr[j - step].value;
j -= step;
}
if (j != i) {
arr[j].value = temp;
}
arr[i - step].itemStyle = {
color: '#a90000'
}
arr[i].itemStyle = {
color: '#a90000'
}
await sleep();
initChart(arr);
}
step = Math.floor(step / 2);
}
}
async function recoverColor(arr, color) {
for (var i = 0; i < arr.length; i++) {
arr[i].itemStyle = {
color: color
}
}
}
export const quickSort = async (arr) => {
await quickSortStart(arr, 0, arr.length - 1);
await recoverColor(arr, "#a90000");
await sleep();
initChart(arr);
}
async function quickSortStart(arr, low, high) {
if (low < high) {
var pivot = await partition(arr, low, high);
arr[pivot].itemStyle = {
color: '#ffd766'
}
await sleep();
initChart(arr);
await quickSortStart(arr, low, pivot - 1);
await quickSortStart(arr, pivot + 1, high);
}
}
async function partition(arr, low, high) {
var temp = arr[low].value;
var pivot = arr[low].value;
while (low < high) {
while (low < high && arr[high].value >= pivot) {
high--;
}
arr[high].itemStyle = {
color: '#a90000'
}
arr[low].value = arr[high].value;
while (low < high && arr[low].value <= pivot) {
low++;
}
arr[low].itemStyle = {
color: '#a90000'
}
arr[high].value = arr[low].value;
}
arr[low].value = temp;
return low;
}
export const heapSort = async (arr) => {
var i;
for (i = arr.length / 2; i >= 0; i--) {
await heapAdjust(arr, i, arr.length);
}
for (i = arr.length - 1; i >= 0; i--) {
var temp = arr[0].value;
arr[0].value = arr[i].value;
arr[i].value = temp;
await heapAdjust(arr, 0, i - 1);
arr[i].itemStyle = {
color: '#a90000'
}
}
await sleep();
initChart(arr);
}
async function heapAdjust(arr, low, high) {
var temp = arr[low].value;
for (var i = 2 * low; i < high; i *= 2) {
if (i < high && arr[i].value < arr[i + 1].value) {
i++;
}
if (temp >= arr[i].value) {
break;
}
arr[low].value = arr[i].value;
low = i;
}
arr[low].value = temp;
await sleep();
initChart(arr);
}
export const radixSort = async (arr) => {
var i, j, l, digit;
const radixSortTempArr = [];
for (i = 0; i < 10; i++) {
const tempArr = [];
for (j = 0; j < arr.length; j++) {
tempArr.push(0);
}
radixSortTempArr.push(tempArr);
}
const maxDigitLength = await getmaxLength(arr);
const index = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
for (i = 1; i <= maxDigitLength; i++) {
for (j = 0; j < arr.length; j++) {
digit = await getDigit(arr[j].value, i);
radixSortTempArr[digit][index[digit]++] = arr[j].value;
}
l = 0;
for (j = 0; j < 10; j++) {
var tempIndex = 0;
while (index[j] > 0) {
arr[l].value = radixSortTempArr[j][tempIndex++];
index[j]--;
arr[l].itemStyle = {
color: '#a90000'
}
l++;
await sleep();
initChart(arr);
}
}
await clearZero(radixSortTempArr);
}
}
async function getmaxLength(arr) {
var max = 0, count, temp;
for (var i = 0; i < arr.length; i++) {
count = 0;
temp = arr[i].value;
while (temp >= 1) {
temp /= 10;
count++;
}
if (count > max) {
max = count;
}
}
return max;
}
async function getDigit(num, i) {
while (i > 1) {
num = Math.floor(num / 10);
i--;
}
return num % 10;
}
async function clearZero(radixSortTempArr) {
for (var i = 0; i < 10; i++) {
for (var j = 0; j < radixSortTempArr[0].length; j++) {
radixSortTempArr[i][j] = 0;
}
}
}
sort.js
import { getRandomArr } from "./api"
import * as echarts from "echarts";
export const initSquareChart = (seriesSquareData) => {
const chartDom = document.getElementById("squareChartContainer");
const myChart = echarts.init(chartDom);
const option = {
xAxis: {
type: "category",
},
yAxis: {
type: "value",
},
legend: {
data: ['冒泡排序', '插入排序', '选择排序']
},
tooltip: {
trigger: 'axis'
},
series: seriesSquareData,
grid: {
left: "1%",
right: "1%",
bottom: "2%",
containLabel: true,
},
};
option && myChart.setOption(option);
}
export const initLogChart = (seriesSquareData) => {
const chartDom = document.getElementById("logChartContainer");
const myChart = echarts.init(chartDom);
const option = {
xAxis: {
type: "category",
},
yAxis: {
type: "value",
},
legend: {
data: ['归并排序', '希尔排序', '快速排序', '堆排序', '基数排序']
},
tooltip: {
trigger: 'axis'
},
series: seriesSquareData,
grid: {
left: "1%",
right: "1%",
bottom: "2%",
containLabel: true,
},
};
option && myChart.setOption(option);
}
const interval = 500;
function sleep() {
return new Promise(resolve => setTimeout(resolve, interval));
}
export const getEightSortPerformance = async (count) => {
const arr = getRandomArr(count);
const seriesSquareData = [];
seriesSquareData.push({
name: '冒泡排序',
type: 'line',
data: getData(arr, bubbleSort)
});
initSquareChart(seriesSquareData);
await sleep();
seriesSquareData.push({
name: '插入排序',
type: 'line',
data: getData(arr, insertSort)
});
initSquareChart(seriesSquareData);
await sleep();
seriesSquareData.push({
name: '选择排序',
type: 'line',
data: getData(arr, selectSort)
});
initSquareChart(seriesSquareData);
await sleep();
const seriesLogData = [];
seriesLogData.push({
name: '归并排序',
type: 'line',
data: getData(arr, mergeSort)
});
initLogChart(seriesLogData);
await sleep();
seriesLogData.push({
name: '希尔排序',
type: 'line',
data: getData(arr, shellSort)
});
initLogChart(seriesLogData);
await sleep();
seriesLogData.push({
name: '快速排序',
type: 'line',
data: getData(arr, quickSort)
});
initLogChart(seriesLogData);
await sleep();
seriesLogData.push({
name: '堆排序',
type: 'line',
data: getData(arr, heapSort)
});
initLogChart(seriesLogData);
// await sleep();
// seriesLogData.push({
// name: '基数排序',
// type: 'line',
// data: getData(arr, radixSort)
// });
// initLogChart(seriesLogData);
}
export const getFiveLogSortPerformance = async (count) => {
const arr = getRandomArr(count);
const seriesLogData = [];
seriesLogData.push({
name: '希尔排序',
type: 'line',
data: getData(arr, shellSort)
});
initLogChart(seriesLogData);
await sleep();
seriesLogData.push({
name: '快速排序',
type: 'line',
data: getData(arr, quickSort)
});
initLogChart(seriesLogData);
await sleep();
seriesLogData.push({
name: '堆排序',
type: 'line',
data: getData(arr, heapSort)
});
initLogChart(seriesLogData);
await sleep();
seriesLogData.push({
name: '归并排序',
type: 'line',
data: getData(arr, mergeSort)
});
initLogChart(seriesLogData);
// await sleep();
// seriesLogData.push({
// name: '基数排序',
// type: 'line',
// data: getData(arr, radixSort)
// });
// initLogChart(seriesLogData);
}
const runTimes = 5;
function getData(arr, func) {
const data = [];
for (var i = 0; i < runTimes; i++) {
const tempArr = [];
arr.forEach(item => tempArr.push(item));
data.push(func(tempArr));
}
return data;
}
function bubbleSort(arr) {
const start = new Date().getTime();
for (var i = 0; i < arr.length; i++) {
for (var j = 1; j < arr.length - i; j++) {
if (arr[j] < arr[j - 1]) {
var temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}
const end = new Date().getTime();
return end - start;
}
function insertSort(arr) {
const start = new Date().getTime();
for (var i = 0; i < arr.length; i++) {
var temp = arr[i];
var j = i;
while (j > 0 && temp < arr[j - 1]) {
arr[j] = arr[j - 1];
j--;
}
if (j != i) {
arr[j] = temp;
}
}
const end = new Date().getTime();
return end - start;
}
function selectSort(arr) {
const start = new Date().getTime();
var minIndex;
for (var i = 0; i < arr.length; i++) {
minIndex = i;
for (var j = i + 1; j < arr.length; j++) {
if (arr[minIndex] > arr[j]) {
minIndex = j;
}
}
if (minIndex != i) {
var temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
const end = new Date().getTime();
return end - start;
}
function mergeSort(arr) {
const start = new Date().getTime();
const tempArr = [];
for (var i = 0; i < arr.length; i++) {
tempArr.push(0);
}
mergeSortStart(arr, tempArr, 0, arr.length - 1);
const end = new Date().getTime();
return end - start;
}
function mergeSortStart(arr, tempArr, start, end) {
if (start >= end) {
return;
}
var mid = Math.floor((start + end) / 2);
mergeSortStart(arr, tempArr, start, mid);
mergeSortStart(arr, tempArr, mid + 1, end);
merge(arr, tempArr, start, mid, end);
}
function merge(arr, tempArr, start, mid, end) {
var k = 0;
var i = start;
var j = mid + 1;
while (i <= mid && j <= end) {
if (arr[i] <= arr[j]) {
tempArr[k++] = arr[i++];
}
else {
tempArr[k++] = arr[j++];
}
}
while (i <= mid) {
tempArr[k++] = arr[i++];
}
while (j <= end) {
tempArr[k++] = arr[j++];
}
for (i = 0, j = start; i < k; i++, j++) {
arr[j] = tempArr[i];
}
}
function shellSort(arr) {
const start = new Date().getTime();
for (var step = arr.length / 2; step >= 1;) {
for (var i = step; i < arr.length; i++) {
var temp = arr[i];
var j = i;
while (j >= step && temp < arr[j - step]) {
arr[j] = arr[j - step];
j -= step;
}
if (j != i) {
arr[j] = temp;
}
}
step = Math.floor(step / 2);
}
const end = new Date().getTime();
return end - start;
}
function quickSort(arr) {
const start = new Date().getTime();
quickSortStart(arr, 0, arr.length - 1);
const end = new Date().getTime();
return end - start;
}
function quickSortStart(arr, low, high) {
if (low < high) {
var pivot = partition(arr, low, high);
quickSortStart(arr, low, pivot - 1);
quickSortStart(arr, pivot + 1, high);
}
}
function partition(arr, low, high) {
var temp = arr[low];
var pivot = arr[low];
while (low < high) {
while (low < high && arr[high] >= pivot) {
high--;
}
arr[low] = arr[high];
while (low < high && arr[low] <= pivot) {
low++;
}
arr[high] = arr[low];
}
arr[low] = temp;
return low;
}
function heapSort(arr) {
const start = new Date().getTime();
var i;
for (i = arr.length / 2; i >= 0; i--) {
heapAdjust(arr, i, arr.length);
}
for (i = arr.length - 1; i >= 0; i--) {
var temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heapAdjust(arr, 0, i - 1);
}
const end = new Date().getTime();
return end - start;
}
function heapAdjust(arr, low, high) {
var temp = arr[low];
for (var i = 2 * low; i < high; i *= 2) {
if (i < high && arr[i] < arr[i + 1]) {
i++;
}
if (temp >= arr[i]) {
break;
}
arr[low] = arr[i];
low = i;
}
arr[low] = temp;
}
export const radixSort = (arr) => {
const start = new Date().getTime();
var i, j, l, digit;
const radixSortTempArr = [];
for (i = 0; i < 10; i++) {
const tempArr = [];
for (j = 0; j < arr.length; j++) {
tempArr.push(0);
}
radixSortTempArr.push(tempArr);
}
const maxDigitLength = getmaxLength(arr);
const index = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
for (i = 1; i <= maxDigitLength; i++) {
for (j = 0; j < arr.length; j++) {
digit = getDigit(arr[j], i);
radixSortTempArr[digit][index[digit]++] = arr[j];
}
l = 0;
for (j = 0; j < 10; j++) {
var tempIndex = 0;
while (index[j] > 0) {
arr[l++] = radixSortTempArr[j][tempIndex++];
index[j]--;
}
}
clearZero(radixSortTempArr);
}
const end = new Date().getTime();
return end - start;
}
function getmaxLength(arr) {
var max = 0, count, temp;
for (var i = 0; i < arr.length; i++) {
count = 0;
temp = arr[i];
while (temp >= 1) {
temp /= 10;
count++;
}
if (count > max) {
max = count;
}
}
return max;
}
function getDigit(num, i) {
while (i > 1) {
num = Math.floor(num / 10);
i--;
}
return num % 10;
}
function clearZero(radixSortTempArr) {
for (var i = 0; i < 10; i++) {
for (var j = 0; j < radixSortTempArr[0].length; j++) {
radixSortTempArr[i][j] = 0;
}
}
}
附注:代码实际有一些可改进的地方,主要是基数排序和冒泡排序里面的逻辑,可以改进