抱佛脚-刷题系列之排序

抱佛脚一时爽,一直抱佛脚一直爽!这篇文章总结常见的排序算法~
参考链接:leetcode 剑指offer

算法总结


参见 幺幺山的博客

选择排序


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

冒泡排序


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

插入排序


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

希尔排序


void shellSort(vector<int>& nums) {
    int n = nums.size();
    for (int h = n / 2; h >= 1; h /= 2) {
        for (int i = h; i < n; ++i) {
            for (int j = i; j >= h && nums[j] < nums[j - h]; j -= h) {
                swap(nums[j], nums[j - h]);
            }
        }
    }
}

归并排序


void sort(vector<int>& nums) {
    mergeSort(nums, 0, nums.size() - 1);
}

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

void merge(vector<int>& nums, int l, int mid, int r) {
    vector<int> tmp(l - r + 1);
    int i = l, j = mid + 1, k = 0;
    while (i <= mid && j <= r) {
        if (nums[i] <= nums[j]) tmp[k++] = nums[i++];
        else tmp[k++] = nums[j++];
    }
    while (i <= mid) tmp[k++] = nums[i++];
    while (j <= r) tmp[k++] = nums[j++];
    for (k = 0, i = l; i <= r; ++i, ++k) {
        nums[i] = tmp[k];
    }
}

快速排序


void sort(vector<int>& nums) {
    quickSort(nums, 0, nums.size() - 1);
}

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

int partition(vector<int>& nums, int low, int high) {
    int pivot = nums[low];
    while (low < high) {
        while (low < high && nums[high] >= pivot) --high;
        nums[low] = nums[high];
        while (low < high && nums[low] <= pivot) ++low;
        nums[high] = nums[low];
    }
    nums[low] = pivot;
    return low;
}

堆排序


概述

  • 堆中某个节点的值总是大于等于其子节点的值,并且堆是一颗完全二叉树
  • 位置 k 的节点的父节点位置为 k/2,而它的两个子节点的位置分别为 2k 和 2k+1;这里不使用数组索引为 0 的位置

插入元素

  • 将新元素放到数组末尾,然后上浮到合适的位置
  • 从位置k上浮的代码:
void swim(int k) {
    while (k > 1 && nums[k] > nums[k / 2]) {
        swap(nums[k], nums[k / 2]);
        k /= 2;
    }
}

删除最大元素

  • 从数组顶端删除最大的元素,并将数组的最后一个元素放到顶端,并让这个元素下沉到合适的位置
  • 从位置k下沉的代码:
void sink(int k) {
    while (k * 2 < nums.size()) {
        int j = k * 2;
        if (j + 1 < nums.size() && nums[j] < nums[j + 1]) ++j;
        swap(nums[k], nums[j]);
        k = j;
    }
}

堆排序

void heapSort(vector<int> nums) {
    for (int i = (nums.size() - 1) / 2; i >= 1; --i) { // 处理非叶子节点
        sink(i);
    }
    for (int i = nums.size() - 1; i > 1; --i) {
        swap(nums[i], nums[1]);
        sink(1);
    }
}

桶排序

计数排序

https://www.cnblogs.com/kyoner/p/10604781.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。