赞
踩
/*选择排序*/ void select_sort(vector<int>& nums) { /*选取一个基准元素逐个与后面的比较*/ for (int i = 0; i < nums.size() - 1-1; i++) { int min = i;/*定义随之变化的基准元素*/ for (int j = i + 1; j < nums.size() - 1; j++) { if (nums[i] > nums[j]) { swap(nums[i], nums[j]);//交换元素 } } } } /* 选择排序 */ 官方正解 void selectionSort(vector<int>& nums) { int n = nums.size(); // 外循环:未排序区间为 [i, n-1] 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) { // 外循环:未排序区间为 [0, i] for (int i = nums.size() - 1; i > 0; i--) { // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端 for (int j = 0; j < i; j++) { if (nums[j] > nums[j + 1]) { // 交换 nums[j] 与 nums[j + 1] // 这里使用了 std::swap() 函数 swap(nums[j], nums[j + 1]); } } } } void test() { vector<int> nums = { 4,23,6,12,56,78,2,3,5,76 }; //select_sort(nums); bubbleSort(nums); for (int num : nums) { cout << num << " "; } }
/* 插入排序 */
void insertionSort(vector<int> &nums) {
// 外循环:已排序区间为 [0, i-1]
for (int i = 1; i < nums.size(); i++) {
int base = nums[i], j = i - 1;
// 内循环:将 base 插入到已排序区间 [0, i-1] 中的正确位置
while (j >= 0 && nums[j] > base) {
nums[j + 1] = nums[j]; // 将 nums[j] 向右移动一位
j--;
}
nums[j + 1] = base; // 将 base 赋值到正确位置
}
}
重点理解反复熟悉
/* 元素交换 */ void swap(vector<int>& nums, int i, int j) { int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp; } /* 哨兵划分 */ int partition(vector<int>& nums, int left, int right) { // 以 nums[left] 为基准数 int i = left, j = right; while (i < j) { while (i < j && nums[j] >= nums[left]) j--; // 从右向左找首个小于基准数的元素 while (i < j && nums[i] <= nums[left]) i++; // 从左向右找首个大于基准数的元素 swap(nums, i, j); // 交换这两个元素 } swap(nums, i, left); // 将基准数交换至两子数组的分界线 return i; // 返回基准数的索引 } /* 快速排序 */ void quickSort(vector<int>& nums, int left, int right) { // 子数组长度为 1 时终止递归 if (left >= right) return; // 哨兵划分 int pivot = partition(nums, left, right); // 递归左子数组、右子数组 quickSort(nums, left, pivot - 1); quickSort(nums, pivot + 1, right); }
参考:数据结构之堆火烨烨
#include <vector> #include <iostream> #include <algorithm> // 引入 swap 函数 using namespace std; // 向下调整堆 void siftDown(vector<int>& nums, int n, int i) { while (true) { int l = 2 * i + 1; int r = 2 * i + 2; int ma = i; if (l < n && nums[l] > nums[ma]) ma = l; if (r < n && nums[r] > nums[ma]) ma = r; if (ma == i) { break; } swap(nums[i], nums[ma]); i = ma; } } /* 堆排序 */ void heapSort(vector<int>& nums) { int n = nums.size(); // 建堆操作 for (int i = n / 2 - 1; i >= 0; --i) { siftDown(nums, n, i); } // 提取最大元素并重新建堆 for (int i = n - 1; i > 0; --i) { swap(nums[0], nums[i]); siftDown(nums, i, 0); } } int main() { vector<int> nums = { 10, 30, 40, 20, 100 }; cout << "Before sorting: "; for (int num : nums) { cout << num << " "; } cout << endl; heapSort(nums); cout << "After sorting: "; for (int num : nums) { cout << num << " "; } cout << endl; return 0; }
/* 桶排序 */ void bucketSort(vector<float> &nums) { // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素 int k = nums.size() / 2; vector<vector<float>> buckets(k); // 1. 将数组元素分配到各个桶中 for (float num : nums) { // 输入数据范围为 [0, 1),使用 num * k 映射到索引范围 [0, k-1] int i = num * k; // 将 num 添加进桶 bucket_idx buckets[i].push_back(num); } // 2. 对各个桶执行排序 for (vector<float> &bucket : buckets) { // 使用内置排序函数,也可以替换成其他排序算法 sort(bucket.begin(), bucket.end()); } // 3. 遍历桶合并结果 int i = 0; for (vector<float> &bucket : buckets) { for (float num : bucket) { nums[i++] = num; } } }
/* 合并左子数组和右子数组 */ void merge(vector<int> &nums, int left, int mid, int right) { // 左子数组区间为 [left, mid], 右子数组区间为 [mid+1, right] // 创建一个临时数组 tmp ,用于存放合并后的结果 vector<int> tmp(right - left + 1); // 初始化左子数组和右子数组的起始索引 int i = left, j = mid + 1, k = 0; // 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中 while (i <= mid && j <= right) { if (nums[i] <= nums[j]) tmp[k++] = nums[i++]; else tmp[k++] = nums[j++]; } // 将左子数组和右子数组的剩余元素复制到临时数组中 while (i <= mid) { tmp[k++] = nums[i++]; } while (j <= right) { tmp[k++] = nums[j++]; } // 将临时数组 tmp 中的元素复制回原数组 nums 的对应区间 for (k = 0; k < tmp.size(); k++) { nums[left + k] = tmp[k]; } } /* 归并排序 */ void mergeSort(vector<int> &nums, int left, int right) { // 终止条件 if (left >= right) return; // 当子数组长度为 1 时终止递归 // 划分阶段 int mid = (left + right) / 2; // 计算中点 mergeSort(nums, left, mid); // 递归左子数组 mergeSort(nums, mid + 1, right); // 递归右子数组 // 合并阶段 merge(nums, left, mid, right); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。