1.冒泡排序:
代码:
//冒泡
void bubblesort(vector<int>&v) {
int n = v.size();
for (int i = 1; i < n; i++) {//表示趟数
bool flag = 0;
for (int j = 0; j < n - i; j++) {
//表示待排序序列的下标
if (v[j] > v[j + 1]) {
swap(v[j], v[j + 1]);
flag = 1;
}
}
if (flag == 0) {
break;
}
}
}
时间复杂度:
最优情况:O(n) 有序 1趟排序 n-1次比较
最差情况:O(n^2) 逆序 n-1趟排序
稳定性:
稳定
2.选择排序:
代码:
//选择
void selectsort(vector<int>& v) {
int n = v.size();
for (int i = 1; i < n; i++) {//i表示趟数
int index = 0;
for (int j = 1; j <= n - i; j++) {
if (v[index] < v[j]) {
index = j;
}
}
//每一趟找待排序序列当中的最大值
//让其与排序序列最后一个元素 发生交换
if (index != n - i) {
swap(v[n - i], v[index]);
}
}
}
时间复杂度:
O(n^2)
稳定性:
不稳定
3.插入排序:
代码:
//插入
void insertsort(vector<int>& v) {
int n = v.size();
for (int i = 1; i < n; i++) {
int j = i - 1;
int temp = v[i];
for (; j >= 0; j--) {
if (v[j] > temp) {
v[j + 1] = v[j];
}
else {
break;
}
}
v[j + 1] = temp;
}
}
时间复杂度:
最优情况:O(n) 有序 每一趟只需要一次比较
最差情况:O(n^2) 逆序 每一趟有序区有多少个元素 就需要比较多少次
稳定性:
稳定
4.计数排序:
代码:
//计数
int maxval(vector<int>& v) {
int max = v[0];
int n = v.size();
for (int i = 1; i < n; i++) {
if (v[i] > max) {
max = v[i];
}
}
return max;
}
void bucketsort(vector<int>& v) {
int n = v.size();
//1.找原数组最大值
int max = maxval(v);
//2.要给桶申请足够大的空间
vector<int>bucket(max + 1);
//3.遍历原数组 用桶进行计数
for (int i = 0; i < n; i++) {
bucket[v[i]]++;
}
//4.遍历桶 把元素拿回原数组
int index = 0;//记录数据拿回到什么位置的
for (int i = 0; i <= max; i++) {
while (bucket[i]--) {
v[index++] = i;
}
}
}
时间复杂度:
O(n)
稳定性:
稳定
5.堆排序:
代码:
//堆排
void adjust(vector<int>& v, int start, int end) {
int father = start;
int child = father * 2 + 1;
while (child <= end) {
if (child + 1 <= end && v[child + 1] > v[child]) {
child++;
}
if (v[child] > v[father]) {
swap(v[father], v[child]);
father = child;
child = 2 * father + 1;
}
else {
break;//避免死循环
}
}
}
void heapsort(vector<int>& v) {
int n = v.size();//待排序元素个数
//1.初始化堆 形成最大堆 任何一个父亲节点都大于孩子节点
for (int i = n / 2 - 1; i >= 0; i++) {//从最后一个父亲节点的位置开始调整
adjust(v, i, n - 1);//下标最多达到n-1 下限
}
//2.拿堆顶元素跟待排序序列最后一个元素发生交换
for (int j = n - 1; j >= 1; j--) {//j表示的是待排序序列最后一个元素下标
swap(v[0], v[j]);
//重新调整结构
adjust(v, 0, j - 1);//此时j位置的值已经固定 待排序序列元素个数减少一个
}
}
时间复杂度:
稳定性:
不稳定
6.快速排序:
代码:
//快排
void quicksort(vector<int>& v, int start, int end) {
if (start >= end) {//基线条件
return;
}
int temp = v[start];//区域内第一个元素定成基准值
int i = start-1, j = end + 1;
int index = start;
while (index < j) {
if (v[index] == temp) {
index++;
}
else if(v[index]>temp) {
swap(v[--j], v[index]);
}
else {
swap(v[++i], v[index++]);
}
}
//递归条件
quicksort(v, start, i);
quicksort(v, j, end);
}
时间复杂度:
最优情况: 有序
最差情况: 逆序
稳定性:
不稳定
7.归并排序:
代码:
//归并
void merge(vector<int>& v, int L, int mid, int R) {
//主要思想 将两个有序数组合成一个有序数组
//先分再和
int n = R - L + 1;
vector<int>temp(n);
int index = 0;
int i = L, j = mid + 1;//控制左右侧下标
while (i <= mid && j <= R) {
if (v[i] <= v[j]) {
temp[index++] = v[i++];
}
else {
temp[index++] = v[j++];
}
}
while (i <= mid) {
temp[index++] = v[i++];
}
while (j <= R) {
temp[index++] = v[j++];
}
i = L;//将合并后的元素拿回到原数组中
for (index = 0; index < n; index++) {
v[i++] = temp[index];
}
}
void merg(vector<int>& v, int L, int R) {
//基线条件
if (L == R) {//区域内只剩下一个元素为止
return;
}
//当区域内元素多于一个 需要找中间位置进行分割
int mid = (R - L) / 2 + L;
//递归条件
merg(v, L, mid);//向左分割
merg(v, mid + 1, R);//向右分割
merge(v, L, mid, R);//合并
}
时间复杂度:
稳定性:
稳定