​912. 排序数组​


给你一个整数数组 ​​nums​​,请你将该数组升序排列。


示例 1:

输入:nums = [5,2,3,1] 输出:[1,2,3,5]

示例 2:

输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]
更简单易懂的方法:
定第一个元素为基准元素,然后利用两个指针,分别从后往前,从前往后和基准元素比较,满足条件则交换,直到两个指针相遇
两个指针相遇后,再将基准元素归位,也是两个元素进行交换,完成后就实现了一轮排序,分治递归即可;


#include <iostream> #include<vector> #include<bits/stdc++.h> using namespace std;  void quick_sort(vector<int>& nums,int start ,int end){     if(start>=end){         return;     }     int left = start;     int right = end;               int base = nums[start];          while(left<right){         while(left<right&& nums[right]>=base){             right--;         }         while(left<right&& nums[left]<=base){             left++;         }         if(left<right){                          int temp = nums[right];             nums[right] = nums[left];             nums[left] = temp;         }     }          //注意基准数归位的时候,需要交换两个数,不要直接进行简单赋值          nums[start] = nums[left];     nums[left] = base;          quick_sort(nums,start,left-1);     quick_sort(nums,left+1,end);      }  int main(){     vector <int> nums = {-1,20,2,9,90,888,0,7,0,12,23};     int end=nums.size()-1;          quick_sort(nums,0,end);          for(auto n:nums){         cout<<n<<endl;     }          return 0; }



更快一点的快速排序:


class Solution { public:  vector<int> sortArray(vector<int>& nums) {   quicksort(0, nums.size() - 1, nums);   return nums;  }   private:  void quicksort(int low, int high, vector<int>& a) {   if (low < high) {    int i = low;    int j = high;    int key = a[i];    while (i < j) {     while (i < j && a[j] >= key) {      j--;     }     a[i] = a[j];     while (i < j && a[i] <= key) {      i++;     }     a[j] = a[i];    }    a[i] = key;    quicksort(i + 1, high, a);    quicksort(low, j - 1, a);   }   else {    return;   }  } };



#include <iostream> #include<vector> #include<bits/stdc++.h> using namespace std;   class Solution { public:     vector<int> sortArray(vector<int>& nums) {         quicksort(0, nums.size() - 1, nums);         return nums;     }    private:     void quicksort(int low, int high, vector<int>& a) {         if (low < high) {             int i = low;             int j = high;             int key = a[i];             while (i < j) {                 while (i < j && a[j] >= key) {                     j--;                 }                 a[i] = a[j];                 while (i < j && a[i] <= key) {                     i++;                 }                 a[j] = a[i];             }             a[i] = key;             quicksort(i + 1, high, a);             quicksort(low, j - 1, a);         }         else {             return;         }     } };  int main(){     vector <int> nums = {0,9,88,9,76,234};     Solution s;     s.sortArray(nums);     for(auto n:nums){         cout<<n<<endl;     }     return 0; }





冒泡排序(Bubble Sort)

算法描述

冒泡排序要对一个数组多次重复遍历。它要比较相邻的两项,并且交换顺序排错的项。

每对数组进行一次遍历,就会有一个最大项排在了正确的位置。大体上讲,数组的每一个数据项都会在其相应的位置“冒泡”。若数组有n项,则需要遍历n-1次。

时间复杂度: 基本排序算法汇总_i++


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



选择排序(Selection Sort)

算法描述

选择排序提高了冒泡排序的性能,它每一次遍历一次数组只会进行一次交换,即在遍历过程中记录最大项的索引,完成遍历后,再把它换到正确的位置

同样若数组有n项,它也需要遍历n-1次。

时间复杂度:基本排序算法汇总_i++_02


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



插入排序(Insertion Sort)

算法描述

插入排序总是保持一个位置靠前的已经排好的数组,然后每一个新的数据项被“插入”到前边的子表里。共需进行n-1次插入,每进行一次插入,排好的数组增加一项。

时间复杂度:基本排序算法汇总_i++_03



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



希尔排序

原 理:希尔排序是对插入排序的改进,通过对无序序列进行多次分组,使每组中有序,最终令整体序列有序。




#include <iostream> using namespace std;  void ShellSort(int arr[] , int length) {     for(int gap = length/2; gap > 0; gap /= 2)     {         for(int i = gap; i < length; i++)         {             for(int j = i; j > 0 && arr[j-1] > arr[j]; j--)             {                 int tem = arr[j];                 arr[j] = arr[j-1];                 arr[j-1] = tem;             }         }     } }  int main() {     int a[] = {3 , 5 , 2 , 4 , 1 , 6 , 7};     int len = sizeof(a)/sizeof(a[0]);     ShellSort(a , len);     for(int i = 0; i < len; i++)     {         cout << a[i] << endl;     }     return 0; }



