《啊哈!算法》学习笔记(一)——排序
开头
后续的几篇博客是对看完《啊哈算法》后的一个复习整理,书中对各类算法有一个思想和基本代码框架的介绍,对于算法们进一步的应用,相关的题目没有涉及。博客内容比较浅显。后续深入学习的,另会涉及题目
简易桶排序
#include <stdio.h>
int main()
{
int a[1000] = {0};
int t, i, j;
int n;
scanf("%d", &n); //输入有多少个数需要排序
for (i = 0; i < n; i++)
{
scanf("%d", &t);
a[t]++;
}
for (i = 0; i < 1000; i++)
for (j = 0; j < a[i]; j++)
printf("%d ", i);
return;
}
巧妙之处:存储数的不是数组元素的值,而是数组元素的角标,元素的值用来记录该数出现了几次。
不足之处:如果需要排序的数非常大,那空间复杂度就很差,容易溢出;另外,因为是遍历整个数组,所以有很多无效遍历;最严重的是,如果需要排序的数为浮点数或者负数,上述排序就不适用了。
易错之处:如果说数的范围都在0~1000,设1000为m,一共有n个数要排序。那么它的时间复杂度不是O(nm),而是O(n+m),并不是每一次外循环都会完全遍历n次内循环,内部只遍历n次。
真正的桶排序并没有这么简单,它就能处理元素为浮点数的情况,此处不提。
冒泡排序_bubblesort
#include <stdio.h>
int Swap(int *e1, int *e2)
{
int temp = *e1;
*e1 = *e2;
*e2 = temp;
}
int main()
{
int a[1000] = {0};
int n, i, j;
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
for (i = 0; i < n - 1; i++)//只用排n-1次,最后只剩下未归位的角标为0的第一个元素,已经排好。
for (j = 0; j < n - 1 - i; j++)//别少-i,因为从后往前数共i个元素都是排好序的,不用遍历
{
if (a[j] > a[j + 1])
Swap(&a[j], &a[j + 1]);
}
for (i = 0; i < n; i++)
printf("%d ", a[i]);
return 0;
}
特征:双重for循环遍历,初学较为常见,时间复杂度为O(N^2),因为是用数组元素的值来存储数值,所以可以对浮点型数据排序。
缺点:时间复杂度太高,大部分题目会超时。
描述:Donald E. Knuth&