// 冒泡排序
// 通过相邻元素的比较和交换,使得每一趟循环都能找到未排序数组的最大值或最小值
// 最好:O(n),只冒泡一次数组就有序的情况。
// 最坏:O(n^2)
// 平均:O(n^2)
void bubbleSort(vector<int> &nums){
for(int i=0; i<nums.size(); ++i){
for(int j=0; j<nums.size()-i-1; ++j){
if(nums[j] > nums[j+1])
swap(nums[j], nums[j+1]);
}
}
}
//选择排序
//将每一个元素和它后面的每一个元素进行比较、交换,从而找到最小值
// 最好:O(n^2)
// 最坏:O(n^2)
// 平均:O(n^2)
void selectSort(vector<int> &nums){
for(int i=0; i<nums.size(); ++i)
for(int j=i; j<nums.size(); ++j)
if(nums[i] > nums[j])
swap(nums[i], nums[j]);
}
// 插入排序
// 以第一个元素作为有序数组,其后的元素通过在这个已有序的数组中找到合适的位置并插入
// 最好:O(n),原数组已经是升序的
// 最坏:O(n^2),原数组已经是降序的
// 平均:O(n^2)
void insertSort(vector<int> &nums){
for(int i=0; i<nums.size(); ++i){
int temp = nums[i];
int j=i;
while(j > 0){
if(temp < nums[j-1]){
swap(nums[j-1], nums[j]);
}
--j;
}
}
}
// 快速排序
// 选择一个元素作为基数(通常是第一个元素),把比基数小的元素放到它左边,比基数大的元素放到它右边(相当于二分),再不断递归基数左右两边的序列。
// 快速排序之填坑
// 从右边向中间推进的时候,遇到小于基数的数就赋给左边(一开始是基数的位置),右边保留原先的值等之后被左边的值填上。
// 最好:O(n * logn),其他的数均匀分布在基数的两边,此时的递归就是不断地二分左右序列。
// 最坏:O(n2) , 其他的数都分布在基数的一边,此时划分左右序列就相当于成了插入排序。
// 平均:O(n * logn)
void quickSort(vector<int> &nums, int left, int right){
if(left >= right)
return;
int pivot = nums[left]; // 最左边为pivot
int index = left;
int p = left;
int q = right;
while(p < q){
if(nums[p] <= pivot)
p++;
if(nums[p] > pivot){
swap(nums[p], nums[q]);
q--;
}
}
swap(nums[index], nums[p-1]);
quickSort(nums, left, p-2);
quickSort(nums, p, right);
}
// 归并排序
// 递归将数组分为两个序列,有序合并这两个序列
// 最好:O(n * logn)
// 最坏:O(n * logn)
// 平均:O(n * logn)
void mergeSort(vector<int> &nums, int left, int right, vector<int> &res){
if(left >= right)
return;
int middle = (left + right)/2;
mergeSort(nums, left, middle, res);
mergeSort(nums, middle+1, right, res);
int i = left;
int j = middle+1;
int index = 0;
while(i <= middle && j <= right){
if(nums[i] < nums[j])
res[index++] = nums[i++];
else
res[index++] = nums[j++];
}
while(i <= middle)
res[index++] = nums[j++];
while(j <= right)
res[index++] = nums[i++];
}
排序算法
最新推荐文章于 2022-04-27 23:04:16 发布