冒泡排序是C语言中的较简单的一种排序算法。其算法思想如下:
1,首先比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2,对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
3,针对所有的元素重复以上的步骤,除了最后一个。
4,持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
下面以代码的方式实现:
第一种:数组方式实现:
#include<stdio.h>
void print(int arr[], int sz)
{
int i = 0;
for(i=0; i<sz; i++)
{
printf("%d ", arr[i]);
}
}
void swap(int arr[], int sz)
{
int i = 0;
int j = 0;
for(i=0; i<sz; i++)
{
for(j=0; j<sz-1-i; j++)
{
if(arr[j]<arr[j+1])
{
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int sz = sizeof(arr)/sizeof(arr[0]) ;
swap(arr, sz);
print(arr, sz);
return 0;
}
第二种:指针方式实现:
void bubble(int *arr, int sz)
{
int *start = arr;
int *end = arr+sz-1;
int *cur;
assert(arr != NULL);
while(start<end)
{
cur = start;
while(cur<end)
{
if(*cur <*cur+1)
{
int tmp = *cur;
*cur = *(cur+1);
*(cur+1) = tmp;
}
cur++;
}
end--;
}
}
void print(int arr[], int sz)
{
int i = 0;
for(i=0; i<sz; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int sz = sizeof(arr)/sizeof(arr[0]);
int left = 0;
int right = sz-1;
int i = 0 ;
bubble(arr, sz);
print(arr, sz);
return 0;
}
第一种方法固然可行,但存在一个问题。如果给定的数组本身就是从大到小排列的,那么这个程序依旧会执行不断执行,那么如何进行优化呢?
首先我们定义一个变量flag,将其赋初值为0。当发生交换时,可将flag的值变为1。在进行完一趟排序之后,如果flag的值并没有发生改变,那么说明该数组已经是由小到大排列好的,即不再向下执行。每一次排序完成后,进行判断,如果有序,直接跳出,具体实现如下:
void swap(int arr[], int sz)
{
int i = 0;
int j = 0;
int flag = 0;
for(i=0; i<sz; i++)
{
flag = 0;
for(j=0; j<sz-1-i; j++)
{
if(arr[j]<arr[j+1])
{
flag = 1;
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
if(flag == 0)
{
break;
}
}
}
还有一种优化方法就是减少内层循环,实现如下:
void swap(int arr[], int sz)
{
int i = 0;
int j = 0;
int k = sz-1;
int pos = 0;
for(i=0; i<sz-1; i++)
{
pos = 0;
for(j=0; j<k; j++)
{
if(arr[j]>arr[j+1])
{
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
pos = j;
}
}
k = pos;
}
}
欢迎各位指教,我的理解还不是很透彻