不得不说,算法这个东西还是挺让人头疼的。。昨天中午忽然脑袋短路,一时竟想不起以前看过的冒泡算法的原理,看来还是没有理解透,中午躺床上睡不着了。。。。
于是,先把他想明白了再休息吧。。。。
冒泡算法1:
# include <iostream>
# include <ctime>
# define SIZE 11
using namespace std;
void bubble_sort(int a[], int n);
void bubble_sort(int a[], int n)
{
int i=0, j=0, temp=0;
for (j = 0; j < n; j++)
{
for (i = j+1; i < n; i++)
{
if(a[j] > a[i])
{
temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
}
int main()
{
int number[SIZE];
srand(time(0));
for(int m=0;m<SIZE;m++)
{
number[m] = (rand()%100);
}
int num=0;
bubble_sort(number, SIZE);
for (num = 0; num < SIZE; num++)
{
cout<<number[num]<<" ";
}
}
这是我实现的最笨拙的冒泡算法,按《大话数据结构》书上来说,这不算是正宗的冒泡算法。。
他的原理很简单,第一层循环用来确定当前最小数的存放位置,这里为依次从前往后,第二层循环用来比较出当前的最小值。
冒泡算法2.
这个算法也是我刚开始犯迷糊的地方,其实如果想不明白只要在纸上自己写一个序列,然后把这个程序循环自己走完就能明白他的原理。
# include <iostream>
# include <ctime>
# define SIZE 11
using namespace std;
void bubble_sort(int a[], int n);
//void bubble_sort(int a[], int n)
//{
// int i=0, j=0, temp=0;
// for (j = 0; j < n; j++)
// {
// for (i = j+1; i < n; i++)
// {
// if(a[j] > a[i])
// {
// temp = a[j];
// a[j] = a[i];
// a[i] = temp;
// }
// }
// }
//}
void bubble_sort(int a[],int n)
{
int i=0, j=0, temp=0;
for (j = 0; j < n-1; j++)
{
for (i = 0; i < n-j-1; i++)
{
if(a[i] > a[i+1])
{
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
}
}
int main()
{
int number[SIZE];
srand(time(0));
for(int m=0;m<SIZE;m++)
{
number[m] = (rand()%100);
}
int num=0;
bubble_sort(number, SIZE);
for (num = 0; num < SIZE; num++)
{
cout<<number[num]<<" ";
}
}
这是正宗冒泡排序的一种形式,第一层循环(j=0)过后,最大的数落在了最后,较小的数相应的都会有所提前,第一层循环(j=1)过后,次大的数落在倒数第二位,较小的数相应会有所提前,如此循环………….完成从小到大的排列。
这种形式还有另外一种变形,代码如下:
# include <iostream>
# include <ctime>
# define SIZE 11
using namespace std;
void bubble_sort(int a[], int n);
//void bubble_sort(int a[], int n)
//{
// int i=0, j=0, temp=0;
// for (j = 0; j < n; j++)
// {
// for (i = j+1; i < n; i++)
// {
// if(a[j] > a[i])
// {
// temp = a[j];
// a[j] = a[i];
// a[i] = temp;
// }
// }
// }
//}
//void bubble_sort(int a[],int n)
//{
// int i=0, j=0, temp=0;
// for (j = 0; j < n-1; j++)
// {
// for (i = 0; i < n-j-1; i++)
// {
// if(a[i] > a[i+1])
// {
// temp = a[i];
// a[i] = a[i+1];
// a[i+1] = temp;
// }
// }
// }
//}
void bubble_sort(int a[],int n)
{
int i, j, temp,flag=0;
for (j = 0; j < n; j++)
{
for (i = n-2; i >= j; i--)
{
cout<<flag++<<endl;
if(a[i] > a[i+1])
{
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
}
}
int main()
{
int number[SIZE];
srand(time(0));
for(int m=0;m<SIZE;m++)
{
number[m] = (rand()%100);
}
int num=0;
bubble_sort(number, SIZE);
for (num = 0; num < SIZE; num++)
{
cout<<number[num]<<" ";
}
}
这种形式跟上一个原理一样,只不过这种做法是较小的数字会慢慢如同气泡一样浮到前面,此算法命名为冒泡的由来。
3.冒泡排序的优化
参考大话数据结构优化方法:
如果待排序的序列为{2,1,3,4,5,6,7,8,9,10,11},我们会发现,除了第一个数和第二个数需要交换外,其余的并不需要交换,然而算法依然两两比较,做了好多无用功。
改进一下代码,增加一个标记变量flag来实现算法的改进,即当两两比较发现所有相邻的元素都是大小有序(即相邻两元素不再需要交换位置),则停止后面的比较,即认为此时序列已经完成排序。
代码如下:
# include <iostream>
//# include <ctime>
# define SIZE 11
using namespace std;
void bubble_sort(int a[], int n);
//void bubble_sort(int a[], int n)
//{
// int i=0, j=0, temp=0;
// for (j = 0; j < n; j++)
// {
// for (i = j+1; i < n; i++)
// {
// if(a[j] > a[i])
// {
// temp = a[j];
// a[j] = a[i];
// a[i] = temp;
// }
// }
// }
//}
//void bubble_sort(int a[],int n)
//{
// int i=0, j=0, temp=0;
// for (j = 0; j < n-1; j++)
// {
// for (i = 0; i < n-j-1; i++)
// {
// if(a[i] > a[i+1])
// {
// temp = a[i];
// a[i] = a[i+1];
// a[i+1] = temp;
// }
// }
// }
//}
void bubble_sort(int a[],int n)
{
int i, j, temp,count=0;
bool flag = true;
for (j = 0; j < n && flag; j++)
{
flag = false;
count++;//增加计数变量,用于查看循环进行次数
for (i = n-2; i >= j; i--)
{
if(a[i] > a[i+1])
{
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
flag = true;
}
}
}
cout<<count<<endl;
}
int main()
{
int number[SIZE] = {1,2,3,4,5,6,7,9,11,8,10};
//srand(time(0));
//for(int m=0;m<SIZE;m++)
//{
// number[m] = (rand()%100);
//}
int num;
bubble_sort(number, SIZE);
for (num = 0; num < SIZE; num++)
{
cout<<number[num]<<" ";
}
}
我们增加count变量用于查看循环进行了多少次,如果序列是{1,2,3,4,5,6,7,9,11,8,10},则第一次循环,序列变为{1,2,3,4,5,6,7,8,9,11,10},第二次循环,序列变为{1,2,3,4,5,6,7,8,9,10,11},第三次循环,序列没有作数据交换(此时序列已经有序),所以标志变量flag = false;下面的循环不再进行,即count = 3;
分析与运行结果一致。。