冒泡排序算法:
冒泡排序。就是它进行两个两个的比较如果发生了逆序,就进行交换。这里以大的数字放在最右边,小的在最左边先看一组数字:3,10,5,16,9,12,7,冒泡排序进行就是相邻的元素两两比较。
比较结果:
第一次 3,5,10,9,12, 7, 16
第二次 3,5,9,10,7, 12 ,16
第三次 3,5,9,7,10 ,12 ,16
第四次 3,5,7,9,10, 12, 16
从这里我们就可以看出端倪,在整个的排序过程中,相邻两个进行比较的时候我们要使用一次内部循环,在进行排序操作的时候我们还需要进行一次外部循环,才可以最后得出结果。
源代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void swap(int arr_01[],int n);
void fuzhi(int arr_03[],int n);
int main()
{
int i;
int arr[10]={0};
fuzhi(arr,10);
for(i=0;i<10;i++)
{
printf("排序前(随机产生):arr[%d]=%d \n",i,arr[i]);
}
swap(arr,10);
printf("\n");
for(i=0;i<10;i++)
{
printf("排序后(升序排列):arr[%d]=%d \n",i,arr[i]);
}
return 0;
}
void fuzhi(int arr_03[],int n)
{
int i;
srand(time(0));
for(i=0;i<n;i++)
{
arr_03[i]=rand()%99+1;
}
}
void swap(int arr_01[],int n)
{
int i,j,temp;
for(i=0;i<n-1;i++)//比较的轮数
{
for(j=0;j<n-1;j++)//每进行一轮比较,前一个小的元素和后一个较大的元素交换一下位置
{
if(arr_01[j]>arr_01[j+1])
{
temp=arr_01[j];
arr_01[j]=arr_01[j+1];
arr_01[j+1]=temp;
}
}
}
}
运行结果:
核心的算法就是利用了两次for循环:
for(i=0;i<n-1;i++)//比较的轮数
{
for(j=0;j<n-1;j++)//每进行一轮比较,前一个小的元素和后一个较大的元素交换一下位置
{
if(arr_01[j]>arr_01[j+1])
{
temp=arr_01[j];
arr_01[j]=arr_01[j+1];
arr_01[j+1]=temp;
}
}
}
起初我一直不太理解为啥要用到两次循环,这里借用一位博主的巧妙比喻,理解之后,便豁然开朗。
首先:嵌套是这么理解的。比如你有10棵树,每天都去检查是否生虫子了,连续检查一个月(30天)
用代码表示这个循环就是这样:
for(j=1;j<=30;j++)
{
for(i=1;i<=10;i++)
{
print("今天是第%d天, 正在检查第%d棵树",j,i);
}
}
外层循环用户控制天,内层循环用于控制树,缺一不可,第一天检查十遍,第二天检查十遍,...
也就是j=1的时候内层循环执行一遍,j=2的时候内层循环执行一遍...
对于冒泡排序,可以这样考虑:
外层循环式控制一共有多少个泡需要排序, 这个当然要用循环,内层循环控制把某一个泡放到正确的位置, 这个也要用循环, 因为这个泡要和所有未排序泡比较一遍, 然后才能知道自己应该处的位置
这里有两个点,明白了的话,这道题就明白了。
1. 外层循环: 仅仅控制一共有多少个泡需要排序, 比如代码中a[10], 一共是10个元素
2. 内层循环: 仅仅控制把当前最大的泡放到最后, 也就是一次内层循环,仅仅把最大的那个泡放到最后了而已
把1和2综合起来看,当j=0时,把a数组10个元素中最大的泡放到最后,当j=1时,把a数组10个元素中第二大的元素放到倒数第二个位置,依次类推..直到第10大的元素,即最小的元素放到正数第一个位置,可以这样测试一下,会更加清晰,把第一个循环去掉, 内层循环改为:for(i=0; i< 10; i++) 相当于仅执行上述j=0的一次内层循环, 这个循环的作用是把最大的元素放到最后。
这是我把外层循环注释掉之后的结果,可以看到输出的结果只是把最大的“泡”放到了最后,其他位置没有更改。