Skip to content

Commit f973794

Browse files
committed
main update
1 parent 4c1a24a commit f973794

File tree

6 files changed

+359
-80
lines changed

6 files changed

+359
-80
lines changed

backend/app.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from flask import Flask, request, jsonify
2+
from flask_cors import CORS
3+
import sys
4+
import os
5+
6+
# Add the parent directory to Python path to import playground
7+
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
8+
from backend.services.playground import bubble_sort, insertion_sort, selection_sort, quick_sort, merge_sort, shell_sort, heap_sort
9+
10+
app = Flask(__name__)
11+
CORS(app)
12+
13+
# Global variable to store sorting steps
14+
sorting_steps = []
15+
16+
def clear_steps():
17+
global sorting_steps
18+
sorting_steps = []
19+
20+
def add_step(step):
21+
global sorting_steps
22+
sorting_steps.append(step)
23+
24+
# Modify the original print statements to store steps
25+
def custom_print(message):
26+
add_step(message)
27+
28+
@app.route('/api/sort', methods=['POST'])
29+
def sort():
30+
data = request.get_json()
31+
numbers = data.get('numbers', [])
32+
method = data.get('method', 'bubble')
33+
34+
# Clear previous steps
35+
clear_steps()
36+
37+
# Create a copy of the numbers to avoid modifying the original
38+
numbers_copy = numbers.copy()
39+
40+
# Dictionary of sorting functions
41+
sort_functions = {
42+
'bubble': bubble_sort,
43+
'insertion': insertion_sort,
44+
'selection': selection_sort,
45+
'merge': merge_sort,
46+
'quick': quick_sort,
47+
'shell': shell_sort,
48+
'heap': heap_sort
49+
}
50+
51+
if method not in sort_functions:
52+
return jsonify({'error': 'Invalid sorting method'}), 400
53+
54+
# Temporarily redirect print output to our custom function
55+
import builtins
56+
original_print = builtins.print
57+
builtins.print = custom_print
58+
59+
try:
60+
# Run the sorting algorithm
61+
sorted_numbers = sort_functions[method](numbers_copy)
62+
63+
# Restore original print function
64+
builtins.print = original_print
65+
66+
return jsonify({
67+
'sorted': sorted_numbers,
68+
'steps': sorting_steps
69+
})
70+
except Exception as e:
71+
builtins.print = original_print
72+
return jsonify({'error': str(e)}), 500
73+
74+
if __name__ == '__main__':
75+
app.run(debug=True, port=5000)

playground.py renamed to backend/services/playground.py

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,32 +24,55 @@ def selection_sort(a):
2424
print(f"选择交换 {a[i]}{a[min_idx]},当前序列:{a}")
2525
return a
2626

