八大排序算法简单讲解和实现

冒泡排序(Bubble Sort)是最简单、最经典的排序算法之一。它的基本思想是重复地遍历要排序的列表,每次比较相邻的两个元素,如果顺序不正确则交换它们。冒泡排序的时间复杂度最好、最坏和平均情况下都为O(n^2),空间复杂度为O(1)。

void bubbleSort(vector<int>& nums) {
    int n = nums.size();
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (nums[j] > nums[j + 1]) {
                swap(nums[j], nums[j + 1]);
            }
        }
    }
}

选择排序(Selection Sort)每次从未排序的列表中选择最小(或最大)的元素,然后将其放置在已排序列表的末尾。选择排序的时间复杂度也是O(n^2),空间复杂度为O(1)。

void selectionSort(vector<int>& nums) {
    int n = nums.size();
    for (int i = 0; i < n - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < n; j++) {
            if (nums[j] < nums[minIndex]) {
                minIndex = j;
            }
        }
        swap(nums[i], nums[minIndex]);
    }
}

插入排序(Insertion Sort)将列表分为已排序和未排序两部分,每次从未排序部分选择一个元素插入到已排序部分的合适位置。插入排序的时间复杂度最好情况下为O(n),最坏和平均情况下为O(n^2),空间复杂度为O(1)。

void insertionSort(vector<int>& nums) {
    int n = nums.size();
    for (int i = 1; i < n; i++) {
        int key = nums[i];
        int j = i - 1;
        while (j >= 0 && nums[j] > key) {
            nums[j + 1] = nums[j];
            j--;
        }
        nums[j + 1] = key;
    }
}

希尔排序(Shell Sort)是对插入排序的一种改进,它将列表分成几个子列表进行插入排序,每次逐步缩小子列表的长度。希尔排序的时间复杂度依赖于所选用的间隔序列,最坏情况下为O(n^2),平均情况下为O(n log n),空间复杂度为O(1)。

void shellSort(vector<int>& nums) {
    int n = nums.size();
    for (int gap = n / 2; gap > 0; gap /= 2) {
        for(int i = gap; i < n; i++) {
            int temp = nums[i];
            int j;
            for(j = i; j >= gap && nums[j - gap] > temp; j -= gap) {
                nums[j] = nums[j - gap];
            }
            nums[j] = temp;
        }
    }
}

归并排序(Merge Sort)采用分而治之的策略,将列表逐步分成较小的子列表,然后通过合并这些子列表来完成排序。归并排序的时间复杂度在任何情况下都是O(n log n),空间复杂度为O(n)。

void merge(vector<int>& nums, int left, int mid, int right) {
    int n1 = mid - left + 1;
    int n2 = right - mid;
    vector<int> L(n1), R(n2);
    
    for (int i = 0; i < n1; i++) {
        L[i] = nums[left + i];
    }
    for (int j = 0; j < n2; j++) {
        R[j] = nums[mid + 1 + j];
    }
    
    int i = 0, j = 0, k = left;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            nums[k] = L[i++];
        } else {
            nums[k] = R[j++];
        }
        k++;
    }
    
    while (i < n1) {
        nums[k++] = L[i++];
    }
    while (j < n2) {
        nums[k++] = R[j++];
    }
}

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

快速排序(Quick Sort)也是一种分而治之的排序算法,通过选择一个基准值,将列表分为小于基准值和大于基准值的两部分,然后再对这两部分分别进行快速排序。快速排序的时间复杂度最好情况下为O(n log n),最坏情况下为O(n^2),平均情况下为O(n log n)。空间复杂度为O(1)。

int partition(vector<int>& nums, int low, int high) {
    int pivot = nums[high];
    int i = low - 1;
    
    for (int j = low; j < high; j++) {
        if (nums[j] < pivot) {
            i++;
            swap(nums[i], nums[j]);
        }
    }
    
    swap(nums[i + 1], nums[high]);
    return i + 1;
}

void quickSort(vector<int>& nums, int low, int high) {
    if (low < high) {
        int pivotIndex = partition(nums, low, high);
        quickSort(nums, low, pivotIndex - 1);
        quickSort(nums, pivotIndex + 1, high);
    }
}

堆排序(Heap Sort)利用堆这种数据结构进行排序,首先构建一个最大(或最小)堆,然后依次将堆顶元素与列表末尾的元素交换并重新调整堆。堆排序的时间复杂度为O(n log n),空间复杂度为O(1)。

void heapify(vector<int>& nums, int n, int i) {
    int largest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;
    
    if (left < n && nums[left] > nums[largest]) {
        largest = left;
    }
    
    if (right < n && nums[right] > nums[largest]) {
        largest = right;
    }
    
    if (largest != i) {
        swap(nums[i], nums[largest]);
        heapify(nums, n, largest);
    }
}

void heapSort(vector<int>& nums) {
    int n = nums.size();
    
    for (int i = n / 2 - 1; i >= 0; i--) {
        heapify(nums, n, i);
    }
    
    for (int i = n - 1; i > 0; i--) {
        swap(nums[0], nums[i]);
        heapify(nums, i, 0);
    }
}

基数排序(Counting Sort)是一种非比较性的排序算法,根据每个元素的出现次数进行排序。它的时间复杂度为O(n + k),其中n是列表的长度,k是列表中的最大值。空间复杂度为O(n + k)。

以上就是八大排序算法的讲解以及它们的时间复杂度和空间复杂度。希望对您有所帮助!如有其他问题,请随时提问

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值