问题情境:
设计算法找出数组a[n]中相差最小的两个元素,考虑数组中的元素互不相同和有相同元素两种情况。
起泡排序/冒泡排序:
基本思想:
两两比较相邻记录,如果反序则交换,直到没有反序的记录为止。
排序过程:
(以升序排列为例)
(1)将整个待排序的记录序列划分为有序区和无序区,初始时有序区为空,无序区包括所有待排序的记录。
(2)对无序区从前向后依次比较相邻记录,若反序则交换,从而使得值较小的记录向前移,值较大的记录向后移。
(3)重复执行(2),直到无序区中没有反序的记录。
注意事项:
在第一趟起泡排序过程中,如果有多个记录交换到最终位置,则下一趟起泡排序将不处理这些记录;另外,在一趟起泡排序过程中如果没有记录相互交换,则表明序列已经有序,算法将终止。
代码实现:
#include<iostream.h>
#include<math.h>
void BubbleSort(int r[],int n)
{
int bound,exchange=n-1; //第一趟起泡排序的区间是【0,n-1】
while(exchange!=0) //当上一趟排序有记录交换时
{
bound=exchange;
exchange=0;
for(int j=0;j<bound;j++) //一趟起泡排序区间是【0,bound】
if(r[j]>r[j+1])
{
int temp=r[j]; //交换记录
r[j]=r[j+1];
r[j+1]=temp;
exchange=j; //记载每一次记录交换的位置
}
}
}
int main()
{
int n;
int r[100];
int j;
cout<<"请输入数组中元素的个数:"<<endl;
cin>>n;
cout<<"请输入数组中各个元素的值:"<<endl;
for(int i=0;i<n;i++)
{
cin>>r[i];
}
BubbleSort(r,n);
int a=0;
int b=1;
cout<<"排序后的顺序是:";
for(j=0;j<n;j++)
{
cout<<r[j]<<" ";
}
int dx=abs(r[1]-r[0]);
for(j=0;j<n;j++)
{
int dTmp;
dTmp=abs(r[j+1]-r[j]);
if(dTmp<dx)
{
a=j;
b=j+1;
dx=dTmp;
}
}
cout<<"位置"<<a<<"和位置"<<b<<"对应的"<<r[a]<<"和"<<r[b]<<"差值最小"<<endl;
}
算法分析:
算法由两层嵌套的循环组成,内层循环的执行次数取决于每一趟待排序区间的长度,也就是待排序记录个数,外层循环的终止条件是在一趟排序过程中没有交换记录的操作,是否有交换记录的操作取决于相邻两个元素的比较结果,也就是说,没执行一次for循环,都要执行一次比较操作,而交换九路的操作却不一定执行。输入规模是待排序的记录的个数n,基本语句是比较操作(r[j]>r[j+1])。
运行结果:
注意:c++语言数组下标从0开始。
a.数组中元素互不相同的情况:
b.数组中有相同元素的情况: