您的位置:首页 > 编程语言 > C语言/C++

C语言实现冒泡排序与交换排序

2019-11-30 12:04 1716 查看

交换法排序

算法思想

将数组的第一个元素与后面的元素逐一进行比较,若遇到较小的元素,则交换它们的值,第一轮比较完成后数组的第一个元素即为数组中的最小值了,接下来再进行第二轮比较,将数组中的第二个元素与后面的元素进行比较获取剩余元素中的最小值,依次类推,完成第n-1轮比较之后,数组就完成从小到大排序了

时间复杂度

需进行(n(n-1))/2次比较判断(第一轮n-1次,第二轮n-2次.......第n-1轮1次,累加可得),时间复杂度为O(N^2)

代码实现

#include <stdio.h>
#include <stdlib.h>

int main()
{
int score[] = {1, 2, 3, 4, 5, 6, 7};
printf("before sort: ");
for(int i=0;i < 7;i++)
{
printf("%d ", score[i]);
}
ChangeSort(score, 7);
printf("\nafter sort: ");
for(int i=0;i < 7;i++)
{
printf("%d ", score[i]);
}
return 0;
}

void ChangeSort(int score[], int n)
{
int cycles=0, temp;
for(int i = 0;i < n;i++)
{
for(int j = i+1;j < n;j++)
{
cycles++;
if(score[i] > score[j])
{
temp = score[j];
score[j] = score[i];
score[i] = temp;
}
}
}
printf("\ncycles: %d", cycles);
}

选择法排序

算法思想

设一个变量值为第一个元素的下标值(即为0),将下标变量指向的元素值与之后的元素逐一进行比较,若遇到较小的元素,则将这个变量值改为较小元素的下标值,再继续用下标变量对应的新元素值与后面的元素进行比较,第一轮比较完成后该下标变量就指向了数组中的最小值,若下标变量值改变了(即不为0,最小值不是第一个元素),就将这个最小元素值与第一个元素值进行交换,完成第一轮循环比较。再开始第二轮,下标变量设为第二个元素的下标值(即为1),将下标变量指向的元素值与之后的元素逐一进行比较....重复上述过程选出剩余元素中最小值的下标,将第二个元素与该最小值交换。依此类推,第n-1轮循环后,就完成了选择排序

可以看出,选择法排序与交换法排序算法思想类似,都是在每一轮循环比较中寻找当前剩余元素最小值,只不过交换法通过直接交换元素值实现,而选择法是通过保存较小元素下标实现

时间复杂度

时间复杂度与交换排序法一样,都是O(N^2)。但是由于选择排序不需要频繁的交换元素值,只保存元素下标在每一轮比较结束后再进行一次元素值交换,因此空间复杂度更低

代码实现

#include <stdio.h>
#include <stdlib.h>

int main()
{
int score[] = {7, 2, 3, 4, 5, 6, 1};
printf("before sort: ");
for(int i = 0;i < 7;i++)
{
printf("%d ", score[i]);
}
SelectionSort(score, 7);
printf("\nafter sort: ");
for(int i = 0;i < 7;i++)
{
printf("%d ", score[i]);
}
return 0;
}

void SelectionSort(int score[], int n)
{
int cycles = 0, k, temp;
for(int i = 0;i < n;i++)
{
k = i;
for(int j = i+1;j < n;j++)
{
cycles++;
if(score[k] > score[j])
{
k = j;
}
}
if(k!=i)
{
temp = score[i];
score[i] = score[k];
score[k] = temp;
}
}
printf("\ncycles: %d", cycles);
}

冒泡法排序

算法思想

将数组中的第一个元素与第二个元素进行比较,若比较结果为大于,则交换它们的值,再进行第二个与第三个比较,大于则交换值....第n-1个与第n  个比较,大于则交换值,就如同向上冒泡一样,将最大值向上冒,这样完成一轮冒泡循环后,最右边的值即为最大值了。再将剩下的元素进行第二轮冒泡循环,以此类推,每一轮循环都向右冒出一个剩余元素中的最大值。当在某一轮循环中没有发生元素交换时,说明剩下的元素是从小到大排列的了,即完成了冒泡排序

时间复杂度

最好情况是数组为正序,第一轮循环中就无元素交换,需比较n-1次,时间复杂度为O(N)

最坏情况是数组为逆序,需进行到最后一轮(第n-1次)循环,共比较(n(n-1))/2次,时间复杂度为O(N^2)

因此可看出,从时间复杂度来讲,冒泡法排序是优于交换排序和选择排序的

代码实现

如下数组{1, 2, 3, 4, 5, 6, 7}即为正序,比较6次就完成了排序,而在上述交换法排序中需要比较(n(n-1))/2次即21次才能完成排序

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int main()
{
int score[] = {1, 2, 3, 4, 5, 6, 7};
printf("before sort: ");
for(int i=0;i < 7;i++)
{
printf("%d ", score[i]);
}
ChangeSort(score, 7);
printf("\nafter sort: ");
for(int i=0;i < 7;i++)
{
printf("%d ", score[i]);
}
return 0;
}

void ChangeSort(int score[], int n)
{
int cycles=0, temp;
for(int i = 0;i < n;i++)
{
for(int j = i+1;j < n;j++)
{
cycles++;
if(score[i] > score[j])
{
temp = score[j];
score[j] = score[i];
score[i] = temp;
}
}
}
printf("\ncycles: %d", cycles);
}

 

注:

  1. C99中没有特定的布尔类型,因此引入<stdbool.h>使用bool类型
  2. 将每次比较的符号由小于改为大于即可实现降序排序
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: