本次排序都是按照升序排的
冒泡排序
void bubbleSort(vector<int>& nums) {int n=nums.size();for(int i=0;i<n-1;i++){bool swapped=false;for(int j=0;j<n-1-i;j++){if(nums[j]>nums[j+1]){swap(nums[j],nums[j+1]);swapped=true;}}if(!swapped)break;} } //算法原理: 一共排序n-1次,每一次排序,相邻元素两两比较,一共比较n-1-i次,最后排出一个元素放在数组末尾,n-1次后,排序完成。 // 若还没有到第n-1次排序,比较元素没有交换位置,则排序已完成,可提前结束排序。 //时间复杂度: O(N^2) //空间复杂度: O(1) //稳定性: 稳定
选择排序
void SelectSort(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]);} } //算法原理: 需要选择n-1次基准元素,从下标为0开始选取,然后与未排序的元素比较,找到元素最小的下标,交换基准元素和最小元素,一次排序 // 已完成。一共排序n-1次。 //时间复杂度: O(N^2) //空间复杂度: O(1) //稳定性: 不稳定
插入排序
void InsertSort(vector<int>& nums) {int n=nums.size();for(int i=1;i<n;i++){int key=nums[i],j=i-1;while(j>=0&&nums[j]>key){nums[j+1]=nums[j];j--;}nums[j+1]=key;} } //算法原理: 从下标为1开始,令其为key,然后插入到已排序的元素中,找到应该插入的位置。 //时间复杂度: O(N^2) //空间复杂度: 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 key=nums[i],j=i-gap;while(j>=0&&nums[j]>key){nums[j+gap]=nums[j];j-=gap;}nums[j+gap]=key;}} } //算法原理: 插入排序的优化,按照gap为间隔,每次排序是预排序,使数组趋于有序化,当gap等于1时,才是真的排序 //时间复杂度: O(N^2) //空间复杂度: O(1) //稳定性: 不稳定
快速排序
快排思想:
int _QuickSort(vector<int> &nums, int left, int right) {int key = left;left++;while (left <= right){while (left <= right && nums[left] < nums[key])left++;while (left <= right && nums[right] > nums[key])right--;if (left <= right)swap(nums[left++], nums[right--]);}swap(nums[key], nums[right]);return right; } void QuickSort(vector<int> &nums, int left, int right) {if (left > right)return;int key = _QuickSort(nums, left, right);QuickSort(nums, left, key - 1);QuickSort(nums, key + 1, right); } //算法原理: 任取待排序元素中的某元素作为基准元素,使左边元素都小于基准元素,右边元素都大于基准元素,然后重复该过程,直到所有元素都 // 排序完成。 //时间复杂度: O(NlogN) //空间复杂度: O(logN) //稳定性: 不稳定
归并排序
void MergeSort(vector<int> &nums, int left, int right) {if (left >= right) return;int mid = (left + right) >> 1;MergeSort(nums, left, mid);MergeSort(nums, mid + 1, right);vector<int> tmp(right-left+1);int cur1 = left, cur2 = mid + 1, i = 0;while (cur1 <= mid && cur2 <= right)tmp[i++] = nums[cur1] < nums[cur2] ? nums[cur1++] : nums[cur2++];while (cur1 <= mid)tmp[i++] = nums[cur1++];while (cur2 <= right)tmp[i++] = nums[cur2++];for (int i = left; i <= right; i++)nums[i] = tmp[i - left]; } //算法原理: 将数组分为两部分,不断的递归,直到数组元素为1或者不能再分,然后合并两个有序数组。 //时间复杂度: O(NlogN) //空间复杂度: O(N) //稳定性: 稳定
堆排序
void AdjustDown(vector<int>& nums,int n,int parent) {int child=parent*2+1;while(child<n){if(child+1<n && nums[child+1]>nums[child]) child=child+1;if(nums[child]>nums[parent]){swap(nums[child],nums[parent]);parent=child;child=parent*2+1;}else{break;}} } void HeapSort(vector<int>& nums) {int n=nums.size();//构建大根堆,从最后一个非叶子节点开始for(int i=(n-1-1)/2;i>=0;i--){AdjustDown(nums,n,i);}//排序int end=n-1;while(end>=0){swap(nums[0],nums[end]);AdjustDown(nums,end,0);end--;} } //算法原理: 先构建最大堆,然后交换堆顶元素和最后一个元素,这样最后一个元素就是最大的了,然后再建堆,这样不断循环。 //时间复杂度: O(NlogN) //空间复杂度: O(N) //稳定性: 稳定
基数排序
void RadixSort(std::vector<int>& nums) {int maxVal=*max_element(nums.begin(),nums.end());int maxDigits=0;while(maxVal){maxVal/=10;maxDigits++;}vector<queue<int>> buckets(10);for(int i=0;i<maxDigits;i++){for(int num : nums){int bucketIndex=num/static_cast<int>(pow(10,i))%10;buckets[bucketIndex].push(num);}int index=0;for(auto& bucket : buckets){while(!bucket.empty()){nums[index++]=bucket.front();bucket.pop();}}} } //算法原理: 按照位数排序,按照位数把元素分配到对应的桶中,然后依据先进先出的顺序再收集到数组中,这样依次排个位,十位,百位。 //时间复杂度: O(NlogN) //空间复杂度: O(N) //稳定性: 稳定