- 冒泡排序
相邻元素比较,每次“浮”出最大(最小) 平均时间复杂度: O(N^2)
可以提前退出
void bubbleSort(vector<int>&nums,int start , int end){
for(int i = start ;i < end;++i){
bool flag = false;
for(int j = start ; j < end - 1 - i ; ++j){
if(nums[j] > nums[j+1]){
swap(nums[j],nums[j+1]);
flag = true;
}
}
if(false == flag) {
cout<< " 提前退出 "<<endl;
return;
}
}
}
- 选择排序
每一轮从未排序的部分中选出最大(最小)的 平均时间复杂度:O(N^2)
void selectSort(vector<int>&nums,int start , int end){
for(int i = start ;i < end ;++i){
int index = start;
for(int j = start; j < end - i ; ++j){
if(nums[j] > nums[index]){
index = j;
}
}
swap(nums[index],nums[end-1-i]);
}
}
- 插入排序
将前面数据视为排好序的,将当前待插入的数据与前面排好顺序的数据进行比较,找到插入数据的位置,以此类推。 O(N^2)
void insertionSort(vector<int>&nums,int start , int end){
for(int i = start ;i < end ;++i){
int tmp = nums[i];
int j = i-1;
for(; j>= 0 && nums[j] > tmp;--j){
nums[j+1] = nums[j];
}
nums[j+1] = tmp;
}
}
- 希尔排序
将插入排序进行了优化,插入排序适合部分有顺序的数据,通常采用一个递减到1的序列数,调节步长将长序列拆分成多个,步长逐渐缩小,使数据大部分都有序的时候可以提高排序效率。
平均时间复杂度:O(NlongN)~ O(N^2)
void shellSort(vector<int>& nums ,int start,int end){
for(int kd = end/2;kd >= 1;kd = kd/2){
for(int i = kd ;i < end; ++i){
int tmp = nums[i],j;
for(j = i - kd;j>= 0 && nums[j] > tmp;j = j -kd){
nums[j+kd] = nums[j];
}
nums[j+kd] = tmp;
}
}
}
- 快速排序
每次选取一个基数,将数组分成大于基数和小于基数的两个区间,不断再递归左右区间。
平均时间复杂度:O(NlongN)
int partition(vector<int>& nums,int start,int end){
int pivot = nums[start];
while(start<end) {
while(start<end && nums[end]>=pivot)--end;
nums[start] = nums[end];
while(start<end && nums[start]<=pivot) ++start;
nums[end] = nums[start];
}
nums[start] = pivot;
return start;
}
void quickSort(vector<int>& nums ,int start,int end){
if(start<end ) {
int pivotpos = partition(nums,start,end);
quickSort(nums,start,pivotpos-1);
quickSort(nums,pivotpos+1,end);
}
}
void quickSort(vector<int>&nums, int left, int right){
if(left >= right){
return;
}
int pivot = partition(nums, left, right);
int leftPivot = pivot - 1;
int rightPivot = pivot + 1;
while(leftPivot > left && nums[leftPivot] == nums[pivot]){
leftPivot --;
}
while(rightPivot < right && nums[rightPivot] == nums[pivot]){
rightPivot++;
}
quickSort(nums, left, leftPivot);
quickSort(nums, rightPivot, right);
}
int partition(vector<int>&nums, int left, int right){
int randomIndex = left + (int)(rand() / double(RAND_MAX) * (right - left + 1));
int tmp = nums[left];
nums[left] = nums[randomIndex];
nums[randomIndex] = tmp;
int pivotVal = nums[left];
while(left < right){
while(left < right && nums[right] >= pivotVal){
right --;
}
nums[left] = nums[right];
while(left < right && nums[left] <= pivotVal){
left ++;
}
nums[right] = nums[left];
}
nums[left] = pivotVal;
return left;
}
- 堆排序
一般情况下升序排序使用最大堆,降序排序排序使用最小堆
先构建大根堆,然后每次将堆顶和倒数第一个交换,调整,然后再交换对顶和倒数第二个
平均时间复杂度:O(NlongN)
void adjust(vector<int> &nums, int len, int index){
int left = 2*index + 1;
int right = 2*index + 2;
int maxIdx = index;
if(left<len && nums[left] > nums[maxIdx]) maxIdx = left;
if(right<len && nums[right] > nums[maxIdx]) maxIdx = right;
if(maxIdx != index)
{
swap(nums[maxIdx], nums[index]);
adjust(nums, len, maxIdx);
}
}
void HeapSort(vector<int> &nums, int size){
for(int i=size/2 - 1; i >= 0; i--){
adjust(nums, size, i);
}
for(int i = size - 1; i >= 1; i--){
swap(nums[0], nums[i]);
ad just(nums, i, 0);
}
}
- 归并
将区间拆分成两段或者多段,对小段区间进行排序,然后再对有序数组进行合并。
平均时间复杂度:O(NlongN)
void mergeSortInOrder(vector<int>&arr,int bgn,int mid, int end){
int l = bgn, m = mid +1, e = end;
vector<int> arrs(end - bgn + 1);
int k = 0;
while(l <= mid && m <= e){
if(arr[l] < arr[m]){
arrs[k++] = arr[l++];
}else{
arrs[k++] = arr[m++];
}
}
while(l <= mid){
arrs[k++] = arr[l++];
}
while(m <= e){
arrs[k++] = arr[m++];
}
for(int i = 0; i < arrs.size(); i++){
arr[i + bgn] = arrs[i];
}
}
void mergeSort(vector<int>& arr, int bgn, int end)
{
if(bgn >= end){
return;
}
int mid = (bgn + end) >> 1;
mergeSort(arr,bgn,mid);
mergeSort(arr,mid + 1, end);
mergeSortInOrder(arr,bgn,mid,end);
}