!!本章部分内容取自网络!!
目录
1.本章内容
本章将讲解插入、归并、快速等排序。
2.算法分类
十种常见排序算法可以分为两大类:
- 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。
- 非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。
3.算法复杂度
- 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
- 不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
4.1插入排序
- 从第一个元素开始,该元素可以认为已经被排序
- 取出下一个元素,在已经排序的元素中从后向前扫描
- 如果该元素(已排序)大于新元素,将该元素移动到下一位置
- 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
- 将新元素插入到该位置后
- 重复步骤2~5
4.2选择排序
第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。 以此类推,直到全部待排序的数据元素的个数为零。
4.3冒泡排序
1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
4.4快速排序
- 选取第一个数为基准
- 将比基准小的数交换到前面,比基准打的数交换到后面
- 对左右区间重复第二步,直到各区间只有一个数
4.5归并排序
- 把长度为n的输入序列分成两个长度为 n/2 的子序列
- 对这两个子序列采用归并排序
- 将两个排序好的子序列合并成一个最终的排序序列
5.排序算法代码
4.1插入排序
void insertSort(int* a,int len)
{
for (int i = 0; i < len - 1; i++) {
int j = i + 1;
while (a[j] < a[j - 1] && j > 0) {
int tmp = a[j];
a[j] = a[j - 1];
a[j - 1]=tmp;
j--;
}
}
}
4.2选择排序
void selectionSort(int *a, int len)
{
int minn = 0;
for (int i = 0; i < len; i++) {
minn = i;
for (int j = i + 1; j < len; j++) {
if (a[j] < a[minn]) {
minn = j;
}
}
int tmp = a[i];
a[i] = a[minn];
a[minn] = tmp;
}
}
4.3冒泡序
void bubbleSort(int* a, int len)
{
for (int i = 0; i < len - 1; i++) {
for (int j = 0; j < len - i - 1; j++) {
if (a[j] > a[j + 1]) {
int tmp = a[j];
a[j] = a[j+1];
a[j+1] = tmp;
}
}
}
}
4.4快速排序
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int a[1000001];
void print(int n)
{
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
int getRand(int l,int r)
{
srand(time(0));
return rand()%(r-l+1)+l;
}
void quicksort(int l,int r)
{
int flag=a[getRand(l,r)];
int i=l,j=r;
while(i<=j)
{
while(a[i]<flag)
i++;
while(a[j]>flag)
j--;
if(i<=j)
{
swap(a[i],a[j]);
j--,i++;
}
}
if(i<r)
quicksort(i,r);
if(l<j)
quicksort(l,j);
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
quicksort(1,n);
print(n);
return 0;
}
4.5归并排序
void MergeSort(int l,int r)
{
if (l == r) {
return ;
}
int mid = (l + r) / 2;
MergeSort(l, mid);
MergeSort(mid + 1, r);
int i = l, j = mid + 1, k = l;
while (i <= mid && j <= r) {
if (a[i] <= a[j]) {
t[k++] = a[i++];
} else {
t[k++] = a[j++];
}
}
while (i <= mid) {
t[k++] = a[i++];
}
while (j <= r) {
t[k++] = a[j++];
}
for (int i = l; i <= r; i++) {
a[i] = t[i];
}
}