对于冒泡排序,大家肯定都熟知,每一轮的冒泡都将最大的数排到最前面,每一轮的时间复杂度是O(n),如果要排序的数组大小为n,要经过n轮才能将数组中所有元素排序,所以总共的时间复杂度为O(n2)。
迭代型冒泡排序
void BubbleSort(int *a, int len) //待排数组a以及它的长度len
{
int ordered = false;
int temp, i;
while(len && !ordered)
{
ordered = true; //也许一趟排序过程中没有发生交换,说明数组已有序
for(i = 1; i < len; i++) //此时i从1开始比从0开始更好
{
if(a[i-1] > a[i])
{
ordered = false;
temp = a[i];
a[i] = a[i-1];
a[i-1] = temp;
}
}
len--;
}
}
int main()
{
int a[5] = {5,1,2,3,4};
int i = 0;
int len = length(a);
BubbleSort(a,len);
for(i = 0; i < len; i++)
{
printf("%d ",a[i]);
}
return 0;
}
----------------------------------------------------------------
对 于快速排序,选出一个枢纽元素,然后将这个枢纽元素和数组所有元素进行比较,把彼枢纽元素大的元素放在枢纽元素右边,把比枢纽元素小的放在枢纽元素左边, 而对于一趟快速排序要比较n次,每一趟快排的时间复杂度是O(n),接下来你要对快排划分出来的两个子数组进行递归快排,如果每一趟快排很平均的将数组划分为两个子数组,那么递归快排的深度就是O(lgn),所以总的时间复杂度就是O(nlgn)。但是快排可以退化成冒泡,如果一旦每一趟快排,不幸的选择出最大或最小元素作为枢纽元素,那么递归深度将变成n,则时间复杂度变成了O(n2),此时快排的效率降到最低,退化为冒泡,所以快排对于枢纽元素的选择上很关键,如果能选择出每趟平均划分数组的枢纽元素,那么快排的效率最高,如何选择枢纽元素将成为衡量快排的关键,我推荐使用三者取中法来选择,每趟快排前,先将数组开始位置,中间位置,以及结尾位置的三个元素进行比较,选择其中的中间大的数做为枢纽元素,这样可以降低退化成冒泡的风险,也可以使用任取一个数做为枢纽元素,这样也可以降低风险。
----------------------------------------------------------------
递归型的冒泡排序和递归型的快速排序,你会发现两者的区别,以及为什么快排会比冒泡好的原因,以及如何将程序从冒泡写成快排。
递归型冒泡排序
int Sort(int *a, int len)
{
int ordered = true; //也许一趟排序过程中没有发生交换,说明数组已有序
int temp, i;
for(i = 1; i < len; i++) //由此可以看出Sort()的时间复杂度是O(n),跟待排数组的长度有关。
{
if(a[i-1] > a[i])
{
ordered = false;
temp = a[i];
a[i] = a[i-1];
a[i-1] = temp;
}
}
return ordered;
}
void BubbleSort(int *a, int len) //冒泡排序的递归算法
{
if(len == 1) //如果只有一个元素,它就是最大的元素,无须在冒泡
return;
else
{
int ordered = Sort(a,len); //选出最大的元素,将所有比最大元素小的元素放在最大元素的左边,而快排是将使用一个枢纽元素,将比枢纽元素大的放在枢纽右边,小的放在左边
if(ordered) //如果一趟冒泡,没有交换元素,说明已有序
return;
BubbleSort(a,len-1); //递归冒泡出最大元素后面的所有元素,如果快排将作为快排的左递归
//如果快排会有右递归
}
}
int main()
{
int a[10] = {10,1,5,2,4,3,6,7,9,8};
int i = 0;
int len = length(a);
BubbleSort(a,len);
for(i = 0; i < len; i++)
{
printf("%d ",a[i]);
}
return 0;
}
----------------------------------------------------------------
递归快速排序
int Sort(int *a, int low, int high)
{
int pivot = a[low]; //这里每次的枢纽元素都取了待排数组的第一个元素,记住是a[low],而不是a[0]
if(low < high) //时间复杂度是O(n),n是数组长度
{
while(a[high] >= pivot && low < high)
high --;
a[low] = a[high];
while(a[low] <= pivot && low <high)
low ++;
a[high] = a[low];
}
a[low] = pivot;
return low;
}
void QuickSort(int *a, int low, int high)
{
if(low >= high)
return ;
else
{
int mid = Sort(a,low,high); //划分子递归数组
QuickSort(a,low,mid-1); //左递归
QuickSort(a,mid+1,high); //右递归,一旦右递归mid+1=high,将退化成冒泡,递归深度将变成n,n为数组长度
}
}
int main()
{
int a[5] = {3,1,5,2,4};
int i = 0;
int len = length(a);
QuickSort(a,0,len-1);
for(i = 0; i < len; i++)
{
printf("%d ",a[i]);
}
return 0;
}
递归型的冒泡就是一个只有右子树的递归树,递归深度为O(n),而好的快速排序,将产生一个平衡的二叉树,递归深度为O(lgn),所以快排是对冒泡的一个巨大的改进。
相关推荐
随机生成10000数字,进行插入,快速,冒泡,选择排序比较,并输出耗时
冒泡排序和快速排序的时间性能比较 冒泡排序和快速排序是两种常见的排序算法,它们在排序过程中的时间性能有很大的差异。在本文中,我们将比较冒泡排序和快速排序的时间性能,并讨论它们在实际应用中的优缺点。 ...
在本文中,我们将对冒泡排序和快速排序的时间性能进行深入分析和比较。 冒泡排序是一种简单的排序算法,它的时间复杂度为O(n^2),其中n是要排序的元素个数。冒泡排序的基本思想是通过不断地比较和交换相邻元素来...
对于冒泡排序和快速排序的比较次数与移动次数进行比较
本文将深入探讨四种在C++中实现的常见排序算法:插入排序、冒泡排序、堆排序和快速排序。这些算法各有特点,适用于不同的场景,理解并掌握它们对于提升编程能力至关重要。 1. **插入排序**: 插入排序是一种简单的...
快速排序和冒泡排序是两种常见的排序算法,它们在计算机科学中扮演着重要的角色,特别是在数据处理和优化程序性能方面。本篇文章将深入探讨这两种排序算法的原理、效率以及它们在C#编程语言中的实现。 首先,让我们...
选择排序、插入排序、冒泡排序以及快速排序和归并排序的C语言实现,绝对可用
直接插入排序、冒泡排序、快速排序、直接选择排序、堆排序和二路归并排序是计算机科学中经典的排序算法,它们在数据处理和算法学习中占有重要地位。这些排序算法各有特点,适用场景不同,下面将逐一详细介绍,并结合...
输入同样一组数据,比较直接插入排序、冒泡排序、快速排序这三种排序算法的关键字的比较次数和数据移动次数。
数据结构(c语言版)严蔚敏 吴伟民编著 中直接插入排序、折半排序、shell排序、冒泡排序、快速排序、选择排序、堆排序的实现、归并排序,使用c语言实现
直接插入排序 选择排序 堆排序 归并排序 快速排序 冒泡排序等七种排序方法
本文将详细讲解六种经典的排序算法——合并排序、插入排序、希尔排序、快速排序、冒泡排序以及桶排序,并结合提供的文件名(sort.c、set.c、main.c、set.h、sort.h)推测出每个文件可能包含的代码实现。 1. **合并...
例如,如果某组数据导致快速排序的比较次数和移动次数大幅增加,可能是因为输入序列已经部分排序,此时冒泡排序可能会相对更稳定。优化快速排序,例如采用三向切分,可以减少这种情况下不必要的交换,从而提高效率。...
本节将深入探讨两种常见的排序算法:冒泡排序和快速排序。 首先,我们来详细讲解冒泡排序。冒泡排序是一种简单直观的排序算法,它的基本思想是通过重复遍历待排序的数列,依次比较相邻元素并交换位置,使得较大的...
C语言数据结构课程设计实例二叉树建立遍历冒泡排序快速排序等 C语言数据结构课程设计实例二叉树建立遍历冒泡排序快速排序等 C语言数据结构课程设计实例二叉树建立遍历冒泡排序快速排序等 C语言数据结构课程设计实例...
10个数据结构课程设计实例二叉树建立遍历冒泡排序快速排序等10个数据结构课程设计实例二叉树建立遍历冒泡排序快速排序等10个数据结构课程设计实例二叉树建立遍历冒泡排序快速排序等 10个数据结构课程设计实例二叉树...
printf("\t3: 快速排序\n"); printf("\t4: 直接选择排序\n"); printf("\t5: 堆排序\n"); printf("\t6: 归并排序\n"); printf("\t7: 希尔排序\n"); printf("\t***************************\n"); scanf("%d",&i...
基于c语言10个数据结构课程设计实例二叉树建立遍历冒泡排序快速排序等 基于c语言10个数据结构课程设计实例二叉树建立遍历冒泡排序快速排序等 基于c语言10个数据结构课程设计实例二叉树建立遍历冒泡排序快速排序等 ...
在分析和比较这两种排序算法时,我们关注的指标可能包括:运行时间、内存占用、稳定性(冒泡排序是稳定的,即相等的元素保持原有顺序,而快速排序不是)、以及算法的可读性和可维护性。此外,测试集还可以用于对比...