1:冒泡排序
基本思路就是:枚举每对相邻的数,如果 左边的数 > 右边的数,交换(左边元素,右边元素);
例子:9 8 7 6 5 4 3 2 1这九个数(从小到大):
第一次j从1枚举到8,让k=j+1;.然后开始枚举;9会和后面每个数都交换一遍。
所以第一遍换完以后就是8 7 6 5 4 3 2 1 9;
第二次重复上述操作,8会和7~1每个数都交换,数组变成7 6 5 4 3 2 1 9 8;
第三次:6 5 4 3 2 1 7 8 9
第四次:5 4 3 2 1 6 7 8 9.》》
》》最后就变成了1 2 3 4 5 6 7 8 9
程序:
#include<bits/stdc++.h>
using namespace std;
int n,a[1000001];
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<n;i++)//枚举
{
for(int j=1;j<n;j++)
{
int k=j+1;
if(a[j]>a[k])
{
int t=a[j];
a[j]=a[k];
a[k]=t;
}
}
cout<<"第"<<i<<"次"<<":"<<' ';
for(int j=1;j<=n;j++) cout<<a[j]<<' ';
cout<<endl;
}
}
2:选择排序:
思路:把第一个没有排序过的元素设置为最小值,
遍历每个没有排序过的元素,
如果元素 < 现在的最小值,
将此元素设置成为新的最小值,
将最小值和第一个没有排序过的位置交换。
例子:9 8 7 6 5 4 3 2 1
第一次开始时最小值定义为9,然后遍历找到最小值1,1和9交换:1 8 7 6 5 4 3 2 9
第二次开始时最小值定义为8,然后遍历找到最小值2,2与8交换:1 2 7 6 5 4 3 8 9
然后依次重复,最后得到1 2 3 4 5 6 7 8 9;
程序:
#include<bits/stdc++.h>
using namespace std;
int n,a[1000001];
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<n;i++)
{
int minn=i;
for(int j=i+1;j<=n;j++)
{
if(a[minn]>a[j])
minn=j;
}
if(i!=minn)//如果最小值就是自己就不用交换了
{
int t=a[minn];
a[minn]=a[i];
a[i]=t;
}
cout<<"第"<<i<<"次"<<":"<<' ';
for(int j=1;j<=n;j++) cout<<a[j]<<' ';
cout<<endl;
}
return 0;
}
3:插入排序:
思路:i从1枚举到n每次枚举都和它之前的数列进行比较,如果第i个数比比较的数小,比较的数往后移动一格,知道第i个数找到合适的位置(就是比较的数比他小),然后插入,这样就可以保证前i个数字有序。
过程:由于我是读入一个插入一个,所以没有排序的都是0
程序:
#include<bits/stdc++.h>
using namespace std;
int a[100111];//有序数组
int n,x,k;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
for(k=i;k>0;k--)
{
if (a[k-1]>x) a[k]=a[k-1];//往后移动
else break;//找到合适的位置
}
a[k]=x; //插入
cout<<"第"<<i<<"次"<<":"<<' ';
for(int i=1;i<=n;i++) cout<<a[i]<<' ';
cout<<endl;
}
// for(int i=1;i<=n;i++)printf("%d",a[i]);
return 0;
}
4:归并排序:
其实是采用了分治的思想,我们可以先假设一格长度为8的数组,把他的前4的和后四个都是有序的
比如:1 2 3 4 ||| 3 4 5 6 然后把他们合并;可以设两个指针i=1,j=5;把第i个和第j个比较,明显1比3小,就把1放在第一个,i++;
如果第i个大于第j个,那就把第j个放进去,j++;
但是怎么把数组变成前一半和后一半都有序呢,就在每一半都进行同样的操作。
(于是我找到一张形象的图:
然后是代码:
#include<bits/stdc++.h>
using namespace std;
//归并过程
void merge(int arr[], int l, int mid, int r){
int help[r-l+1];//辅助数组
int i = 0;
int lIndex = l;
int rIndex = mid+1;
while(lIndex <= mid && rIndex <= r){
help[i++] = arr[lIndex] < arr[rIndex] ? arr[lIndex++]:arr[rIndex++];
}
//左边和右边肯定有一边到头了,不可能同时,因为每次只移动一边
while(lIndex <= mid){
help[i++] = arr[lIndex++];
}
while(rIndex <= r){
help[i++] = arr[rIndex++];
}
//将排好序的辅助数组赋值给原始数组,不需要返回值
for(i = 0; i < r-l+1; i++){
arr[l+i] = help[i];
}
}
//递归
static void mergeSort(int arr[], int l, int r){
if(l == r){
return;
}
int mid = (l + r) / 2;
//左半部分归并排序
mergeSort(arr, l, mid);
//右半部分归并排序
mergeSort(arr, mid+1, r);
//左右部分归并
merge(arr, l, mid, r);
}
//归并排序整个数组
void mergeSort(int arr[], int n){
//如果数组为空或只有一个元素,不需要排序
if(arr == NULL || n < 2){
return;
}
mergeSort(arr,0,n-1);
}
int main(){
int n;
while(cin >> n){
int arr[n];
for(int i = 0; i < n; i++) cin >> arr[i];
mergeSort(arr, n);
for(int i = 0; i < n; i++){
cout << arr[i] << " ";
}
cout << endl;
}
return 0;
}
5:计数排序:
采用了空间换时间的思路
开一个很大的数组,读入一个数x,就a[x]++;
找最大值maxx
最后按顺序从1到maxx,每输出一个就a[i]--;直到a[i]==0;
这个的实用性低,但是好理解,就直接放代码了。
代码:
#include<bits/stdc++.h>
using namespace std;
int a[100111];//有序数组
int n,x,maxx=-1;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x;
if(x>maxx) maxx=x;//找最大值,
a[x]++;
}
for(int i=1;i<=maxx;i++)
{
while(a[i])
{
cout<<i<<' ';
a[i]--;
}
}
return 0;
}
6:基数排序
由于是按位数排序,就大一点,不是1~9了。
3221, 1, 10, 9680, 577, 9420, 7, 5622, 4793, 2030, 3138, 82, 2599, 743, 4127
对于一串数,先按个位排序(按先后顺序)
0:10 9680 9420 2030
1:3221 1
2: 5622 82
3: 4793 743
没有就省略了
7:577 7 4127
8:3138
9:2599
按顺序再放回去:10 9680 9420 2030 3221 1 5622 82 4793 743 577 7 4127 3138 2599
然后在十位数排序
在放回去,从下往上按顺序:
再按百位数排序:
放回去:
千位:
再放回去:
由于没万位数了,就不用继续了;
由于本人比较蔡,代码先鸽了。