题目描述:
请创建一个一维整型数组用来存储待排序关键码,关键码从数组下标为1的位置开始存储,下标为0的位置不存储关键码。输入关键码的个数,以及各个关键码,采用起泡排序方法对关键码数组进行排序(从小到大)。输出排好序之前的每一趟排序后的关键码序列。
输入描述
各个命令以及相关数据的输入格式如下: 第一行输入关键码的个数n 第二行输入n个整型关键码
输出描述
输出关键码比较过程,即输出每一趟排序后的关键码序列,每轮一行,关键码之间以空格隔开,最后一个关键码后有空格,然后回车
输入样例
输入样例1: 5 1 2 4 3 5 输入样例2: 5 5 4 3 2 1
输出样例
输出样例1: 1 2 3 4 5 输出样例2: 4 3 2 1 5 3 2 1 4 5 2 1 3 4 5 1 2 3 4 5
方法一:(独创的馊主意)
#include<iostream>
using namespace std;
int main()
{
int a[100],n,temp;
//输入排序数的个数;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
//起泡排序
for(int i=0;i<n;i++)
{
if(n%2==0)//n的奇偶判断
for(int j=0;j<n-i;j++)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
else
for(int j=0;j<n-i-1;j++)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
//用于控制验证是否排序将完成(完成前的每一趟交换后的数据输出);
int flag=1;
for(int c=0;c<n-1;c++)
{
if(a[c]>=a[c+1])
{
flag=0;
}
}
if(flag==0)
{
for(int k=0;k<n;k++)
{
cout<<a[k]<<" ";
}
}
}
//对排序完成后的数据输出
for(int k=0;k<n;k++)
cout<<a[k]<<" ";
return 0;
}
方法二:
#include<iostream>
using namespace std;
int main()
{ int n,b1=0;
while(cin>>n)
{
int j;
b1++;
int data[n+1];
for(int i=0;i<n;i++)
{
cin>>data[i];
}
int temp,ex,b;
ex=n-1;
cout<<"输出样例"<<b1<<":"<<endl;
while(ex!=0)
{
b=ex;ex=0;
for(j=0;j<b;j++)
{
if(data[j]>data[j+1])
{
temp=data[j];
data[j]=data[j+1];
data[j+1]=temp;
ex=j;
}
}
int flag=1;
for(int c=0;c<n-1;c++)
{
if(data[c]>=data[c+1])
{
flag=0;
}
}
if(flag==0)
{
for(int k=0;k<n;k++)
{
cout<<data[k]<<" ";
}
cout<<endl;
}
}
for(int k=0;k<n;k++)
{
cout<<data[k]<<" ";
}
}
}
方法三:(和方法二一样,只不过构造了函数)
#include <iostream>
using namespace std;
class Sort
{
public:
void BubbleSort(int data[]);
int length;
};
void Sort::BubbleSort(int data[])
{
int j;
int exchange;
int bound;
int temp;
exchange = length-1; //第一趟起泡排序的区间是 [0-length-1]
while(exchange != 0)
{
bound = exchange; exchange = 0;
for ( j = 1; j < bound;j++)
{
if(data[j] > data[j+1])
{
temp = data[j];
data[j] = data[j+1];
data[j+1] = temp;
exchange = j;
}
}
int flag=1;
for (j = 1; j < length-1;j++)
{
if (data[j] > data[j+1])
flag=0;
}
if(flag==0)
{
for (int k = 1;k < length;k++)
{
cout <<data[k]<<" ";
}
cout <<endl;
}
}
for (int k = 1;k < length;k++)
{
cout << data[k]<<" ";
}
}
int main ()
{
int i;
cin>> i;
int a[i+1];
Sort S;
S.length = i+1;
for (int j = 1;j < i+1;j++)
{
cin>> a[j];
}
S.BubbleSort(a);
return 0;
}
冒泡排序是因为越小的元素会经由交换以升序或降序的方式慢慢浮
到数列的顶端,就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名冒泡排序。
复杂度与稳定性
思路原理
以顺序为例
-
从第一个元素开始一个一个的比较相邻的元素,如果第一个比第二个大即
a[1]>a[2]
,就彼此交换。 -
从第一对到最后一对,对每一对相邻元素做一样的操作。此时在最后的元素应该会是最大的数,我们也称呼
一遍这样的操作
为一趟冒泡排序。 -
针对所有的元素重复以上的步骤,每一趟得到的最大值已放在最后,下一次操作则不需要将此最大值纳入计算。
-
持续对每次对越来越少的元素,重复上面的步骤。
-
直到所有的数字都比较完成符合
a[i]<a[i+1]
,即完成冒泡排序。
图示过程
以数组数据{ 70,50,30,20,10,70,40,60}为例:
如图,每一次排序把一个最大的数被放在了最后,然后按照这个趋势逐渐往前,直到按从小到大的顺序依次排序。
到了第4轮的时候,整个数据已经排序结束了,但此时程序仍然在进行。
直到第5,6,7轮程序才算真正的结束,这其实是一种浪费算力的表现。
void bubble(int a[],int n) {
for(int i=0; i<n; i++) {
for(int j=0; j<n-i; j++) {
if(a[j]>a[j+1]) {
swap(a[j],a[j+1]); //交换数据
}
}
}
}
注意,由于C++的namespace std
命名空间的使用,std自带了交换函数swap(a,b)
,可以直接使用,其功能是交换a与b的两个值,当然你可以自定义swap函数
其代码为
void swap(int &a, int &b) { //指定类型(整型)
int temp = a;
a = b;
b = temp;
}