### **归并排序的时间和空间复杂度计算** #### **时间复杂度计算** 归并排序遵循分治思想,将数组分为两半递归处理,然后合并两个有序数组。 1. **分解过程** - 将数组分为两半,分解所需的时间是常数级别的 \(O(1)\)。 - 每次分解数组的大小减半,分解的层数为 \(\log_2 n\),因此分解过程的时间复杂度为 \(O(\log n)\)。 2. **合并过程** - 每层需要合并 \(n\) 个元素,合并操作为线性时间 \(O(n)\)。 - 合并层数与分解层数相同,也为 \(\log_2 n\)。 3. **总时间复杂度** - 每层合并耗时 \(O(n)\),共有 \(\log_2 n\) 层。 - 因此,总时间复杂度为: \[ T(n) = O(n \log n) \] --- #### **空间复杂度计算** 1. **临时数组** - 在合并过程中,需要额外的数组来存储左右子数组。每次合并的数组总大小是 \(n\)。 - 因此,临时数组占用的空间复杂度为 \(O(n)\)。 2. **递归栈空间** - 每次递归调用会占用栈空间,递归深度为 \(\log_2 n\)。 - 递归栈空间的复杂度为 \(O(\log n)\)。 3. **总空间复杂度** - 临时数组和递归栈空间的复杂度之和为: \[ O(n) + O(\log n) = O(n) \] --- ### **快速排序的时间和空间复杂度计算** #### **时间复杂度计算** 快速排序通过选择一个基准元素,将数组分为两部分,然后递归处理这两部分。 1. **划分过程** - 每次划分时,需要遍历整个数组来确定小于和大于基准的部分。 - 划分的时间复杂度为 \(O(n)\)。 2. **递归深度** - **最好情况**:每次划分将数组均匀分成两部分,递归深度为 \(\log_2 n\)。 - **最坏情况**:每次划分时,只有一个元素进入子数组,递归深度为 \(n\)。 3. **总时间复杂度** - **最好情况**: \[ T(n) = n + \frac{n}{2} + \frac{n}{4} + \cdots + 1 = O(n \log n) \] - **最坏情况**: \[ T(n) = n + (n-1) + (n-2) + \cdots + 1 = O(n^2) \] - **平均情况**: 通过数学期望分析,平均时间复杂度为 \(O(n \log n)\)。 --- #### **空间复杂度计算** 1. **原地排序** - 快速排序在划分数组时,直接在原数组上操作,因此额外空间复杂度为 \(O(1)\)。 2. **递归栈空间** - **最好情况**:划分均匀时,递归深度为 \(\log_2 n\),栈空间复杂度为 \(O(\log n)\)。 - **最坏情况**:每次划分仅一个元素进入子数组,递归深度为 \(n\),栈空间复杂度为 \(O(n)\)。 3. **总空间复杂度** - **最好情况**: \[ O(\log n) \] - **最坏情况**: \[ O(n) \] --- ### **对比总结** | **算法** | **时间复杂度(最好)** | **时间复杂度(最坏)** | **时间复杂度(平均)** | **空间复杂度(额外)** | |----------------|------------------------|------------------------|------------------------|------------------------| | **归并排序** | \(O(n \log n)\) | \(O(n \log n)\) | \(O(n \log n)\) | \(O(n)\) | | **快速排序** | \(O(n \log n)\) | \(O(n^2)\) | \(O(n \log n)\) | \(O(\log n)\) | 通过以上计算,快速排序在平均情况下效率更高,但需要优化基准选择以避免最坏情况。归并排序虽然时间复杂度稳定,但占用更多的空间。