27-
def quick_sort(a):
28-
if len(a) <= 1:
27+
def quick_sort(a, start=None, end=None):
28+
if start is None:
29+
start = 0
30+
end = len(a) - 1
31+
32+
if start >= end:
2933
return a
30-
pivot = a[len(a)//2]
31-
left = [x for x in a if x < pivot]
32-
middle = [x for x in a if x == pivot]
33-
right = [x for x in a if x > pivot]
34-
return quick_sort(left) + middle + quick_sort(right)
34+
35+
pivot = a[end]
36+
i = start - 1
37+
38+
for j in range(start, end):
39+
if a[j] <= pivot:
40+
i += 1
41+
if i != j:
42+
a[i], a[j] = a[j], a[i]
43+
print(f"快速排序交换 {a[i]}{a[j]},当前序列:{a}")
44+
45+
a[i + 1], a[end] = a[end], a[i + 1]
46+
if i + 1 != end:
47+
print(f"快速排序放置基准 {a[i + 1]},当前序列:{a}")
48+
49+
quick_sort(a, start, i)
50+
quick_sort(a, i + 2, end)
51+
return a
3552

3653
def merge_sort(a):
3754
if len(a) <= 1:
3855
return a
39-
mid = len(a)//2
56+
57+
mid = len(a) // 2
4058
left = merge_sort(a[:mid])
4159
right = merge_sort(a[mid:])
42-
return merge(left, right)
60+
print(f"归并排序分解:左半部分 {left},右半部分 {right}")
61+
result = merge(left, right)
62+
print(f"归并排序合并结果:{result}")
63+
return result
4364

4465
def merge(left, right):
4566
result = []
4667
i = j = 0
4768
while i < len(left) and j < len(right):
4869
if left[i] < right[j]:
4970
result.append(left[i])
71+
print(f"归并取左边元素 {left[i]}")
5072
i += 1
5173
else:
5274
result.append(right[j])
75+
print(f"归并取右边元素 {right[j]}")
5376
j += 1
5477
result.extend(left[i:])
5578
result.extend(right[j:])
@@ -59,13 +82,17 @@ def shell_sort(a):
5982
n = len(a)
6083
gap = n // 2
6184
while gap > 0:
85+
print(f"希尔排序当前间隔:{gap}")
6286
for i in range(gap, n):
6387
temp = a[i]
6488
j = i
6589
while j >= gap and a[j - gap] > temp:
6690
a[j] = a[j - gap]
91+
print(f"希尔排序移动 {a[j]}→位置{j},当前序列:{a}")
6792
j -= gap
6893
a[j] = temp
94+
if j != i:
95+
print(f"希尔排序插入 {temp}到位置{j},当前序列:{a}")
6996
gap //= 2
7097
return a
7198

@@ -74,20 +101,29 @@ def heapify(a, n, i):
74101
largest = i
75102
l = 2 * i + 1
76103
r = 2 * i + 2
104+
77105
if l < n and a[i] < a[l]:
78106
largest = l
79107
if r < n and a[largest] < a[r]:
80108
largest = r
109+
81110
if largest != i:
82111
a[i], a[largest] = a[largest], a[i]
112+
print(f"堆排序调整 {a[i]}{a[largest]},当前序列:{a}")
83113
heapify(a, n, largest)
84114

85115
n = len(a)
116+
# Build max heap
86117
for i in range(n//2 - 1, -1, -1):
87118
heapify(a, n, i)
119+
print(f"堆排序建堆阶段,当前序列:{a}")
120+
121+
# Extract elements from heap one by one
88122
for i in range(n-1, 0, -1):
89123
a[i], a[0] = a[0], a[i]
124+
print(f"堆排序取出最大值 {a[i]},当前序列:{a}")
90125
heapify(a, i, 0)
126+
91127
return a
92128

93129
if __name__ == "__main__":

frontend/index.html

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,54 @@
11
<!DOCTYPE html>
2-
<html lang="zh">
2+
<html lang="en">
33
<head>
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<title>我的网站</title>
6+
<title>Sorting Visualizer</title>
77
<link rel="stylesheet" href="styles.css">
88
</head>
99
<body>
10-
<h1>欢迎访问我的网站</h1>
11-
<button onclick="showMessage()">点我</button>
12-
<p id="msg"></p>
10+
<div class="container">
11+
<h1>Sorting Visualizer</h1>
12+
13+
<div class="input-section">
14+
<div class="method-selector">
15+
<label for="sortMethod">Select Sorting Method:</label>
16+
<select id="sortMethod">
17+
<option value="bubble">Bubble Sort</option>
18+
<option value="insertion">Insertion Sort</option>
19+
<option value="selection">Selection Sort</option>
20+
<option value="merge">Merge Sort</option>
21+
<option value="quick">Quick Sort</option>
22+
<option value="shell">Shell Sort</option>
23+
<option value="heap">Heap Sort</option>
24+
</select>
25+
</div>
1326

27+
<div class="numbers-input">
28+
<label>Enter 5 Numbers:</label>
29+
<div class="input-group">
30+
<input type="number" class="number-input" placeholder="Number 1">
31+
<input type="number" class="number-input" placeholder="Number 2">
32+
<input type="number" class="number-input" placeholder="Number 3">
33+
<input type="number" class="number-input" placeholder="Number 4">
34+
<input type="number" class="number-input" placeholder="Number 5">
35+
</div>
36+
</div>
37+
38+
<button id="sortButton">Sort Numbers</button>
39+
</div>
40+
41+
<div class="output-section">
42+
<div class="steps-container">
43+
<h2>Sorting Steps:</h2>
44+
<div id="sortingSteps" class="steps-list"></div>
45+
</div>
46+
<div class="result-container">
47+
<h2>Final Result:</h2>
48+
<div id="sortingResult" class="result"></div>
49+
</div>
50+
</div>
51+
</div>
1452
<script src="script.js"></script>
1553
</body>
1654
</html>

frontend/script.js

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,66 @@
1-
function showMessage() {
2-
document.getElementById("msg").innerText = "你点击了按钮!";
3-
}
1+
document.addEventListener('DOMContentLoaded', function() {
2+
const sortButton = document.getElementById('sortButton');
3+
const sortingSteps = document.getElementById('sortingSteps');
4+
const sortingResult = document.getElementById('sortingResult');
5+
6+
sortButton.addEventListener('click', async function() {
7+
// Clear previous results
8+
sortingSteps.innerHTML = '';
9+
sortingResult.innerHTML = '';
10+
11+
// Get selected sort method
12+
const method = document.getElementById('sortMethod').value;
13+
14+
// Get numbers from inputs
15+
const numbers = Array.from(document.querySelectorAll('.number-input'))
16+
.map(input => parseInt(input.value));
17+
18+
// Validate inputs
19+
if (numbers.some(isNaN)) {
20+
alert('Please enter valid numbers in all fields');
21+
return;
22+
}
23+
24+
try {
25+
// Disable button while sorting
26+
sortButton.disabled = true;
27+
sortButton.textContent = 'Sorting...';
28+
29+
// Send request to backend
30+
const response = await fetch('http://localhost:5000/api/sort', {
31+
method: 'POST',
32+
headers: {
33+
'Content-Type': 'application/json',
34+
},
35+
body: JSON.stringify({
36+
method: method,
37+
numbers: numbers
38+
})
39+
});
40+
41+
const data = await response.json();
42+
43+
if (data.error) {
44+
throw new Error(data.error);
45+
}
46+
47+
// Display sorting steps
48+
data.steps.forEach((step, index) => {
49+
const stepElement = document.createElement('div');
50+
stepElement.className = 'step-item';
51+
stepElement.textContent = `Step ${index + 1}: ${step}`;
52+
sortingSteps.appendChild(stepElement);
53+
});
54+
55+
// Display final result
56+
sortingResult.textContent = `[${data.sorted.join(', ')}]`;
57+
58+
} catch (error) {
59+
sortingResult.textContent = `Error: ${error.message}`;
60+
} finally {
61+
// Re-enable button
62+
sortButton.disabled = false;
63+
sortButton.textContent = 'Sort Numbers';
64+
}
65+
});
66+
});

0 commit comments

Comments
 (0)