目录
冒泡排序
思想:反复扫描待排序列,不断将相邻的记录两两比较,当遇到前后逆序的情况下则交换记录,每躺排序可以确定一个最大的记录在最后,至多需要进行n-1躺排序。如果某躺排序未发生交换代表已经有序,停止排序即可。冒泡排序在记录逆序时才交换,保证稳定性。
void BubbleSort(int arr[],int length){//冒泡排序
int CHANGE=1;//改变标志位
for(int i=1;CHANGE && i<length;i++){//对待排序列进行冒泡排序最多length-1躺
CHANGE=0;
for(int j=1;j<=length-i;j++){//逆序则交换
if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
CHANGE=1;
}
}
printf("第%d次冒泡排序的结果为:\n",i);
PrintArr(arr,length);
}
}
时间复杂度:最好情况是待排记录已经从小到大顺序排列,仅仅进行一趟排序比较n-1次即可,不发生移动,最坏情况是待排序记录从大到小逆序排列,第i躺排序对比n-i次,移动3(n-i)次,总比较n-1+n-2+....+1=n(n-1)/2,总移动3n(n-1)/2,平均时间复杂度为T(n)=O(n^2)
快速排序
思想:设置记录基准,从low->high对待排记录进行排序,经过一趟排序后基准将待排序列划分为两个子表,左部子表所有的记录均小于该基准,右部子表的记录均大于该基准,再对左部子表和右部子表进行排序。快速排序不稳定,例如:2,1,1
int QuickPass(int arr[],int low,int high){//对待排记录从low->high进行快速排序,返回基准位置
static int nums=1;//记录执行次数
int x=arr[low];//设置基准
while(low<high){
while(low<high && arr[high]>=x){//从high处开始,大于等于基准时指针向前移动
high--;
}
if(low<high){//小于基准时移动记录
arr[low]=arr[high];
low++;
}
while(low<high && arr[low]<x){//再从low处开始,小于基准时指针向后移动
low++;
}
if(low<high){//大于等于基准时移动记录
arr[high]=arr[low];
high--;
}
}
arr[low]=x;
printf("第%d次快速排序的结果为:\n",nums);
PrintArr(arr,length);
nums++;
return low;//返回基准经过排序后位置
}
void QuickSort(int arr[],int low,int high){
if(low<high){
int pos=QuickPass(arr,low,high);
QuickSort(arr,low,pos-1);
QuickSort(arr,pos+1,high);
}
}
时间复杂度:快速排序的时间复杂度与递归的深度有关,在最好情况下,每一趟快速排序基准都正好将整个待排序列分为两个子表,基准在正中间,每趟的时间复杂度都不大于O(n),此时的递归深度为log2n+1,时间复杂度为T(n)=O(nlog2n)。最坏情况则是原本待排序列已经基本有序,在经过一趟快排后左部子表长度为0,右部子表为除基准外的n-1个记录,再不断对右部子表进行快速排序,此时的时间复杂度会退化为T(n)=O(n^2),平均的时间复杂度为T(n)=O(nlog2n)。
完整代码
#include<stdio.h>
void BubbleSort(int*,int);//冒泡排序
int QuickPass(int*,int,int);//一趟快排
void QuickSort(int*,int,int);//完整快排
void PrintArr(int*,int);//输出记录
int length;//全局变量记录数组长度
void BubbleSort(int arr[],int length){//冒泡排序
int CHANGE=1;//改变标志位
for(int i=1;CHANGE && i<length;i++){//对待排序列进行冒泡排序最多length-1躺
CHANGE=0;
for(int j=1;j<=length-i;j++){//逆序则交换
if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
CHANGE=1;
}
}
printf("第%d次冒泡排序的结果为:\n",i);
PrintArr(arr,length);
}
}
int QuickPass(int arr[],int low,int high){//对待排记录从low->high进行快速排序,返回基准位置
static int nums=1;//记录执行次数
int x=arr[low];//设置基准
while(low<high){
while(low<high && arr[high]>=x){//从high处开始,大于等于基准时指针向前移动
high--;
}
if(low<high){//小于基准时移动记录
arr[low]=arr[high];
low++;
}
while(low<high && arr[low]<x){//再从low处开始,小于基准时指针向后移动
low++;
}
if(low<high){//大于等于基准时移动记录
arr[high]=arr[low];
high--;
}
}
arr[low]=x;
printf("第%d次快速排序的结果为:\n",nums);
PrintArr(arr,length);
nums++;
return low;//返回基准经过排序后位置
}
void QuickSort(int arr[],int low,int high){
if(low<high){
int pos=QuickPass(arr,low,high);
QuickSort(arr,low,pos-1);
QuickSort(arr,pos+1,high);
}
}
void PrintArr(int arr[],int length){//输出记录序列
for(int i=1;i<=length;i++){
printf("%d ",arr[i]);
}
printf("\n");
}
int main(){
int arr[]={00,55,88,66,33,99,44,77,11,22};
length=sizeof(arr)/sizeof(arr[0])-1;
printf("排序前为:\n");
PrintArr(arr,length);
// BubbleSort(arr,length);//冒泡排序
QuickSort(arr,1,length);//快速排序
printf("排序后为:\n");
PrintArr(arr,length);
return 0;
}