6种排序

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

然后在十位数排序

 

 

在放回去,从下往上按顺序:

 

再按百位数排序:

放回去:

千位:

 

 

再放回去:

 

由于没万位数了,就不用继续了;

由于本人比较蔡,代码先鸽了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值