1、冒泡排序(Bubble Sort)
算法描述
1.比较相邻的元素。如果第一个比第二个大,就交换它们两个;
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
3.针对所有的元素重复以上的步骤,除了最后一个;
重复步骤1~3,直到排序完成。
动画演示
代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
void bubble_sort(vector<int> &q)
{
for (int i = q.size() - 1; i > 0; i -- )
{
bool flag = false;
for (int j = 0; j + 1 <= i; j ++)
if (q[j] > q[j + 1])
{
swap(q[j], q[j + 1]);
flag = true;
}
if (!flag) break;
}
}
int main()
{
int n;
vector<int> q;
cin >> n;
for (int i = 0, t; i < n; i ++ )
{
cin >> t;
q.push_back(t);
}
bubble_sort(q);
for (auto x : q) cout << x << ' ';
cout << endl;
return 0;
}
for (int i = 0; i < a.length - 1; i++) { // 轮数
for (int j = 0; j < a.length - 1 - i; j++) {
if (a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
2、选择排序(Selection Sort)
算法描述
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
以此类推,直到所有元素均排序完毕。
动画演示
代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
void selection_sort(vector<int> &q)
{
for (int i = 0; i < q.size(); i ++ )
for (int j = i + 1; j < q.size(); j ++ )
if (q[i] > q[j])
swap(q[i], q[j]);
}
int main()
{
int n;
vector<int> q;
cin >> n;
for (int i = 0, t; i < n; i ++ )
{
cin >> t;
q.push_back(t);
}
selection_sort(q);
for (auto x : q) cout << x << ' ';
cout << endl;
return 0;
}
3、插入排序(Insertion Sort)
算法描述
1.从第一个元素开始,该元素可以认为已经被排序;
2.取出下一个元素,在已经排序的元素序列中从后向前扫描;
3.如果该元素(已排序)大于新元素,将该元素移到下一位置;
4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
5.将新元素插入到该位置后;
重复步骤2~5。
动画演示
代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
void insertion_sort(vector<int> &q)
{
for (int i = 1; i < q.size(); i ++ )
{
int t = q[i], j;
for (j = i - 1; j >= 0; j -- )
if (q[j] > t)
q[j + 1] = q[j];
else break;
q[j + 1] = t;
}
}
int main()
{
int n;
vector<int> q;
cin >> n;
for (int i = 0, t; i < n; i ++ )
{
cin >> t;
q.push_back(t);
}
insertion_sort(q);
for (auto x : q) cout << x << ' ';
cout << endl;
return 0;
}
4、希尔排序(Shell Sort)
算法描述
1.选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
2.按增量序列个数k,对序列进行k 趟排序;
3.每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
动画演示
5、归并排序(Merge Sort)
算法描述
1.把长度为n的输入序列分成两个长度为n/2的子序列;
2.对这两个子序列分别采用归并排序;
3.将两个排序好的子序列合并成一个最终的排序序列。
动画演示
代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
void merge_sort(vector<int> &q, int l, int r)
{
if (l >= r) return;
int mid = (l + r) / 2;
merge_sort(q, l, mid);
merge_sort(q, mid + 1, r);
static vector<int> w;
w.clear();
int i = l, j = mid + 1;
while (i <= mid && j <= r)
if (q[i] <= q[j])
w.push_back(q[i ++ ]);
else
w.push_back(q[j ++ ]);
while (i <= mid) w.push_back(q[i ++ ]);
while (j <= r) w.push_back(q[j ++ ]);
for (i = l, j = 0; j < w.size(); i ++ , j ++ ) q[i] = w[j];
}
int main()
{
int n;
vector<int> q;
cin >> n;
for (int i = 0, t; i < n; i ++ )
{
cin >> t;
q.push_back(t);
}
merge_sort(q, 0, q.size() - 1);
for (auto x : q) cout << x << ' ';
cout << endl;
return 0;
}
6、快速排序(Quick Sort)
算法描述
1.从数列中挑出一个元素,称为 “基准”(pivot);
2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
3.递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
动画演示
代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
void quick_sort(vector<int> &q, int l, int r)
{
if (l >= r) return;
int i = l - 1, j = r + 1, x = q[l + r >> 1];
while (i <= j)
{
do i ++ ; while (q[i] < x);
do j -- ; while (q[j] > x);
if (i < j) swap(q[i], q[j]);
else quick_sort(q, l, j), quick_sort(q, j + 1, r);
}
}
int main()
{
int n;
vector<int> q;
cin >> n;
for (int i = 0, t; i < n; i ++ )
{
cin >> t;
q.push_back(t);
}
quick_sort(q, 0, q.size() - 1);
for (auto x : q) cout << x << ' ';
cout << endl;
return 0;
}
7、堆排序(Heap Sort)
算法描述
1.将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区;
2.将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),且满足R[1,2…n-1]<=R[n];
3.由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,……Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2….Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。
动画演示
代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
void push_down(vector<int> &heap, int size, int u)
{
int t = u, left = u * 2, right = u * 2 + 1;
if (left <= size && heap[left] > heap[t]) t = left;
if (right <= size && heap[right] > heap[t]) t = right;
if (t != u)
{
swap(heap[t], heap[u]);
push_down(heap, size, t);
}
}
void push_up(vector<int> &heap, int u)
{
while (u / 2 && heap[u / 2] < heap[u])
{
swap(heap[u / 2], heap[u]);
u /= 2;
}
}
void heap_sort(vector<int> &q, int n)
{
int size = n;
for (int i = 1; i <= n; i ++ ) push_up(q, i);
for (int i = 1; i <= n; i ++ )
{
swap(q[1], q[size]);
size -- ;
push_down(q, size, 1);
}
}
int main()
{
int n;
vector<int> q;
cin >> n;
q.resize(n + 1);
for (int i = 1; i <= n; i ++ ) cin >> q[i];
heap_sort(q, n);
for (int i = 1; i <= n; i ++ ) cout << q[i] << ' ';
cout << endl;
return 0;
}
8、计数排序(Counting Sort)
算法描述
1.找出待排序的数组中最大和最小的元素;
2.统计数组中每个值为i的元素出现的次数,存入数组C的第i项;
3.对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);
4.反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。
动画演示
代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
// 比如说给了10^7个数, 每个数在0~10^7之间
// 后缀数组
void counting_sort(vector<int> &q, int n)
{
vector<int> cnt(101, 0); // 假设每个数的数据范围都是0~100;
for (int i = 1; i <= n; i ++ ) cnt[q[i]] ++ ;
for (int i = 1, k = 1; i <= 100; i ++ )
while (cnt[i])
{
q[k ++ ] = i;
cnt[i] -- ;
}
}
int main()
{
int n;
vector<int> q;
cin >> n;
q.resize(n + 1);
for (int i = 1; i <= n; i ++ ) cin >> q[i];
counting_sort(q, n);
for (int i = 1; i <= n; i ++ ) cout << q[i] << ' ';
cout << endl;
return 0;
}
9、桶排序(Bucket Sort)
算法描述
1.设置一个定量的数组当作空桶;
2.遍历输入数据,并且把数据一个一个放到对应的桶里去;
3.对每个不是空的桶进行排序;
4.从不是空的桶里把排好序的数据拼接起来。
图片演示
10、基数排序(Radix Sort)
算法描述
1.取得数组中的最大数,并取得位数;
2.arr为原始数组,从最低位开始取每个位组成radix数组;
3.对radix进行计数排序(利用计数排序适用于小范围数的特点);
动画演示
代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int get(int x, int i)
{
while (i -- ) x /= 10;
return x % 10;
}
void radix_sort(vector<int> &q, int n)
{
vector<vector<int>> cnt(10); // 十个桶,int型数最多有十位
for (int i = 0; i < 3; i ++ ) // 个位,十位,百位
{
for (int j = 0; j < 10; j ++ ) cnt[j].clear();
for (int j = 1; j <= n; j ++ )
cnt[get(q[j], i)].push_back(q[j]);
for (int j = 0, k = 1; j < 10; j ++ )
for (int x : cnt[j])
q[k ++ ] = x;
}
}
int main()
{
int n;
vector<int> q;
cin >> n;
q.resize(n + 1);
for (int i = 1; i <= n; i ++ ) cin >> q[i];
radix_sort(q, n);
for (int i = 1; i <= n; i ++ ) cout << q[i] << ' ';
cout << endl;
return 0;
}