总 结:希尔排序是对插入排序的改进,与插入排序相比,希尔排序加入了一层对序列分组的操作。实际操作中,可以对gap进行更加复杂的方式运算。希尔排序可以应用在中量级的排序中。





归并排序(Merge Sort)

算法描述

归并排序是一种递归算法,持续地将一个数组分成两半。如果数组是空的或者只有一个元素,那么根据定义,它就被排序好了。如果数组里的元素超过一个,我们就把数组拆分,然后分别对两个部分调用递归排序,一旦这两个部分被排序好了,就对这两个部分进行归并。

时间复杂度: 基本排序算法汇总_递归_04



void merge(vector<int>& v, int left, int mid, int right){  vector<int> temp = v;  int i = left, j = mid + 1;  int index = left;  while(i <= mid || j <= right){   if(i > mid){    v[index++] = temp[j];    j++;   }   else if(j > right){    v[index++] = temp[i];    i++;   }   else if(temp[i] < temp[j]){    v[index++] = temp[i];    i++;   }   else{    v[index++] = temp[j];    j++;   }  }   } void merge_Sort(vector<int>& v, int left, int right){  if(left >= right) return;  int mid = (left + right) / 2;  merge_Sort(v, left, mid);  merge_Sort(v, mid + 1, right);  if(v[mid] > v[mid + 1]){   merge(v, left, mid, right);  } } void mergeSort(vector<int>& v){  int n = v.size();  merge_Sort(v, 0, n - 1); }




作者:程序员囧辉 链接:https://zhuanlan.zhihu.com/p/36075856 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。  public class MergeSort {     public static void mergeSort(int[] array) {         if (array == null || array.length == 0)             return;         int[] temp = new int[array.length];         mergeSort(array, 0, array.length - 1, temp);       }     // 归并     private static void mergeSort(int array[], int first, int last, int temp[]) {         if (first < last) {             int mid = (first + last) / 2;             mergeSort(array, first, mid, temp); // 递归归并左边元素             mergeSort(array, mid + 1, last, temp); // 递归归并右边元素             mergeArray(array, first, mid, last, temp); // 再将二个有序数列合并         }     }       /**      * 合并两个有序数列      * array[first]~array[mid]为第一组      * array[mid+1]~array[last]为第二组      * temp[]为存放两组比较结果的临时数组      */     private static void mergeArray(int array[], int first, int mid, int last, int temp[]) {         int i = first, j = mid + 1; // i为第一组的起点, j为第二组的起点         int m = mid, n = last; // m为第一组的终点, n为第二组的终点         int k = 0; // k用于指向temp数组当前放到哪个位置         while (i <= m && j <= n) { // 将两个有序序列循环比较, 填入数组temp             if (array[i] <= array[j])                 temp[k++] = array[i++];             else                 temp[k++] = array[j++];         }         while (i <= m) { // 如果比较完毕, 第一组还有数剩下, 则全部填入temp             temp[k++] = array[i++];         }         while (j <= n) {// 如果比较完毕, 第二组还有数剩下, 则全部填入temp             temp[k++] = array[j++];         }         for (i = 0; i < k; i++) {// 将排好序的数填回到array数组的对应位置             array[first + i] = temp[i];         }     } }







快速排序(Quick Sort)

算法描述

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分小,然后对两部分进行递归的快速排序。

时间复杂度: 基本排序算法汇总_i++_05

算法步骤


  1. 从数组中挑出一个元素,称为“基准”(pivot);
  2. 重新排序数组,所有比基准小的数放在基准前面,所有比基准大的元素放在基准后面,这称为分区(partition)操作;
  3. 递归地对基准两边的子数组进行排序。


void quick_Sort(vector<int>& v, int left, int right){  if(left >= right) return;  int i = left, j = right, base = v[left];  //取最左边的数为基数  while(i < j){   while(v[j] >= base && i < j){    j--;   }   while(v[i] <= base && i < j){    i++;   }   if(i < j){    swap(v[i], v[j]);   }  }   v[left] = v[i];  v[i] = base;  quick_Sort(v, left, i - 1);  quick_Sort(v, i + 1, right); } void quickSort(vector<int>& v){  int n = v.size();  quick_Sort(v, 0, n - 1); }




常用排序算法总结:​​https://zhuanlan.zhihu.com/p/121066684​