桶排序、冒泡排序、快速排序
排序
一、桶排序
1、算法思想与原理
- 设置两个数组,分别存放桶和输入的因素
- 桶数组通过循环排序后,输入数字出现几次,在对应桶处标记几次并打印
- 依次打印排序后的数据
2、算法思路
- for循环:初始化数组、输入一串数字并读入数组、依次判断标记桶、打印排序好后的数组
3、代码实现
3.1最简单粗暴滴方法
#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
int a[11],i,j,t;
//int n[5];
for(i=0;i<=10;i++) //将数组中的所有初始化为0
a[i]=0;
for(i=1;i<=5;i++) //循环输入5个数
{
cin>> a[i];
}
for(i=0;i<=10;i++) //依次判断a[0]~a[10]
for(j=1;j<=a[i];j++) //依次打印排序好的数列
cout<<i;
return 0;
}
说明:
(1)只能输入事先预定设置的数组个数
(2)数组中每个数的大小不能超过10
(3)没有人机交互
优化:
(1)从大到小排序
(2)先指定输入数组的大小再完成
3.2 进阶可指定数组大小
#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
int a[201],i,j,t,n;
for(i=0;i<=200;i++) //将数组中的所有初始化为0
{
a[i]=0;
}
cin>>n; //输入一个数n,表示接下来的数组中有n个数
for(i=1;i<=n;i++) //循环输入n个数
{
cin>>a[i]; //把变量读入桶中
a[i]++; //在对应桶中计数
}
for(i=0;i<=n;i++) //依次判断a[0]~a[n]
for(j=1;j<=a[i];j++) //依次打印排序好的数列
cout<<i;
return 0;
}
效果如下:
错误:2、9、1变成了指定1、2、3数字的个数
错误原因:存放输入数组数据时,没有用一个数组来存放,导致最终丢失输入数据
修改如下:
#include<bits/stdc++.h> //调用万能头文件
using namespace std;
#define MAX 200 //定义数组长度
int n,a[MAX],t[MAX]; //分别定义两个数组、t[MAX]存放初始化桶、a[MAX]存放输入数组
int main(){
memset(t,0,sizeof t); //桶数组初始化为0
cin>>n; //输入数组元素数量,也可以用scanf("%d",&n);
for(int i=1;i<=n;i++){
cin>>a[i]; //读入数组每一个元素
t[a[i]]++; // 在初始化桶中计数
}
for(int i=0;i<=n;i++){ //!!!依次判断a[0]~a[n],所以i一定要从0开始,否则会漏掉数组里的数字
if(t[i]!=0){
for(int j=1;j<=t[i];j++) cout<<i<<' ';
}
}
return 0;
}
运行正确。
4、总结
(1)时间复杂度:O(M+N) m:桶的个数,n:待排序的个数
(2)缺点:不可对负数进行排序,因为数组的编号只能从a[0]开始
优点:是一个非常快速的排序方法
二、冒泡排序
1、算法思想与原理
思想:每次比较相邻的元素、若顺序错误则交换过来
原理:n个数进行排序,进行n-1次排序操作。“每一趟”需从第一位开始进行相邻两个数的比较,直至最后一个数比较完成。
2、算法逻辑
- 设置for循环进行整体n-1趟比较(n为输入数组个数)
- 循环将第i个数依次后后面每一个数字作比较
- if条件进行大小比较,并交换
- 循环输出结果
3、代码实现
蓝桥杯:基础练习——BASIC-13 数列排序
#include<iostream>
#include <string>
using namespace std;
int main()
{
int a[100];
int i,j,t,n;
cin>>n; //输入一个数,表示接下来有3个数
for(i=1;i<=n;i++) //循环读入n个数到数组a中
{
cin>>a[i];
}
//冒泡排序核心部分
for(i=1;i<=n-1;i++) //n个数排序,只需要进行n-1趟
{
for(j=1;j<=n-i;j++) //从第1位开始比较直到最后一个尚未归为的数 。
//第i个数比较时只需要比较后面的n-i位 ,所以循环中时n-i即可
{
if(a[j]>a[j+1]) //比较大小并交换
{
t=a[j]; a[j]=a[j+1]; a[j+1]=t;
}
}
}
//输出结果
for(i=1;i<=n;i++)
{
cout<<a[i]<<' ';
}
return 0;
}
代码完善后可完成按照名字对应的分数排序,代码修改如下:
#include<iostream>
#include <string>
using namespace std;
struct student //此处创建一个结构体储存姓名和分数
{
char name [21];
char score;
};
int main()
{
struct student a[100],t;
int i,j,n;
cin>>n; //输入一个数,表示接下来有3个数
for(i=1;i<=n;i++) //循环读入n个名字到结构体中
{
cin>>a[i].name;
}
for(i=1;i<=n;i++) //循环读入n个分数到结构体中
{
cin>>a[i].score;
}
//冒泡排序核心部分
for(i=1;i<=n-1;i++) //n个数排序,只需要进行n-1趟
{
for(j=1;j<=n-i;j++) //从第1位开始比较直到最后一个尚未归为的数 。
//第i个数比较时只需要比较后面的n-i位 ,所以循环中时n-i即可
{
if(a[j].score>a[j+1].score) //比较大小并交换
{
t=a[j]; a[j]=a[j+1]; a[j+1]=t;
}
}
}
//输出结果
for(i=1;i<=n;i++)
{
cout<<a[i].name<<' ';
}
return 0;
}
4、小结
- 时间复杂度:O(N ^ 2 )
三、快速排序
1、算法思想:
基于“二分”的算法思想,选取一个基准数将和两个指针分别指向数列的两端,并与基准数进行大小比较。通过比较完成对基准数的归位,即基准数左边比其大右边比其小。依次选取基准数归位后,便可完成整个数列的排序。
- 1.先从数列中取出一个数作为基准数。
- 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
- 3.再对左右区间重复第二步,直到各区间只有一个数。
2、算法实现
① 从数列中挑出一个元素,称为 “基准”(pivot),
② 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
③ 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
3、代码实现
#include <string>
#include<stdio.h>
using namespace std;
#include<iostream>
using namespace std;
void quickSort(int array[],int left,int right) //left,right分别是数组的起始下标
{
int i,j,k,temp;
if(left<right)
{
i=left;
j=right;
k=array[i]; //关键值(基准值)
do{
while((i<j)&&(array[j]>=k)) //顺序很重要,要先从右往左找
j--;
if(i<j) //右边的元素小于k,移到k的左边。
{
array[i]=array[j];
i++;
}
while((i<j)&&array[i]<=j) //再从左往右找
i++;
if(i<j) //左边的值小于k,移到看k的右边
{
array[j]=array[i];
}
}while(i!=j);
array[i]=k;//复制key值到array[i]
quickSort(array,left,i-1);//对i的左侧进行排序
quickSort(array,i+1,right);//对z的右侧进行排序
}
}
int main()
{
int a[110], i,n;
// char tmp[20];
cin>>n;
for (i = 0; i<n; i++) {
cin>>a[i];
}
quickSort(a, 0, 10);
cout<<"输出数组元素:"<<endl;
for (i = 0; i<n; i++)
cout<<a[i]<<' ';
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】