交换排序的主要思想是:在待排序序列中选择两个记录,将他们的关键码进行比较,如果反序则交换他们的位置。
起泡排序的思想是:
两两比较相邻记录的关键码,如果反序则交换,直到没有反序的记录为止。
起泡排序的问题是:
1.在一趟起泡排序中,若有多个记录位于最终的位置,应如何记载?
2.如何确定起泡排序的范围,使得已经位于最终位置的记录不参与下一趟排序?
3.如何判别起泡排序的结束。
排序的过程:
1.将整个待排序的记录序列划分成有序区和无序区,初始时有序区为空,无序区包括所有待排序的记录;
2.对无序区从前向后依次将相邻记录的关键码进行比较,如果反序则交换,从而使得关键码小的记录向前移动,关键码大的记录向后移动(像水中的气泡,体积大的先浮上来)
3.重复执行2,直到无序区中没有反序的记录。
问题1的解决:
如果在某趟气泡排序中位于最终位置的关键码的个数大于1,那么在下一趟气泡排序中这些关键码应该避免重复比较,为此,设置exchange记载每次记录交换的位置,则一趟排序后,exchange记载的一定是这趟排序中记录的最后一次交换的位置,从此位置之后的所有记录均有序了。
for(r[j]>r[j+1])
{
r[j]<--->r[j+1];
exchange = j;
}
问题2的解决:
设bound位置的记录是无序区的最后一个记录,则每趟气泡排序的范围是:r[1]~r[bound]
<pre name="code" class="java"><pre name="code" class="java">
for(j=1;j<bound;j++)
{
for(r[j]>r[j+1])
{
r[j]<--->r[j+1];
exchange = j;
}
}
bound=exchange
问题3的解决:
判断气泡排序的结束条件是在一趟排序过程中没有进行交换记录的操作。为此,在每趟气泡排序开始之前,设exchange的初值为0,在该趟排序的过程中,只要有记录的交换,exchange的值就会大于0,这样,在一趟比较完毕,就可以通过exchange的值是否为0来判断是否还有记录的交换,从而判断排序是否结束。
算法如下:
while(exchange!=0)
{
bound = exchange;
exchange = 0;
for(j=1;j<bound;j++)
{
for(r[j]>r[j+1])
{
r[j]<--->r[j+1];
exchange = j;
}
}
}
#include <iostream>
#include <cstdlib>
using namespace std;
void swap(int *number1, int *number2)
{
int temp = *number1;
*number1 = *number2;
*number2 = temp;
}
void BubbleSort(int *array, int len)
{
//开始是最后一个记录的交换位置为数组长度
int exchange = len-1;
while (exchange != 0)
{
int i, j, bound;
bound = exchange;
exchange = 0;
for (j = 0; j < bound;j++)
{
if (array[j]>array[j+1])
{
swap(array[j], array[j + 1]);
exchange = j;
}
}
}
}
void show(int *array, int len)
{
for (int i = 0; i < len; i++)
{
cout << array[i] << " ";
}
cout << endl;
}
void main()
{
int array[] = { 7, 6, 5, 4, 3, 2, 1, -1 };
int len = sizeof(array) / sizeof(array[0]);
BubbleSort(array, len);
show(array, len);
system("pause");
}