排序的算法有很多,例如直接插入排序,希尔排序,冒泡排序,选择排序,快速排序,堆排序等等。最简单基础就是冒泡排序了,关于排序hi有一个系列。今天是第一篇,主要讲冒泡排序算法思想以及从各个方面对它进行优化。
冒泡排序:
原理举例:设数组长度为N。
1.比较相邻的前后二个数据,如果前面数据大于后面的数据,就将二个数据交换。
2.这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个数据就“沉”到数组第N-1个位置。
3.N=N-1,如果N不为0就重复前面二步,否则排序完成。如下图所示:
下面来用代码实现上图所示的算法:
void BubbleSort(int *a,size_t size)
{
int i = 0;
int j = 0;
int tmp = 0;
assert(a);
for (i = 0; i < size - 1; i++)//一共需要排序size-1次
{
for (j = 0; j < size - i - 1; j++)//选出这一趟排序的最大值往后沉
{
if (a[j]>a[j + 1])
{
tmp = a[j];
a[j] = a[j + 1];
a[j + 1] = tmp;
}
}
}
}
这样的方法虽然可以做到给排序,但是效率很低,如果只排了两次就有序了,但程序还是会老老实实的把size-1次循环都走完,所以可以对这样的程序进行优化,设置一个标志位,将它置为0,每次循环中,如果程序发生了交换,就将标志位置为1,在每次循环中让if条件做一个判断,如果标志位为0就说明数据没有发生交换,证明它已经有序了,就可以将程序退出循环
代码实现是这样的
void BubbleSort(int *a,size_t size)
{
int i = 0;
int j = 0;
int tmp = 0;
int flag = 0;//设置标志位
assert(a);
for (i = 0; i < size - 1; i++)
{
flag = 0;//在循环内部将标志位置为0
for (j = 0; j < size - i - 1; j++)
{
if (a[j]>a[j + 1])
{
tmp = a[j];
a[j] = a[j + 1];
a[j + 1] = tmp;
flag = 1;//如果发生了交换,就将flag置为1
}
}
if (flag == 0)//判断标志位是否为0,如果为0,就直接return
{
return;
}
}
}
这样写就能比第一次实现的高效很多,但是还有优化的余地,如果发生了交换,记住每次每趟排序中最后一次交换的位置,下次比较到最后一次交换的位置就可以了,
代码实现:
void BubbleSort(int *a, size_t size)
{
int i = 0;
int j = 0;
int tmp = 0;
int flag = 0;
int pos = 0;//pos变量用来标记循环里最后一次交换的位置
int k = size-1;
assert(a);
for (i = 0; i < size - 1; i++)
{
flag = 0;
for (j = 0; j < k; j++)
{
if (a[j]>a[j + 1])
{
tmp = a[j];
a[j] = a[j + 1];
a[j + 1] = tmp;
pos = j;
flag = 1;
}
}
k = pos;
if (flag == 0)
{
return;
}
}
}
好了,写到这里冒泡排序就写完了,欢迎大家前来纠错指导,一起学习哦!!