写在最前面:
这里的所有的排序方法都是我从挑战程序设计竞赛中学习的排序方法,也许c++里面一个sort()就可以搞定的事情,但是还是有必要巩固一些基础的知识吧,否则当去别家的公司面试连最简单的排序都不会就尴尬了。这次的总结也权当是一次复习。
一.插入排序:
说明:从头一开始依次遍历整个数组,当前的数字小于前面的数字时,往前查找,直达查询到小于等于它的数字;
代码如下:
#include <bits/stdc++.h>
using namespace std;
//插入排序
//性质:
//①时间复杂度是O(n^2),排有序的数组复杂度可以达O(n)
//②这是一种稳定的排序
const int maxn = 1e5+5;
int num[maxn];
int N;
void insert_sort(){
for (int i=1; i<N; i++){
int j = i-1;
int temp = num[i];
while (j>=0&&num[j] > temp){
num[j+1] = num[j];
j--;
}
num[j+1] = temp;
}
return;
}
void print(){
for (int i=0; i<N; i++){
cout<<num[i]<<" ";
}
return;
}
int main()
{
cin>>N;
for (int i =0;i <N; i++){
cin>>num[i];
}
insert_sort();
print();
return 0;
}
#include <bits/stdc++.h>
using namespace std;
//冒泡排序
//性质:
//①时间复杂度是O(n^2)
//②可以求出一个数列的逆序数,这个在线性代数中可以用到
int N;
const int maxn = 1e5+5;
int num[maxn];
int bubble_sort(){
int sw = 0;
for (int i=0; i<N; i++){
for (int j=0;j<N-i-1;j++){
if (num[j]>num[j+1]){
swap(num[j], num[j+1]);
sw++;
}
}
}
return sw;
}
int main()
{
cin>>N;
for (int i =0; i<N; i++){
cin>>num[i];
}
int tot = bubble_sort();
for (int i=0; i<N; i++){
cout<<num[i]<<" ";
}
cout<<endl;
cout<<"逆序数是:"<<tot<<endl;
return 0;
}
三.选择排序:
说明:从这个数列中找出未排列数列的最小数的下标,将相对的最小的数放在前面,I++,直到遍历完整个数组。
代码:
#include <bits/stdc++.h>
using namespace std;
int N;
const int maxn = 1e5+5;
int num[maxn];
void select_sort(){
for (int i=0; i<N; i++){
int sw = 0;
int min_index = i;
for (int j = i; j<N; j++){
if (num[j]<num[min_index])
min_index = j;
}
swap(num[i], num[min_index]);
}
return ;
}
int main()
{
cin>>N;
for(int i=0; i<N; i++){
cin>>num[i];
}
select_sort();
for (int i=0; i<N; i++){
cout<<num[i]<<" ";
}
return 0;
}
四.稳定排序:
说明:这应该属于一种思想概念吧:
例子:1Z 5E 2S 7G 2M
我们按照数字的大小进行升序排序。如果排序后2M在2S前面,则这种排序是不稳定的排序。
如果相同的值并且排序之后他们原来的相对位置没有改变,则这种排序是稳定排序。
上面的三种排序中:冒泡排序(注意这里的筛选条件是<,若是<=则排序是不稳定的排序)和插入排序都是稳定排序,选择排序是不稳定的排序。
总结:上面的排序都是初等的排序方法,这些排序的效率比较的低下,都是O(n^2)的复杂度,当然还有初级的排序方法:桶序法,它的时间复杂度是O(n),但是它有相当大的空间复杂度,相当于是空间换时间。
IMPLEMENT:希尔排序
说明:shell sort结合了插入排序的优点,通过数学的方法经过打表打出一张排序的间隔表,之后排序,时间复杂度约为O(n^(1.25));没有具体的数学证明,详情见P55.
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int N;
int num[maxn];
vector<int> G;
void insert_sort(int interval){//这个间隔的过程可以想象interval=1的情形,这样比较容易理解!
for (int i=interval; i<N; i++){
int temp = num[i];
int j = i - interval;
while(j>=0&&num[j] > temp){
num[j+interval] = num[j];//开始向前的搬运工作
j -= interval;
}
num[j+interval] = temp;
}
return;
}
//生成一张要排序的间隔的表
void shell_sort(){
for (int h=1; ; ){
if (h>N) break;
G.push_back(h);
h = 3*h+1;
}
for (int i = G.size()-1; i>=0; i--){
int interval = G[i];
insert_sort(interval);
}
return ;
}
int main()
{
srand((unsigned)time(NULL));//为了产生随机数而生成的随机种子
cin>>N;
for (int i=0; i<N; i++){
num[i] = rand()%1000;
}
shell_sort();
for (int i =0; i<N; i++){
cout<<num[i]<<" ";
}
return 0;
}
真的是总结啊:
上面的排序方法是简单的排序,希望自己还有时间整理下二分排序,归并排序等高级的排序方法吧。
也希望自己能好好的刷题,迎接下面的training~~:-D