1.冒泡排序 o(n^2)
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
void maopao(vector<int>& t) {
for (int i = 0; i < t.size()-1; i++) {
bool flag = false;
for (int j = 0; j < t.size() - i - 1; j++) {
if (t[j] > t[j + 1]) {
swap(t[j], t[j + 1]);
flag = true;
}
}
if (flag == false)
break;
}
}
int main() {
vector<int> t{ 9,9,8,7,8,6,6,5,4,3 };
maopao(t);
for (auto i = t.begin(); i != t.end(); i++)
cout << *i << " ";
cin.get();
}
2.选择排序:每一轮选择最小的元素在已排序集合后面(时间复杂度o(n^2))稳定
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void xuanze(vector<int>& t) {
int k;
for (int i = 0; i < t.size(); i++) {
k = i;
for (int j = i+1; j < t.size(); j++) {
if (t[j] < t[i]) k = j;
}
swap(t[k], t[i]);
}
}
int main() {
vector<int> t{ 9,8,7,6,5,4,3,2,1,0 };
xuanze(t);
for (auto it = t.begin(); it != t.end(); it++)
cout << *it << " ";
cin.get();
}
3.插入排序(数组基本有序时效率高)每一轮将元素插入到已排序的集合中o(n^2) 最好是n,稳定
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void charu(vector<int>& t) {
for (int i = 1; i < t.size(); i++) {
for (int j = i; j > 0; j--) {
if (t[j] < t[j - 1])
swap(t[j], t[j - 1]);
else
break;
}
}
}
int main() {
vector<int> t{ 9,8,7,6,5,4,3,2,1,0 };
charu(t);
for (auto it = t.begin(); it != t.end(); it++)
cout << *it << " ";
cin.get();
}
4.希尔排序(优化版的插入排序,适用于长数组,优化了步长,逐渐减少至1,变为插入)o(n^2) 不稳定
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void xier(vector<int>& t) {
int n = 1;
int m = t.size() / 3;
while (n < m)
n = 3 * n + 1;
while (n > 0) {
for (int i = n; i < t.size(); i++) {
for (int j = i; j >= n; j-=n) {
if (t[j] < t[j - n])
swap(t[j], t[j - n]);
}
}
n /= 3;
}
}
int main() {
vector<int> t{ 9,8,7,6,5,4,3,3,2,2,1,0 };
xier(t);
for (auto it = t.begin(); it != t.end(); it++)
cout << *it << " ";
cin.get();
}
5.快速排序(冒泡的优化版本,每次递归后把轴放在中间,使得轴比左大比右小)(仅数组,若要在链表上实现需要改为遍历只涉及从一端到另一端)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void kuaisu(vector<int>& t,int left, int right) {
int i = left, j = right;
if (left >= right)
return;
int pivot = t[i];
while (i < j) {
while (i<j&&t[j] >= pivot) j--;
t[i] = t[j];
while (i < j && t[i] <= pivot) i++;
t[j] = t[i];
}
t[i] = pivot;
kuaisu(t, left, i - 1);
kuaisu(t, i + 1, right);
}
int main() {
vector<int> t{ 1,2,3,4,5,9,7,8,9,11,11};
kuaisu(t,0,t.size()-1);
for (auto it = t.begin(); it != t.end(); it++)
cout << *it << " ";
cin.get();
}
6.归并排序(分治思想)空间复杂度o(n),时间复杂度o(nlogn)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void mmerge(vector<int>& t, vector<int>& temp, int left, int mid, int right) {
int i = left;
int j = mid + 1;
int pos = left;
while (i <= mid && j <= right) {
temp[pos++] = (t[i] <= t[j]) ? t[i++] : t[j++];
}
while (i <= mid)
temp[pos++] = t[i++];
while (j <= right)
temp[pos++] = t[j++];
while (left <= right) {
t[left] = temp[left];
left++;
}
}
// 划分子区间
void guibing(vector<int>& t, vector<int>& temp, int left, int right) {
int mid = left + (right - left) / 2;
if (left < right) {
guibing(t, temp, left, mid);
guibing(t, temp, mid + 1, right);
mmerge(t, temp, left, mid, right);
}
}
// 排序入口
void rukou(vector<int>& t, int left, int right) {
vector<int> temp;
temp.resize(t.size());
guibing(t, temp, 0, t.size() - 1);
}
int main() {
vector<int> t{ 9,8,7,7,100,100,3,97,1,0 };
rukou(t, 0, static_cast<int>(t.size()) - 1);
for (auto it = t.begin(); it != t.end(); it++)
cout << *it << " ";
cin.get();
}
7.计数排序(利用数组下标天然有序)
#include<iostream>
#include<vector>
using namespace std;
void jishu(vector<int>& t) {
vector<int>temp(100, 0);
for (int i = 0; i < t.size(); i++) {
temp[t[i]]++;
}
for (int i = 0,j=0; i < temp.size(); i++) {
while (temp[i]--) {
t[j++] = i;
}
}
}
int main() {
vector<int>t{ 9,8,7,6,6,5,5,4,3,2,1,1,0 };
jishu(t);
for (auto i = t.begin(); i < t.end(); i++)
cout << *i << " ";
cin.get();
}
8.基数排序
#include<iostream>
#include<vector>
using namespace std;
void jishutong(vector<int>& t) {
int j;
int pos;
for (int k = 10; k < 10000; k *= 10) {
vector<vector<int>>temp(10);
for (int i = 0; i < t.size(); i++) {
j = 0;
pos = (t[i] / k) %10;
temp[pos].push_back(t[i]);
}
//遍历一轮后写入源容器
pos = 0;
for (int i = 0; i < temp.size(); i++) {
for (int j = 0; j < temp[i].size(); j++) {
t[pos++] = temp[i][j];
}
}
}
}
int main() {
vector<int>t{ 965,987,798,665,645,565,545,445,323,89};
jishutong(t);
for (auto i = t.begin(); i < t.end(); i++)
cout << *i << " ";
cin.get();
}
9.堆排序 维护堆:o(logn) 建堆:o(n)
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void weihu(vector<int>& t,int n,int i) {
int tar = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && t[tar] < t[left])
tar = left;
if (right < n && t[tar] < t[right])
tar = right;
if (tar != i){
swap(t[i], t[tar]);
weihu(t,n,tar);
}
}
void create(vector<int>& t,int n) {
int i;
for (i = n/2-1; i >= 0; i--) {
weihu(t,n,i);
}
for (int i = t.size()-1; i >0; i--) {
swap(t[i], t[0]);
weihu(t,i,0);
}
}
int main() {
vector<int> t{ 8,4,5,6,5,4,3,1,2 };
create(t,t.size());
for (auto i = t.begin(); i != t.end(); i++)
cout << *i << " ";
cin.get();
}
10.桶排序
是计数排序和基数排序的基础:首先根据取值范围将数组内元素放入各个桶中,在每个桶运用某个排序算法进行排序,最后合并;