152 lines
4.6 KiB
Markdown
152 lines
4.6 KiB
Markdown
|
下面对归并排序和快速排序的每一行代码进行详细的解释。
|
|||
|
|
|||
|
---
|
|||
|
|
|||
|
### **归并排序代码详解**
|
|||
|
|
|||
|
#### 函数 `merge_sort`
|
|||
|
|
|||
|
```python
|
|||
|
def merge_sort(arr):
|
|||
|
if len(arr) <= 1:
|
|||
|
return arr
|
|||
|
```
|
|||
|
- **作用**:判断数组是否只有一个元素或为空。如果是,直接返回,因为这样的数组已经是有序的。
|
|||
|
- **意义**:递归终止条件,避免无限递归。
|
|||
|
|
|||
|
```python
|
|||
|
mid = len(arr) // 2
|
|||
|
```
|
|||
|
- **作用**:计算数组的中间位置,将数组分为左右两部分。
|
|||
|
- **意义**:分治算法的关键,将问题拆分为更小的子问题。
|
|||
|
|
|||
|
```python
|
|||
|
left_half = merge_sort(arr[:mid])
|
|||
|
right_half = merge_sort(arr[mid:])
|
|||
|
```
|
|||
|
- **作用**:对左半部分和右半部分递归调用 `merge_sort`,直到每部分只有一个元素。
|
|||
|
- **意义**:实现递归,最终将数组拆分到最小粒度。
|
|||
|
|
|||
|
```python
|
|||
|
return merge(left_half, right_half)
|
|||
|
```
|
|||
|
- **作用**:将左右两个已排序的部分合并为一个完整的排序数组。
|
|||
|
- **意义**:通过合并操作完成排序过程。
|
|||
|
|
|||
|
#### 函数 `merge`
|
|||
|
|
|||
|
```python
|
|||
|
def merge(left, right):
|
|||
|
result = []
|
|||
|
i = j = 0
|
|||
|
```
|
|||
|
- **作用**:
|
|||
|
- 初始化一个空数组 `result`,用来存储合并后的有序数组。
|
|||
|
- 初始化两个指针 `i` 和 `j`,分别指向左数组和右数组的起始位置。
|
|||
|
- **意义**:合并两个有序数组的准备工作。
|
|||
|
|
|||
|
```python
|
|||
|
while i < len(left) and j < len(right):
|
|||
|
if left[i] <= right[j]:
|
|||
|
result.append(left[i])
|
|||
|
i += 1
|
|||
|
else:
|
|||
|
result.append(right[j])
|
|||
|
j += 1
|
|||
|
```
|
|||
|
- **作用**:
|
|||
|
- 比较两个数组的当前元素,将较小的元素加入 `result` 中。
|
|||
|
- 相应的指针 (`i` 或 `j`) 向前移动。
|
|||
|
- **意义**:通过比较大小,确保合并后的数组有序。
|
|||
|
|
|||
|
```python
|
|||
|
result.extend(left[i:])
|
|||
|
result.extend(right[j:])
|
|||
|
```
|
|||
|
- **作用**:
|
|||
|
- 将剩余的元素(可能只在一个数组中剩余)加入 `result` 中。
|
|||
|
- **意义**:处理合并过程中较长数组的剩余部分。
|
|||
|
|
|||
|
---
|
|||
|
|
|||
|
### **快速排序代码详解**
|
|||
|
|
|||
|
```python
|
|||
|
def quick_sort(arr):
|
|||
|
if len(arr) <= 1:
|
|||
|
return arr
|
|||
|
```
|
|||
|
- **作用**:判断数组是否只有一个元素或为空。如果是,直接返回。
|
|||
|
- **意义**:递归终止条件,避免无限递归。
|
|||
|
|
|||
|
```python
|
|||
|
pivot = arr[len(arr) // 2]
|
|||
|
```
|
|||
|
- **作用**:选择数组的中间元素作为基准。
|
|||
|
- **意义**:基准元素是快速排序的核心,用于将数组划分为左右两部分。
|
|||
|
|
|||
|
```python
|
|||
|
left = [x for x in arr if x < pivot]
|
|||
|
middle = [x for x in arr if x == pivot]
|
|||
|
right = [x for x in arr if x > pivot]
|
|||
|
```
|
|||
|
- **作用**:
|
|||
|
- 使用列表推导式将数组分为三个部分:
|
|||
|
- `left`:比基准小的元素。
|
|||
|
- `middle`:与基准相等的元素。
|
|||
|
- `right`:比基准大的元素。
|
|||
|
- **意义**:实现划分步骤,确保数组被分割为有序的三部分。
|
|||
|
|
|||
|
```python
|
|||
|
return quick_sort(left) + middle + quick_sort(right)
|
|||
|
```
|
|||
|
- **作用**:
|
|||
|
- 对 `left` 和 `right` 两部分递归调用快速排序。
|
|||
|
- 将已排序的 `left`、`middle` 和 `right` 拼接为最终的结果。
|
|||
|
- **意义**:通过递归完成整个快速排序过程。
|
|||
|
|
|||
|
---
|
|||
|
|
|||
|
### **测试代码详解**
|
|||
|
|
|||
|
```python
|
|||
|
if __name__ == "__main__":
|
|||
|
import random
|
|||
|
```
|
|||
|
- **作用**:表示以下代码块仅在直接运行文件时执行,而在导入模块时不会执行。
|
|||
|
- **意义**:增强代码的复用性。
|
|||
|
|
|||
|
```python
|
|||
|
test_array = [random.randint(0, 100) for _ in range(10)]
|
|||
|
```
|
|||
|
- **作用**:生成一个包含 10 个随机整数的数组,范围在 0 到 100 之间。
|
|||
|
- **意义**:为测试排序算法创建样例数据。
|
|||
|
|
|||
|
```python
|
|||
|
print("原始数组:", test_array)
|
|||
|
```
|
|||
|
- **作用**:打印未排序的原始数组。
|
|||
|
- **意义**:用于与排序后的结果进行对比,验证算法的正确性。
|
|||
|
|
|||
|
```python
|
|||
|
sorted_array_merge = merge_sort(test_array)
|
|||
|
print("归并排序结果:", sorted_array_merge)
|
|||
|
```
|
|||
|
- **作用**:
|
|||
|
- 调用归并排序对数组进行排序。
|
|||
|
- 打印归并排序后的结果。
|
|||
|
- **意义**:测试归并排序的正确性。
|
|||
|
|
|||
|
```python
|
|||
|
sorted_array_quick = quick_sort(test_array)
|
|||
|
print("快速排序结果:", sorted_array_quick)
|
|||
|
```
|
|||
|
- **作用**:
|
|||
|
- 调用快速排序对数组进行排序。
|
|||
|
- 打印快速排序后的结果。
|
|||
|
- **意义**:测试快速排序的正确性。
|
|||
|
|
|||
|
---
|
|||
|
|
|||
|
### 总结
|
|||
|
通过逐行解释,我们清楚地理解了代码中每一步的作用和意义。整个实验通过递归、分治思想实现了两个经典排序算法:归并排序和快速排序。
|