快速排序
定义:
快速排序是由冒泡排序改进而得的。在冒泡排序过程中,只对相邻的两个记录进行比较,因此每次交换两个相邻记录时只能消除一个逆序。如果能通过两个不相邻记录的一次交换,消除多个逆序,则会大大加快排序的速度。快速排序方法中的一次交换能消除多个逆序。
具体步骤:
1.选择待排序表中的第一个记录作为枢轴,附设两个指针low和high,初始时分别指向标的下界和上界;
2.从标的最右侧位置一次向左搜索,找到第一个关键字小于枢轴关键字的记录,将其移至low处;
3.然后再从表的最左侧位置,依次向右搜索找到第一个关键字大于枢轴的记录,将其移至high处;
4.重复2和3,直至low和high相等为止;
(实际上相当于取出第一个记录,从high向左搜索找到一个值放入第一个记录,再从low向右搜索找到一个值放入上轮空缺的high值。)
算法特点:
(1)记录非顺次的移动导致排序方法是不稳定的。
(2)排序过程中需要定位表的下界和上界,所以适合用于顺序结构,很难用于链式结构。
(3)当n较大时,在平均情况下快速排序是所有内部排序方法中速度最快的一种,所以其适合初始记录无序,n较大的情况。
| 时间复杂度 | 空间复杂度 |
|---|---|
| O(nlogn) | O(1) |
代码:(以对vector排序为例)
#include <iostream>
#include <vector>
using namespace std;
//快速排序
int Partition(vector<int> &arr, int low, int high)//low high指针移动一趟
{
int p = arr[low];
while (low < high) {
while (low < high && arr[high] >= p) high--;
arr[low] = arr[high];
while (low < high && arr[low] <= p) low++;
arr[high] = arr[low];
}
arr[low] = p;
return low;//返回枢轴位置
}
void QSort(vector<int> &arr, int low, int high)//递归
{
if (low < high) {
int p = Partition(arr, low, high);
QSort(arr, low, p - 1);
QSort(arr, p + 1, high);
}
}
int main()
{
vector<int> test = { 49,38,65,97,76,13,27,49 };
QSort(test, 0, test.size()-1);
//输出排序后的向量
for (int k = 0; k < test.size(); k++)
cout << test[k] << " ";
}
归并排序
定义:
归并排序就是将两个或两个以上的有序表合并成一个有序表的过程,将两个有序表合并成一个有序表的过程称为2-路归并,2-路归并最简单和常用。
具体步骤:
2-路归并排序将R[low,high]中的记录归并排序后放入T[low,high]中,当序列长度等于1时,递归结束。否则:
1.将当前序列一分为二,求出分裂点mid=(low+high)/2;
2.对子序列R[low,mid]递归,进行归并排序,结果放入S[low,high]中;
3.对子序列R[mid+1,high]递归,进行归并排序,结果放入S[mid+1,high]中;
4.调用算法Merge,将有序的两个子序列S[low,mid]和S[mid+1,high]归并为一个有序的序列T[low,high];
算法特点:
(1)归并排序为稳定排序
(2)可用于链式结构,且不需要附加存储空间,但递归实现时仍需要开辟相应的递归工作栈。
| 时间复杂度 | 空间复杂度 |
|---|---|
| O(nlogn) | O(n) |
代码:(以对vector排序为例)
#include <iostream>
#include <vector>
using namespace std;
//归并排序
//将R[low,mid] R[mid+1,high]归并为有序表T[low,high]
void Merge(vector<int> &R, vector<int> &T, int low, int mid, int high)
{
int i = low, j = mid + 1, k = low;
while (i <= mid && j <= high) {
if (R[i] < R[j])
T[k++] = R[i++];
else
T[k++] = R[j++];
}
while (i <= mid) T[k++] = R[i++];
while (j <= high) T[k++] = R[j++];
}
//R归并排序后放入T中
void MSort(vector<int> &R, vector<int> &T, int low, int high)
{
if (low == high) T[low] = R[low];
else {
int mid = (low + high) / 2;
vector<int> S(R.size());
MSort(R, S, low, mid);
MSort(R, S, mid+1, high);
Merge(S, T, low, mid, high);
}
}
int main()
{
vector<int> test = { 49,38,65,97,76,13,27,49 };
MSort(test, test, 0, test.size()-1);
for (int k = 0; k < test.size(); k++)
cout << test[k] << " ";
}
实验结果截图:

本文详细介绍了两种经典的排序算法——快速排序和归并排序。快速排序采用分治策略,通过选取枢轴元素将数组划分为两部分,再递归排序。归并排序则通过不断合并已排序的子序列来达到整体有序。两者都是O(nlogn)的时间复杂度,但快速排序在平均情况下更优,而归并排序则是稳定的排序算法。文中提供了C++实现代码示例,并分析了它们各自的特点和适用场景。
901

被折叠的 条评论
为什么被折叠?



