交换排序
基本思想:在一个待排序序列中,两两比较元素的排序码,如果不满足次序要求则进行交换,直到整个排序序列满足要求。
冒泡排序
思想:对待排序序列从前向后,依次比较相邻元素的排序码,若发生逆序,则进行交换。
实现:
#include <stdio.h>
void BubbleSort(int *p, int N)
{
int i, j;
int flag; //标志位,判断元素是否发生交换
int t; //交换时的中间变量
for(i = 0; i < N-1; i++) //需要几次排序
{
flag = 0;
for(j = 0; j < N-1-i; j++) //每次排序需要几次比较
{
if(p[j] > p[j+1]) //>--从小到大;<--从大到小
{
t = p[j];
p[j] = p[j+1];
p[j+1] = t;
flag = 1;
}
}
if(!flag) //减少不必要的比较
return;
}
}
int main()
{
int m, n;
//待排序序列
int a[7] = {49, 38, 65, 97, 76, 13, 27};
//输出待排序序列
printf("待排序序列:");
for(m = 0; m < 7; m++)
{
printf("%d ", a[m]);
}
printf("\n");
//冒泡排序
BubbleSort(a, 7);
//输出排序后的序列
printf("经过冒泡排序后的序列:");
for(n = 0; n < 7; n++)
{
printf("%d ", a[n]);
}
printf("\n");
return 0;
}
结果:
分析:
- 时间复杂度:O(n^2)
- 空间复杂度:O(1)
- 算法是否稳定:稳定
快速排序
思想:从待排序序列中选取一个基准元素(一般选取第一个元素),按照该元素排序码的大小,将待排序序列分为两个子序列,左边子序列元素的排序码都小于基准元素的排序码,右边子序列元素的排序码都大于或等于基准元素的排序码,找到基准元素的最终位置。之后在左右两个子序列中重复以上步骤,直到子序列中只有一个元素。(冒泡排序的改进)
实现:
#include <stdio.h>
int FindPivotLoc(int *q, int low2, int high2)
{
int pivot; //基准元素
pivot = q[low2];
while(low2 < high2)
{
while(low2<high2 && q[high2]>=pivot)
{
high2--;
}
q[low2] = q[high2]; //小于基准元素的元素放在左边
while(low2<high2 && q[low2]<=pivot)
{
low2++;
}
q[high2] = q[low2]; //大于基准元素的元素放在右边
}
q[low2] = pivot; //将基准元素放在最终的位置
return high2; //返回基准元素的最终位置,此时high2 = low2;
}
void QuickSort(int *p, int low1, int high1)
{
if(low1 < high1) //子序列中只有一个元素时不执行
{
int pivotloc; //基准元素的最终位置
pivotloc = FindPivotLoc(p, low1, high1); //确定基准元素的最终位置
QuickSort(p, low1, pivotloc-1); //左边子序列,递归思想
QuickSort(p, pivotloc+1, high1); //右边子序列
}
}
int main()
{
int m, n;
//待排序序列
int a[7] = {49, 38, 65, 97, 76, 13, 27};
//输出待排序序列
printf("待排序序列:");
for(m = 0; m < 7; m++)
{
printf("%d ", a[m]);
}
printf("\n");
//快速排序
QuickSort(a, 0, 6);
//输出排序后的序列
printf("经过快速排序后的序列:");
for(n = 0; n < 7; n++)
{
printf("%d ", a[n]);
}
printf("\n");
return 0;
}
结果:
分析:
- 时间复杂度:O(nlogn) (log以2为底)
- 空间复杂度:O(logn)~O(n)
- 算法是否稳定:不稳定