C++ 详解 —— 一维数组排序

“排序”就是按照某个关键字的大小,将若干对象从小到大或者从大到小进行重新排列。关键字是对象的某一个属性,它可以是任何基本数据类型,甚至结构体等。

例如,体育课上我们会按照身高从矮到高站队,这就是“升序”排序,身高是我们每个人的一个属性,也就是排序的关键字。

排序算法非常多,其中最基本的有选择排序、冒泡排序和插入排序三种。其本质上都是通过数组中的元素比较和交换来实现的,关键是数组下标的分析。

例1:

【问题描述】

给出n个同学的身高,请根据他们的身高升序排列并输出排序结果。

【输入格式】

第一行1个正整数n,表示有n个同学的身高,2<n≤100。

第二行包含n个正整数,之间用一个空格隔开,表示n个同学的身高。每个同学的身高都在150~200厘米之间。

【输出格式】

一行n个正整数,之间用一个空格隔开,表示n个同学根据身高升序排列的结果。

【输入样例】

7

180 170 176 160 155 150 160

【输出样例】

150 155 160 160 170 176 180

一、选择排序

选择排序的基本思想是:每一趟从待排序的数据中,通过“打擂台”比较选出最小元素,放在这些数据的最前面。这样,第一趟把n个数中(第1个到第n个)最小的放在第一个位置,第二趟把剩余的n-1个数中(第2个到第n个)最小的放在第二个位置,第三趟把剩余的n-2个数中(第3个到第n个)最小的放在第三个位,……第n-1趟把剩下的2个数中(第n-1个到第n个)最小的放在第n-1个位置,剩下的最后一个数(第n个)一定最大,自然落在了第n个位置。

//例1 选择排序参考代码
#include<bits/stdc++.h>
using namespace std;
int a[50],n;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i];

	for(int i=1;i<n;i++){
            for(int j=i+1;j<=n;j++)
                  if(a[i]>a[j])
                    swap(a[i],a[j]);
	}

	for(int i=1;i<=n;i++)
		cout<<a[i]<<" ";
	
	return 0; 
} 

处理逻辑:

~~~1.png

二、冒泡排序

冒泡排序的基本思想是:从第一个数开始,依次不断比较相邻的两个元素,如果“逆序”就交换。这样,一趟排序结束后,最大的元素就放在了第n个位置了。对于样例数据,第一趟冒泡排序的过程如下:

~~~2.png

用同样的方法,第二趟把剩余的前n-1个数中最大的交换到第n-1个位置,第三趟把剩余的前n-2个数中最大的交换到第n-2个位置,……经过n-1趟,排序结束。

//例1 冒泡排序参考代码
#include<bits/stdc++.h>
using namespace std;
int a[50],n;
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-i;j++){
          if(a[j]>a[j+1])
              swap(a[j],a[j+1]);
      }
  }
  	
  for(int i=1;i<=n;i++)
      cout<<a[i]<<" ";

  return 0; 
} 

对于冒泡排序,我们还可以做些算法“优化”。如果一趟排序下来,都没有任何“逆序”数对,即没有发生“交换”操作,则说明已经排好序了。此时,就可以立刻退出循环。

三、插入排序

插入排序的基本思想是:把所有待排序元素分成前后两段,前一段是已经排好序的,后一段是待排序的。每一趟都是把后一段的第一个数“插入”到前一段的某一个位置,保证前一段仍然是有序的。开始时,第1个数作为前一段肯定是有序的;第一趟,把第2个数插入进去,保证前2个数有序;第二趟,把第3个数插入进去,保证前3个数有;……第n-1趟,把第n个数插入进去,保证n个数都有序。

~~~3.png

//例1 插入排序参考代码
#include<bits/stdc++.h>
using namespace std;
int a[50],n,t,k;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    		
    for(int i=2;i<=n;i++){
        t=a[i];
        k=1;
        while(a[k]<=t && k<i)
            k++;
        for(int j=i-1;j>=k;j--)
            a[j+1]=a[j];
        a[k]=t;
    }
    	
    for(int i=1;i<=n;i++)
        cout<<a[i]<<" ";
    	
    return 0; 
} 

四、计数排序

计数排序的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数(此处并非比较各元素的大小,而是通过对元素值的计数和计数值的累加来确定)。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。

//例1 计数排序参考代码
#include<bits/stdc++.h>
using namespace std;
int a[50],x[50],n,maxx=-1e9,minn=1e9;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>x[i];	
        a[x[i]]++;
        if(x[i]>maxx) maxx=x[i];
        if(x[i]<minn) minn=x[i];
    }		
        for(int i=minn;i<=maxx;i++){
            for(int j=1;j<=a[i];j++)
                  cout<<i<<" ";
    }
    	
    return 0; 
} 

下面是各自动画演示:

1、选择排序

2.gif

2、冒泡排序

1.gif

3、插入排序

3.gif

四、计数排序 

4.gif

 

 

相关推荐

  1. C++数组

    2024-03-24 12:20:02       40 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-24 12:20:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-24 12:20:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-24 12:20:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-24 12:20:02       20 阅读

热门阅读

  1. vite vue3中使用 webworker

    2024-03-24 12:20:02       20 阅读
  2. (数据类型)前端八股文修炼Day1

    2024-03-24 12:20:02       13 阅读
  3. 【保姆级讲解计算机视觉的研究方向】

    2024-03-24 12:20:02       20 阅读
  4. 【Docker】常用命令 docker logs

    2024-03-24 12:20:02       16 阅读
  5. 第二十八章:Docker自动化部署脚本

    2024-03-24 12:20:02       13 阅读
  6. CloudCompare 二次开发(30)——均匀采样

    2024-03-24 12:20:02       22 阅读
  7. Web 中的 3D 游戏

    2024-03-24 12:20:02       18 阅读