排序算法总结
1. 冒泡排序
思路:
- 循环遍历数组,比较相邻数字,满足条件就交换。
- 每次遍历都会把最大或者最小的数冒到最后。
实现:
void bubble_sort(int nums[] , int size)
{
if (!nums || size <= 1) return ;
for (int i=0; i<size-1; ++i)
{
for (int j=0; j < size-i-1; ++j)
{
if (nums[j] > nums[j+1])
{
int tmp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = tmp;
}
}
}
return ;
}
2. 插入排序
思路:
实现:
void insert_sort(int nums[], int size)
{
if (!nums || size <= 1) return;
for (int i=1; i<size; ++i)
{
int cur = nums[i];
int j = i-1;
for (; j>=0; --j)
{
if (cur < nums[j])
{
nums[j+1] = nums[j];
}
else
{
break;
}
}
nums[j+1] = cur;
}
return;
}
3. 选择排序
思路:
实现:
void select_sort(int nums[], int size)
{
if (!nums || size <= 1) return;
for (int i=0; i<size-1; ++i)
{
for (int j=i+1; j<size; ++j)
{
if (nums[i] > nums[j])
{
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
}
return ;
}
4. 归并排序
思路:
- 先递归的把队列二分,再把已排序后的队列合并成一个。
- 自底向上
实现:
void merge(int A[], int start, int mid, int end)
{
int len = end - start + 1;
int *nums = (int*)malloc(sizeof(int)*len);
if (!nums) return;
memset(nums, 0, sizeof(int)*len);
int p1 = start, p2 = mid+1, i = 0;
while((p1 <= mid) && (p2 <= end))
{
if (A[p1] <= A[p2])
{
nums[i++] = A[p1++];
}
else
{
nums[i++] = A[p2++];
}
}
while(p1 <= mid)
{
nums[i++] = A[p1++];
}
while(p2 <= end)
{
nums[i++] = A[p2++];
}
memcpy(A+start, nums, sizeof(int)*len);
std::cout << "A[" << start << "..." << end << "]: ";
for (int j = 0; j<len; ++j)
{
std::cout << A[j] << " ";
}
std::cout << std::endl;
free(nums);
return;
}
void merge_sort_c(int A[], int start, int end){
if (start >= end)
return;
int mid = (start + end)/2;
merge_sort_c(A, start, mid);
merge_sort_c(A, mid+1, end);
merge(A, start, mid, end);
return;
}
void merge_sort(int A[], int length)
{
if (!A || length <= 0) return;
merge_sort_c(A, 0, length-1);
return;
}
5. 快速排序
思路:
- 选择队列中适当的数,根据数值大小,把队列分割成两部分。
- 递归的分割
- 自顶向下
实现:
int split_opt(int nums[], int start, int end)
{
int mid = nums[end];
int i = start, j = start;
while (j<=end)
{
if (nums[j] <= mid)
{
int tmp = nums[i];
nums[i++] = nums[j];
nums[j] = tmp;
}
++j;
}
std::cout << "nums[" << start << "..." << end <<"] " << "mid " << mid <<" : ";
for (int k=start; k<=end; ++k)
{
std::cout << nums[k] << " ";
}
std::cout << std::endl;
return i-1;
}
void quick_sort_c(int nums[], int start, int end)
{
if (start >= end) return;
int provit = 0;
provit = split_opt(nums, start, end);
quick_sort_c(nums, start, provit-1);
quick_sort_c(nums, provit+1, end);
return;
}
void quick_sort(int nums[], int length)
{
quick_sort_c(nums, 0, length-1);
return;
}
6. 总结
排序算法 | 时间复杂度(最好/平均/最坏) | 空间复杂度 | 稳定度 |
---|
冒泡 | O(n) / O(n*n) / O(n*n) | O(1) | 稳定 |
插入 | O(n) / O(n*n) / O(n*n) | O(1) | 稳定 |
选择 | O(n*n) / O(n*n) / O(n*n) | O(1) | 不稳定 |
归并排序 | 始终是 O(nlogn) | O(n) | 稳定 |
快速排序 | O(nlogn)/O(nlogn)/O(n*n) | O(1) | 不稳定 |