十大排序算法
排序代码都是以这个题为参照,可以直接提交ac
215. 数组中的第K个最大元素 - 力扣(LeetCode) (leetcode-cn.com)
冒泡排序
选择排序
插入排序
//插入排序就是从第二个数作为当前位置,假定左边有序,然后将右边的数找个合适位置放进去
1 class Solution { 2 public: 3 void isort(vector<int>&nums){//数组插入要移动很多数,不像链表 4 for(int i=1;i<nums.size();i++){ 5 int now = nums[i]; 6 int j = i-1; 7 while(j>=0&&now>nums[j]){ 8 nums[j+1] = nums[j]; 9 j--; 10 } 11 nums[j+1] = now; 12 } 13 } 14 int findKthLargest(vector<int>& nums, int k) { 15 isort(nums); 16 return nums[k-1]; 17 } 18 };
希尔排序
桶排序
计数排序
基数排序
归并排序
归并排序是分治思想,先分再合,分的时候分到单个元素就停止,合的时候保证左右两个分支都是有序序列,也就是有序序列的合并
1 class Solution { 2 public: 3 void divide(vector<int>& nums,int l,int r){ 4 if(l>=r) 5 return ; 6 int mid = (l+r)/2; 7 divide(nums,l,mid); 8 divide(nums,mid+1,r); 9 vector<int> t1(nums.size()); 10 vector<int> t2(nums.size()); 11 int len1=0,len2=0; 12 for(int i=l;i<=mid;i++){ 13 t1[len1++] = nums[i]; 14 } 15 for(int i = mid+1;i<=r;i++){ 16 t2[len2++] = nums[i]; 17 } 18 int l1 = 0,l2 = 0; 19 int i; 20 for(i=l;i<=r&l1<len1&&l2<len2;i++){ 21 if(t1[l1]>t2[l2]){//从大到小排 22 nums[i] = t1[l1++]; 23 }else{ 24 nums[i] = t2[l2++]; 25 } 26 } 27 while(l1<len1){ 28 nums[i++] = t1[l1++]; 29 } 30 while(l2<len2){ 31 nums[i++] = t2[l2++]; 32 } 33 } 34 int findKthLargest(vector<int>& nums, int k) { 35 divide(nums,0,nums.size()-1); 36 return a[k-1]; 37 } 38 }; 39 /*void divide(int nums[],int l,int r){void divide(int *nums,int l,int r) 这两种都是可以修改原数组,vector要加取地址符号才行*/
快速排序
//快排就是每次把第一个数放在它有序数组中的位置,左边的数都小于它右边的数都大于他
和归并排序区别就是只分不和
1 class Solution { 2 public: 3 void qsort(vector<int>&nums,int l,int r){ 4 if(l>=r) 5 return ; 6 int cmp=l,j=l; 7 for(int i=l+1;i<=r;i++){ 8 if(nums[i]>nums[cmp]){//这里决定排序方向 9 swap(nums[i],nums[++j]); 10 } 11 } 12 swap(nums[cmp],nums[j]);//j=k-1时就可以return了 13 qsort(nums,l,j-1); 14 qsort(nums,j+1,r); 15 } 16 int findKthLargest(vector<int>& nums, int k) { 17 qsort(nums,0,nums.size()-1); 18 return nums[k-1]; 19 } 20 };
1 class Solution { 2 public: 3 void qsort(vector<int>&nums,int left,int right){ 4 if(left>=right) 5 return ; 6 int cmp = left,j=left; 7 int randnum = rand() % (right - left + 1) + left; // 随机选一个作为我们的cmp,思路:选好了和left交换。不要把随机数直接作为cmp 8 swap(nums[left], nums[randnum]); 9 for(int i=left+1;i<=right;++i){ 10 if(nums[i]<nums[cmp]){//这里小于 11 swap(nums[++j],nums[i]); 12 } 13 } 14 swap(nums[cmp],nums[j]); 15 qsort(nums,left,j-1);//这里是j 16 qsort(nums,j+1,right); 17 } 18 vector<int> sortArray(vector<int>& nums) { 19 qsort(nums,0,nums.size()-1); 20 return nums; 21 } 22 };
堆排序
堆是完全二叉树,父节点大于等于(或小于等于)子节点的值。公式:parent = (son-1)/2 lson = parent*2+1 rson = parent*2+2
你还别说这还是有几个步骤的,第一步是构建堆核心是从最后一个节点的父节点开始往上递归调整父子值的大小关系,第二步是取堆顶元素,取完后递归调整堆父子大小关系。注意调整堆和构建堆的关系,构建堆需要从下往上多次调整堆。
堆排序(heapsort)_哔哩哔哩_bilibili 这个视频讲的透彻
1 class Solution {//parent = (son-1)/2 lson = parent*2+1 rson = parent*2+2 2 public: 3 void adjust(vector<int>&nums,int n,int index){//递归调整当前节点 4 if(index>=n) 5 return; 6 int lson = index*2+1,rson = index*2+2; 7 int mx = index; 8 if(lson<n&&nums[lson]>nums[mx]){ 9 mx = lson; 10 } 11 if(rson<n&&nums[rson]>nums[mx]){ 12 mx = rson; 13 } 14 if(mx!=index){ 15 swap(nums[mx],nums[index]); 16 adjust(nums,n,mx); 17 } 18 } 19 void build_heap(vector<int>&nums,int n){//大根堆,排序后是从小到大 20 int last_node = n-1; 21 int last_parent = (last_node-1)/2; 22 for(int i=last_parent;i>=0;i--){//从最后一个节点的父节点(即最后一个非叶子节点进行调整) 23 adjust(nums,n,i); 24 } 25 } 26 void hsort(vector<int>&nums,int n){//在数组已经是堆的基础之上,拿到最大值赋值到数组末尾,调整堆顶, 27 build_heap(nums,n); 28 for(int i=n-1;i>=0;i--){ 29 swap(nums[i],nums[0]); 30 adjust(nums,i,0); 31 } 32 } 33 int findKthLargest(vector<int>& nums, int k) { 34 int n=nums.size(); 35 hsort(nums,n); 36 for(int i=0;i<nums.size();i++) 37 cout<<nums[i]<<" "; 38 return nums[n-k]; 39 } 40 };
1 class Solution {//parent = (son-1)/2 lson = parent*2+1 rson = parent*2+2 2 public: 3 void adjust(vector<int>&nums,int n,int index){//递归调整当前节点 4 if(index>=n) 5 return; 6 int lson = index*2+1,rson = index*2+2; 7 int mn = index; 8 if(lson<n&&nums[lson]<nums[mn]){//堆是大还是小就看这里符号 9 mn = lson; 10 } 11 if(rson<n&&nums[rson]<nums[mn]){ 12 mn = rson; 13 } 14 if(mn!=index){ 15 swap(nums[mn],nums[index]); 16 adjust(nums,n,mn); 17 } 18 } 19 void build_heap(vector<int>&nums,int n){//小根堆,排序后是从大到小 20 int last_node = n-1; 21 int last_parent = (last_node-1)/2; 22 for(int i=last_parent;i>=0;i--){//从最后一个节点的父节点(即最后一个非叶子节点进行调整) 23 adjust(nums,n,i); 24 } 25 } 26 void hsort(vector<int>&nums,int n){//在数组已经是堆的基础之上,拿到最小值赋值到数组末尾,调整堆顶, 27 build_heap(nums,n); 28 for(int i=n-1;i>=0;i--){ 29 swap(nums[i],nums[0]); 30 adjust(nums,i,0); 31 } 32 } 33 int findKthLargest(vector<int>& nums, int k) { 34 int n=nums.size(); 35 hsort(nums,n); 36 for(int i=0;i<nums.size();i++) 37 cout<<nums[i]<<" "; 38 return nums[k-1]; 39 } 40 };