#每日美图分享#

假设有一个整型数组:arr[]={9,8,7,6,5,4,3,2,1,0};现在需要通过编写程序来把它转换为升序,这时我们就可以考虑用冒泡排序来解决。
先让下标为零的与下标为一的比较大小,如果arr[0]>arr[1],则互相两值交换,此时原先下标为零的数下标变为一,下标为一的数下标变为零;然后下标为一的再和下标为二的进行比较,以此循环···,直到最大的数排在最后。
此时仅仅只是完成了一趟,接着要把第二大的数进行类似上述的操作,使其排在倒数第二位···
···
一直到最小的排在最前的话,需要进行九趟类似操作,其中第一趟需要比较九次,第二趟需要比较八次···,依次递减,直到完成排序。
上述操作可通过两次for循环来实现:
#include
void bubble_sort(int *n)
{
int i;
int sz = sizeof(n) / sizeof(n[0]);
for (i = 0; i < 10; i++)
{
int j;
for(j=0;j<sz-1-i;j++)
{
if (n[j] > n[j + 1])
{
int tmp = n[j];
n[j] = n[j + 1];
n[j + 1] = tmp;
}
}
}
}
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr);
int a = 0;
for (; a < 10; a++)
{
printf("%d ", arr[a]);
}
return 0;
}

可以看到这个程序并没有实现升序排序,因为数组在传参的过程中,传过去的只是数组第一个元素的地址,此时其实质就相当于一个指针,则可知
sz=4/4=1(此时电脑为32位),而我们所预期的sz应为10,这也就是出错的主要原因。
当电脑为64位时(sz=8/4=2):

改正方法如下,通过把sz=10传过去来避免出错。
#include
void bubble_sort(int* n,int sz)
{
int i;
for (i = 0; i < 10; i++)
{
int j;
for(j=0;j<sz-1-i;j++)
{
if (n[j] > n[j + 1])
{
int tmp = n[j];
n[j] = n[j + 1];
n[j + 1] = tmp;
}
}
}
}
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz);
int a = 0;
for (; a < 10; a++)
{
printf("%d ", arr[a]);
}
return 0;
}
运行结果如下:

现在可以看到,升序已经基本完成了。
但这个代码其实是还可以优化的,想一下,如果arr[]={0,1,2,3,4,5,6,7,8,9};
的话其实是不用进行排序的,但如果这个数组在我们的代码中的话,还是会呆呆的一个一个进行比较,即使这个数组已经是升序的了。基于上述,我们可以给每一趟比较完后加一个判断:如果数组已经是升序,那就不用在执行循环,直接结束bubble_sort()函数。但该怎么实现呢?
如果是一个升序数组的话,那么arr[j]恒成立的话则就说明该数组已经为升序。
则优化方案如下:
#include
void bubble_sort(int* n,int sz)
{
int i;
for (i = 0; i < 10; i++)
{
int j;
int flag = 1; //加了一个flag
for(j=0;j<sz-1-i;j++)
{
if (n[j] > n[j + 1])
{
int tmp = n[j];
n[j] = n[j + 1];
n[j + 1] = tmp;
flag = 0;
}
}
if (flag == 1) //如果flag==0的话则说明if()执行了,也即说明还未升序
break; /
}
}
int main()
{
int arr[] = { 8,9,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz);
int a = 0;
for (; a < 10; a++)
{
printf("%d ", arr[a]);
}
return 0;
}
由于作者水平有限,如有不对欢迎指正。