解题思路

三种排序算法分析

一、冒泡排序 (Bubble Sort)

1. 基本原理

- 比较相邻的两个元素,如果前者大于后者则交换
- 每一轮将最大的元素"冒泡"到末尾
- 重复n-1轮,直到所有元素有序

2. 时间复杂度

  • 最好情况,数组已经有序
  • 最坏情况,数组逆序
  • 平均情况
  • 空间复杂度
  • 稳定性:稳定

3. 代码框架

for(int i = 0; i < n-1; i++) {
    for(int j = 0; j < n-1-i; j++) {
        if(arr[j] > arr[j+1]) {
            swap(arr[j], arr[j+1]);
        }
    }
}

二、快速排序 (Quick Sort)

1. 基本原理

- 选择基准元素(pivot)
- 将数组分为两部分:小于pivot和大于pivot
- 递归对两部分进行排序
- 最终合并得到有序数组

2. 时间复杂度

  • 最好情况,每次都平分数组
  • 最坏情况,已经有序或逆序
  • 平均情况
  • 空间复杂度,递归栈空间
  • 稳定性:不稳定

3. 代码框架

void quickSort(int left, int right) {
    if(left >= right) return;
    int pivot = partition(left, right);
    quickSort(left, pivot-1);
    quickSort(pivot+1, right);
}

三、归并排序 (Merge Sort)

1. 基本原理

- 将数组分成两半
- 递归排序两个子数组
- 合并两个有序数组
- 最终得到完整有序数组

2. 时间复杂度

  • 最好情况
  • 最坏情况
  • 平均情况
  • 空间复杂度,需要临时数组
  • 稳定性:稳定

3. 代码框架

void mergeSort(int left, int right) {
    if(left >= right) return;
    int mid = left + (right-left)/2;
    mergeSort(left, mid);
    mergeSort(mid+1, right);
    merge(left, mid, right);
}

四、比较分析

1. 时间效率

  • 小数据量:冒泡 ≈ 快速 ≈ 归并
  • 大数据量:快速 ≈ 归并 >> 冒泡
  • 平均性能:快速 > 归并 > 冒泡

2. 空间效率

  • 冒泡:,原地排序
  • 快速:,递归栈空间
  • 归并:,需要临时数组

3. 稳定性

  • 冒泡:稳定
  • 快速:不稳定
  • 归并:稳定

4. 适用场景

  1. 冒泡排序

    • 数据量小
    • 要求稳定
    • 代码简单
  2. 快速排序

    • 数据量大
    • 不要求稳定
    • 平均性能最好
  3. 归并排序

    • 数据量大
    • 要求稳定
    • 外部排序

5. 优化方向

  1. 冒泡排序

    • 提前退出标志
    • 记录最后交换位置
  2. 快速排序

    • 三数取中选择pivot
    • 处理重复元素
    • 小数组使用插入排序
  3. 归并排序

    • 小数组使用插入排序
    • 优化临时数组分配
    • 避免重复拷贝

代码

O(n²) 解法 - 冒泡排序

