classSolution { public: intpartition(vector<int>& nums, int left, int right){ int randomIndex = right; int pivot = nums[right]; int i = left; int j = right - 1;
while (true) { while (i <= j && nums[i] < pivot) { i++; }
while (i <= j && nums[j] > pivot) { j--; }
if (i >= j) { break; } swap(nums, i, j); i++; j--; }
swap(nums, right, i); return i; }
voidswap(vector<int>& nums, int index1, int index2){ int temp = nums[index1]; nums[index1] = nums[index2]; nums[index2] = temp; }
intfindKthLargest(vector<int>& nums, int k){ int len = nums.size(); int target = len - k;
int left = 0; int right = len - 1;
while (true) { int pivotIndex = partition(nums, left, right); // 分治思想 if (pivotIndex == target) { return nums[pivotIndex]; } elseif (pivotIndex < target) { left = pivotIndex + 1; } else { right = pivotIndex - 1; } } } };
voidBubbleSort(vector<int>& nums,int n) { for(int i=0;i<n-1;i++) { bool flag = false; for (int j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; flag = true; } } if(flag == false){ return ; } } }
快排
arr是待排序的整数数组,left 和 right 表示列表的左右边界。在 partition() 函数中,我们选取左边第一个元素作为枢轴(pivot),并使用 i 和 j 两个指针在列表中进行从左到右和从右到左的扫描。在扫描的过程中,如果发现 i 指向的元素大于枢轴,或者 j 指向的元素小于枢轴,则将 i 和 j 指向的元素进行交换。最终,当 i 大于 j 时,将枢轴与 j 指向的元素进行交换,并返回 j。
voidQuickSort(vector<int>& nums,int low,int high) { if(low<high) { int pivot = partition(nums, low, high); QuickSort(nums,low,pivot-1); QuickSort(nums,pivot+1,high); } } intpartition(vector<int>& arr, int left, int right) { int pivot = arr[left]; int i = left + 1; int j = right;
while (i <= j) { while (i <= j && arr[i] < pivot) i++; while (i <= j && arr[j] > pivot) j--; if (i <= j) { swap(arr[i], arr[j]); i++; j--; } }
swap(arr[left], arr[j]); // 和基准相反的那个数 return j; }
// 优化版,防止退化为选择排序 intpartition(vector<int>& arr, int left, int right) { int randidx = left + rand() % (right - left + 1); int pivot = arr[randidx]; // 通过将随机选择的基准元素与数组的左边界元素进行交换 // 确保了在后续的分区过程中可以直接使用 arr[left] 作为基准元素,而不需要特别考虑基准元素的位置。 swap(arr[left], arr[randidx]); int i = left + 1; int j = right;
while (i <= j) { while (i <= j && arr[i] < pivot) i++; while (i <= j && arr[j] > pivot) j--; if (i <= j) { swap(arr[i], arr[j]); i++; j--; } }
swap(arr[left], arr[j]); // 和基准相反的那个数 return j; }
选择排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
voidSelectSort(vector<int>& nums,int n) { // 遍历数组 // 外层循环 for(int i=0;i<n-1;i++) 中的 n-1 是合理的,因为最后一个元素无需再参与比较和交换。 for(int i=0;i<n-1;i++) { // 找到未排序部分的最小元素 int min = i; for(int j=i+1;j<n;j++) { if(nums[j]<nums[min]) min = j;
// 递归方式构建大根堆(len是arr的长度,index是第一个非叶子节点的下标) voidadjust(vector<int> &arr, int len, int index) { int left = 2*index + 1; // index的左子节点 int right = 2*index + 2;// index的右子节点