Skip to content

Commit ad862a8

Browse files
authored
Add files via upload
1 parent a983a8f commit ad862a8

21 files changed

Lines changed: 7626 additions & 0 deletions

dp-algorithms.js

Lines changed: 723 additions & 0 deletions
Large diffs are not rendered by default.

dp.html

Lines changed: 455 additions & 0 deletions
Large diffs are not rendered by default.

graph-algorithms.js

Lines changed: 735 additions & 0 deletions
Large diffs are not rendered by default.

graph.html

Lines changed: 456 additions & 0 deletions
Large diffs are not rendered by default.

greedy-algorithms.js

Lines changed: 775 additions & 0 deletions
Large diffs are not rendered by default.

greedy.html

Lines changed: 518 additions & 0 deletions
Large diffs are not rendered by default.

index.html

Lines changed: 504 additions & 0 deletions
Large diffs are not rendered by default.

main.js

Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
// 主要JavaScript逻辑文件
2+
// 包含通用功能和页面初始化
3+
4+
// 全局变量
5+
let currentArray = [];
6+
let isSorting = false;
7+
let animationSpeed = 5;
8+
let arraySize = 50;
9+
10+
// 初始化排序页面
11+
function initializeSortingPage() {
12+
// 绑定事件监听器
13+
document.getElementById('algorithmSelect').addEventListener('change', updateAlgorithmInfo);
14+
document.getElementById('arraySize').addEventListener('input', updateArraySize);
15+
document.getElementById('speed').addEventListener('input', updateSpeed);
16+
document.getElementById('generateArray').addEventListener('click', generateNewArray);
17+
document.getElementById('startSort').addEventListener('click', startSorting);
18+
document.getElementById('stopSort').addEventListener('click', stopSorting);
19+
20+
// 初始化数组
21+
generateNewArray();
22+
updateAlgorithmInfo();
23+
24+
// 初始化动画
25+
initializeAnimations();
26+
}
27+
28+
// 生成新的随机数组
29+
function generateNewArray() {
30+
if (isSorting) return;
31+
32+
currentArray = [];
33+
const minValue = 10;
34+
const maxValue = 400;
35+
36+
for (let i = 0; i < arraySize; i++) {
37+
currentArray.push(Math.floor(Math.random() * (maxValue - minValue + 1)) + minValue);
38+
}
39+
40+
displayArray();
41+
resetStatistics();
42+
}
43+
44+
// 显示数组可视化
45+
function displayArray() {
46+
const container = document.getElementById('arrayContainer');
47+
container.innerHTML = '';
48+
49+
const maxValue = Math.max(...currentArray);
50+
const containerHeight = container.clientHeight - 20;
51+
52+
currentArray.forEach((value, index) => {
53+
const bar = document.createElement('div');
54+
const height = (value / maxValue) * containerHeight;
55+
56+
bar.className = 'array-bar';
57+
bar.style.height = `${height}px`;
58+
bar.style.width = `${Math.max(2, (container.clientWidth - 40) / arraySize - 1)}px`;
59+
bar.style.background = `linear-gradient(to top, #00d4ff, #4ecdc4)`;
60+
bar.style.marginRight = '1px';
61+
bar.id = `bar-${index}`;
62+
63+
// 添加数值标签
64+
const label = document.createElement('div');
65+
label.textContent = value;
66+
label.style.position = 'absolute';
67+
label.style.bottom = '-20px';
68+
label.style.left = '50%';
69+
label.style.transform = 'translateX(-50%)';
70+
label.style.fontSize = '10px';
71+
label.style.color = '#b0b0b0';
72+
label.style.display = arraySize <= 20 ? 'block' : 'none';
73+
74+
bar.style.position = 'relative';
75+
bar.appendChild(label);
76+
77+
container.appendChild(bar);
78+
});
79+
}
80+
81+
// 更新数组大小
82+
function updateArraySize() {
83+
const sizeSlider = document.getElementById('arraySize');
84+
const sizeValue = document.getElementById('arraySizeValue');
85+
86+
arraySize = parseInt(sizeSlider.value);
87+
sizeValue.textContent = arraySize;
88+
89+
generateNewArray();
90+
}
91+
92+
// 更新动画速度
93+
function updateSpeed() {
94+
const speedSlider = document.getElementById('speed');
95+
const speedValue = document.getElementById('speedValue');
96+
97+
animationSpeed = parseInt(speedSlider.value);
98+
speedValue.textContent = animationSpeed;
99+
}
100+
101+
// 更新算法信息
102+
function updateAlgorithmInfo() {
103+
const algorithm = document.getElementById('algorithmSelect').value;
104+
const description = document.getElementById('algorithmDescription');
105+
const bestCase = document.getElementById('bestCase');
106+
const averageCase = document.getElementById('averageCase');
107+
const worstCase = document.getElementById('worstCase');
108+
const spaceComplexity = document.getElementById('spaceComplexity');
109+
const stability = document.getElementById('stability');
110+
const code = document.getElementById('algorithmCode');
111+
112+
const algorithmInfo = {
113+
bubble: {
114+
description: '冒泡排序是一种简单的排序算法,通过重复遍历数组,比较相邻元素并交换位置,使较大的元素逐渐"冒泡"到数组末尾。虽然效率不高,但是稳定排序,适合教学使用。',
115+
bestCase: 'O(n)',
116+
averageCase: 'O(n²)',
117+
worstCase: 'O(n²)',
118+
spaceComplexity: 'O(1)',
119+
stability: '稳定',
120+
code: `function bubbleSort(arr) {
121+
const n = arr.length;
122+
for (let i = 0; i < n - 1; i++) {
123+
let swapped = false;
124+
for (let j = 0; j < n - i - 1; j++) {
125+
if (arr[j] > arr[j + 1]) {
126+
// 交换元素
127+
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
128+
swapped = true;
129+
}
130+
}
131+
if (!swapped) break; // 优化:如果没有交换,提前结束
132+
}
133+
return arr;
134+
}`
135+
},
136+
selection: {
137+
description: '选择排序每次从未排序部分选择最小元素,放到已排序部分的末尾。虽然交换次数较少,但比较次数固定,不稳定排序。',
138+
bestCase: 'O(n²)',
139+
averageCase: 'O(n²)',
140+
worstCase: 'O(n²)',
141+
spaceComplexity: 'O(1)',
142+
stability: '不稳定',
143+
code: `function selectionSort(arr) {
144+
const n = arr.length;
145+
for (let i = 0; i < n - 1; i++) {
146+
let minIndex = i;
147+
for (let j = i + 1; j < n; j++) {
148+
if (arr[j] < arr[minIndex]) {
149+
minIndex = j;
150+
}
151+
}
152+
if (minIndex !== i) {
153+
// 交换元素
154+
[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
155+
}
156+
}
157+
return arr;
158+
}`
159+
},
160+
insertion: {
161+
description: '插入排序将数组分为已排序和未排序两部分,逐个将未排序元素插入到已排序部分的适当位置。对于部分有序数组效率很高。',
162+
bestCase: 'O(n)',
163+
averageCase: 'O(n²)',
164+
worstCase: 'O(n²)',
165+
spaceComplexity: 'O(1)',
166+
stability: '稳定',
167+
code: `function insertionSort(arr) {
168+
const n = arr.length;
169+
for (let i = 1; i < n; i++) {
170+
const key = arr[i];
171+
let j = i - 1;
172+
173+
while (j >= 0 && arr[j] > key) {
174+
arr[j + 1] = arr[j];
175+
j--;
176+
}
177+
arr[j + 1] = key;
178+
}
179+
return arr;
180+
}`
181+
},
182+
merge: {
183+
description: '归并排序采用分治策略,将数组分成两半,递归排序后再合并。时间复杂度稳定为O(nlogn),但需要额外空间。',
184+
bestCase: 'O(nlogn)',
185+
averageCase: 'O(nlogn)',
186+
worstCase: 'O(nlogn)',
187+
spaceComplexity: 'O(n)',
188+
stability: '稳定',
189+
code: `function mergeSort(arr) {
190+
if (arr.length <= 1) return arr;
191+
192+
const mid = Math.floor(arr.length / 2);
193+
const left = mergeSort(arr.slice(0, mid));
194+
const right = mergeSort(arr.slice(mid));
195+
196+
return merge(left, right);
197+
}
198+
199+
function merge(left, right) {
200+
const result = [];
201+
let leftIndex = 0, rightIndex = 0;
202+
203+
while (leftIndex < left.length && rightIndex < right.length) {
204+
if (left[leftIndex] < right[rightIndex]) {
205+
result.push(left[leftIndex]);
206+
leftIndex++;
207+
} else {
208+
result.push(right[rightIndex]);
209+
rightIndex++;
210+
}
211+
}
212+
213+
return result.concat(left.slice(leftIndex), right.slice(rightIndex));
214+
}`
215+
},
216+
quick: {
217+
description: '快速排序选择基准元素,将数组分为小于和大于基准的两部分,递归排序。平均性能极佳,但最坏情况下为O(n²)。',
218+
bestCase: 'O(nlogn)',
219+
averageCase: 'O(nlogn)',
220+
worstCase: 'O(n²)',
221+
spaceComplexity: 'O(logn)',
222+
stability: '不稳定',
223+
code: `function quickSort(arr, low = 0, high = arr.length - 1) {
224+
if (low < high) {
225+
const pivotIndex = partition(arr, low, high);
226+
quickSort(arr, low, pivotIndex - 1);
227+
quickSort(arr, pivotIndex + 1, high);
228+
}
229+
return arr;
230+
}
231+
232+
function partition(arr, low, high) {
233+
const pivot = arr[high];
234+
let i = low - 1;
235+
236+
for (let j = low; j < high; j++) {
237+
if (arr[j] < pivot) {
238+
i++;
239+
[arr[i], arr[j]] = [arr[j], arr[i]];
240+
}
241+
}
242+
243+
[arr[i + 1], arr[high]] = [arr[high], arr[i + 1]];
244+
return i + 1;
245+
}`
246+
},
247+
heap: {
248+
description: '堆排序利用堆数据结构,首先构建最大堆,然后重复取出堆顶元素。时间复杂度稳定为O(nlogn),空间效率高。',
249+
bestCase: 'O(nlogn)',
250+
averageCase: 'O(nlogn)',
251+
worstCase: 'O(nlogn)',
252+
spaceComplexity: 'O(1)',
253+
stability: '不稳定',
254+
code: `function heapSort(arr) {
255+
const n = arr.length;
256+
257+
// 构建最大堆
258+
for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
259+
heapify(arr, n, i);
260+
}
261+
262+
// 一个个从堆中取出元素
263+
for (let i = n - 1; i > 0; i--) {
264+
[arr[0], arr[i]] = [arr[i], arr[0]]; // 交换
265+
heapify(arr, i, 0);
266+
}
267+
268+
return arr;
269+
}
270+
271+
function heapify(arr, n, i) {
272+
let largest = i;
273+
const left = 2 * i + 1;
274+
const right = 2 * i + 2;
275+
276+
if (left < n && arr[left] > arr[largest]) {
277+
largest = left;
278+
}
279+
280+
if (right < n && arr[right] > arr[largest]) {
281+
largest = right;
282+
}
283+
284+
if (largest !== i) {
285+
[arr[i], arr[largest]] = [arr[largest], arr[i]];
286+
heapify(arr, n, largest);
287+
}
288+
}`
289+
}
290+
};
291+
292+
const info = algorithmInfo[algorithm];
293+
if (info) {
294+
description.textContent = info.description;
295+
bestCase.textContent = info.bestCase;
296+
averageCase.textContent = info.averageCase;
297+
worstCase.textContent = info.worstCase;
298+
spaceComplexity.textContent = info.spaceComplexity;
299+
stability.textContent = info.stability;
300+
code.textContent = info.code;
301+
}
302+
}
303+
304+
// 重置统计信息
305+
function resetStatistics() {
306+
document.getElementById('comparisons').textContent = '0';
307+
document.getElementById('swaps').textContent = '0';
308+
document.getElementById('executionTime').textContent = '0ms';
309+
document.getElementById('currentArraySize').textContent = arraySize;
310+
}
311+
312+
// 初始化动画
313+
function initializeAnimations() {
314+
// 页面加载动画
315+
anime({
316+
targets: '.performance-card',
317+
translateY: [50, 0],
318+
opacity: [0, 1],
319+
duration: 800,
320+
delay: anime.stagger(200),
321+
easing: 'easeOutQuart'
322+
});
323+
}
324+
325+
// 导航栏滚动效果
326+
window.addEventListener('scroll', function() {
327+
const nav = document.querySelector('nav');
328+
if (window.scrollY > 100) {
329+
nav.classList.add('bg-gray-900/95');
330+
} else {
331+
nav.classList.remove('bg-gray-900/95');
332+
}
333+
});
334+
335+
// 工具函数:睡眠函数用于动画控制
336+
function sleep(ms) {
337+
return new Promise(resolve => setTimeout(resolve, ms));
338+
}
339+
340+
// 工具函数:获取动画延迟时间
341+
function getAnimationDelay() {
342+
return Math.max(50, 1100 - animationSpeed * 100);
343+
}
344+
345+
// 导出函数供其他文件使用
346+
window.AlgorithmUtils = {
347+
currentArray,
348+
isSorting,
349+
animationSpeed,
350+
arraySize,
351+
generateNewArray,
352+
displayArray,
353+
sleep,
354+
getAnimationDelay,
355+
resetStatistics
356+
};

0 commit comments

Comments
 (0)