class Solution {
public:
    vector<int> MySort(vector<int>& arr) {
        int n = arr.size();
        for(int i = 0; i < n-1; i++) {
            for(int j = 0; j < n-1-i; j++) {
                if(arr[j] > arr[j+1]) {
                    swap(arr[j], arr[j+1]);
                }
            }
        }
        return arr;
    }
};
public class Solution {
    public int[] MySort (int[] arr) {
        int n = arr.length;
        for(int i = 0; i < n-1; i++) {
            for(int j = 0; j < n-1-i; j++) {
                if(arr[j] > arr[j+1]) {
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
        return arr;
    }
}
class Solution:
    def MySort(self , arr: List[int]) -> List[int]:
        n = len(arr)
        for i in range(n-1):
            for j in range(n-1-i):
                if arr[j] > arr[j+1]:
                    arr[j], arr[j+1] = arr[j+1], arr[j]
        return arr

O(nlogn) 解法 - 快速排序

class Solution {
public:
    void quickSort(vector<int>& arr, int left, int right) {
        if(left >= right) return;
        
        int pivot = arr[left];
        int i = left, j = right;
        
        while(i < j) {
            while(i < j && arr[j] >= pivot) j--;
            while(i < j && arr[i] <= pivot) i++;
            if(i < j) swap(arr[i], arr[j]);
        }
        arr[left] = arr[i];
        arr[i] = pivot;
        
        quickSort(arr, left, i-1);
        quickSort(arr, i+1, right);
    }
    
    vector<int> MySort(vector<int>& arr) {
        quickSort(arr, 0, arr.size()-1);
        return arr;
    }
};
public class Solution {
    public void quickSort(int[] arr, int left, int right) {
        if(left >= right) return;
        
        int pivot = arr[left];
        int i = left, j = right;
        
        while(i < j) {
            while(i < j && arr[j] >= pivot) j--;
            while(i < j && arr[i] <= pivot) i++;
            if(i < j) {
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
        arr[left] = arr[i];
        arr[i] = pivot;
        
        quickSort(arr, left, i-1);
        quickSort(arr, i+1, right);
    }
    
    public int[] MySort(int[] arr) {
        quickSort(arr, 0, arr.length-1);
        return arr;
    }
}
class Solution:
    def quickSort(self, arr: List[int], left: int, right: int):
        if left >= right:
            return
            
        pivot = arr[left]
        i, j = left, right
        
        while i < j:
            while i < j and arr[j] >= pivot:
                j -= 1
            while i < j and arr[i] <= pivot:
                i += 1
            if i < j:
                arr[i], arr[j] = arr[j], arr[i]
        
        arr[left] = arr[i]
        arr[i] = pivot
        
        self.quickSort(arr, left, i-1)
        self.quickSort(arr, i+1, right)
    
    def MySort(self, arr: List[int]) -> List[int]:
        self.quickSort(arr, 0, len(arr)-1)
        return arr

归并排序 O(nlogn)

class Solution {
private:
    void merge(vector<int>& arr, int left, int mid, int right, vector<int>& temp) {
        int i = left, j = mid + 1;
        int k = left;
        
        while(i <= mid && j <= right) {
            if(arr[i] <= arr[j]) {
                temp[k++] = arr[i++];
            } else {
                temp[k++] = arr[j++];
            }
        }
        
        while(i <= mid) temp[k++] = arr[i++];
        while(j <= right) temp[k++] = arr[j++];
        
        for(i = left; i <= right; i++) {
            arr[i] = temp[i];
        }
    }
    
    void mergeSort(vector<int>& arr, int left, int right, vector<int>& temp) {
        if(left < right) {
            int mid = left + (right - left) / 2;
            mergeSort(arr, left, mid, temp);
            mergeSort(arr, mid + 1, right, temp);
            merge(arr, left, mid, right, temp);
        }
    }
    
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 将给定数组排序
     * @param arr int整型vector 待排序的数组
     * @return int整型vector
     */
    vector<int> MySort(vector<int>& arr) {
        vector<int> temp(arr.size());
        mergeSort(arr, 0, arr.size() - 1, temp);
        return arr;
    }
};
import java.util.*;

public class Solution {
    /**
     * 合并两个有序区间
     */
    private void merge(int[] arr, int left, int mid, int right, int[] temp) {
        int i = left;    // 左半部分起始位置
        int j = mid + 1; // 右半部分起始位置
        int k = left;    // 临时数组起始位置
        
        // 合并两个有序区间
        while(i <= mid && j <= right) {
            if(arr[i] <= arr[j]) {
                temp[k++] = arr[i++];
            } else {
                temp[k++] = arr[j++];
            }
        }
        
        // 处理剩余元素
        while(i <= mid) {
            temp[k++] = arr[i++];
        }
        while(j <= right) {
            temp[k++] = arr[j++];
        }
        
        // 将临时数组中的元素复制回原数组
        for(i = left; i <= right; i++) {
            arr[i] = temp[i];
        }
    }
    
    /**
     * 递归进行归并排序
     */
    private void mergeSort(int[] arr, int left, int right, int[] temp) {
        if(left < right) {
            int mid = left + (right - left) / 2;
            // 递归排序左半部分
            mergeSort(arr, left, mid, temp);
            // 递归排序右半部分
            mergeSort(arr, mid + 1, right, temp);
            // 合并两个有序部分
            merge(arr, left, mid, right, temp);
        }
    }
    
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 将给定数组排序
     * @param arr int整型一维数组 待排序的数组
     * @return int整型一维数组
     */
    public int[] MySort (int[] arr) {
        if(arr == null || arr.length <= 1) {
            return arr;
        }
        // 创建临时数组
        int[] temp = new int[arr.length];
        // 调用归并排序
        mergeSort(arr, 0, arr.length - 1, temp);
        return arr;
    }
}
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 将给定数组排序
# @param arr int整型一维数组 待排序的数组
# @return int整型一维数组
#
class Solution:
    def merge(self, arr: List[int], left: int, mid: int, right: int, temp: List[int]):
        """
        合并两个有序区间
        """
        i = left       # 左半部分起始位置
        j = mid + 1    # 右半部分起始位置
        k = left       # 临时数组起始位置
        
        # 合并两个有序区间
        while i <= mid and j <= right:
            if arr[i] <= arr[j]:
                temp[k] = arr[i]
                i += 1
            else:
                temp[k] = arr[j]
                j += 1
            k += 1
        
        # 处理剩余元素
        while i <= mid:
            temp[k] = arr[i]
            k += 1
            i += 1
        while j <= right:
            temp[k] = arr[j]
            k += 1
            j += 1
        
        # 将临时数组中的元素复制回原数组
        for i in range(left, right + 1):
            arr[i] = temp[i]
    
    def mergeSort(self, arr: List[int], left: int, right: int, temp: List[int]):
        """
        递归进行归并排序
        """
        if left < right:
            mid = left + (right - left) // 2
            # 递归排序左半部分
            self.mergeSort(arr, left, mid, temp)
            # 递归排序右半部分
            self.mergeSort(arr, mid + 1, right, temp)
            # 合并两个有序部分
            self.merge(arr, left, mid, right, temp)
    
    def MySort(self, arr: List[int]) -> List[int]:
        """
        主函数:归并排序入口
        """
        if not arr or len(arr) <= 1:
            return arr
        # 创建临时数组
        temp = [0] * len(arr)
        # 调用归并排序
        self.mergeSort(arr, 0, len(arr) - 1, temp)
        return arr