内容简介:本书介绍的第一个算法是利用本节以上面介绍的插入排序为例,展示如何分析算法的运行时间。用常数$c_i$表示计算机模型中基本操作所耗费的时间,推导出整个算法所需时间关于输入规模$n$的函数$T(n)$。算法分析一般只考察
本书介绍的第一个算法是 插入排序 算法。插入 排序 的工作机理和很多人打牌时,整理手中牌时的做法差不多。根据 排序算法 的伪代码,给出如下的 C语言 实现:
void sort(int nums[], int n)
{
for (int i = 1; i < n; i++) {
int key = num[i];
int j;
for (j = i - 1; key < num[j] && j >= 0; j--) {
num[j+1] = num[j];
}
num[j+1] = key;
}
}
利用 循环不变式 可以证明排序算法的正确性。
分析算法
本节以上面介绍的插入排序为例,展示如何分析算法的运行时间。用常数$c_i$表示计算机模型中基本操作所耗费的时间,推导出整个算法所需时间关于输入规模$n$的函数$T(n)$。算法分析一般只考察 最坏情况运行时间 ,这是算法运行时间的上界。
当$n$很大时,$T(n)$的低阶项相对来说不太重要,高阶项的常系数也不重要。忽略它们后,只剩下最重要项的因子。例如,对于插入排序,只剩下$n^2$。我们记插入排序的最坏情况时间代价为$\Theta(n^2)$。
算法设计
本节介绍一种常用设计策略,叫做 分治法 (divide and conquer)。 归并排序 算法遵循分治模式,直观上其操作如下:
- 分解:将$n$个元素分成各含$n/2$个元素的子序列
- 合并:合并两个已排序的子序列以得到排序结果
当待排序的序列长度为1时,递归“开始回升”,在这种情况下不做任何工作,因为长度为1的每个序列已排好序。
为完成算法,需要一个完成合并的辅助过程。由于两个子序列是已经排序好的,所以合并步骤的时间复杂度仅为$\Theta(n)$。它的代码如下:
void merge(int nums[], int aux[], int left, int mid, int right)
{
// 将原数组nums中的元素拷贝到预先分配的辅助数组aux中
for (int k = left; k <= right; k++) {
aux[k] = nums[k];
}
int i = left;
int j = mid + 1;
for (int k = left; k <= right; k++) {
if (i > mid) {
nums[k] = aux[j++];
} else if (j > right) {
nums[k] = aux[i++];
} else if (aux[j] < aux[i]) {
nums[k] = aux[j++];
} else {
nums[k] = aux[i++];
}
}
}
下面便是递归调用过程的代码, merge_sort
也是辅助过程, sort
是最终的接口函数:
void merge_sort(int nums[], int aux[], int left, int right)
{
if (left < right) {
int mid = left + (right - left)/2;
merge_sort(nums, aux, left, mid); // 递归排序左边
merge_sort(nums, aux, mid + 1, right); // 递归排序右边
merge(nums, aux, left, mid, right); // 合并已排序好的两个数组
}
}
void sort(int nums[], int n)
{
// 开辟动态内存,作为参数传入
int *aux = malloc(n * sizeof(int));
if (aux != NULL) {
merge_sort(nums, aux, 0, n - 1);
free(aux);
} else {
printf("Error: malloc() failed!\n");
}
}
当算法包含对其自身的递归调用时,要利用 递归方程 或 递归式 来描述其运行时间。对于上述的归并排序,算法分解成两个子问题加上一个合并过程,所以递归方程如下:
$$
T(n) =
\begin{cases}
c, & \mbox{若} n=1 \\
2T(n/2)+cn, & \mbox{若} n>1
\end{cases}
$$
根据上面的递归公式,可以计算出归并排序算法的时间复杂度为$\Theta(n \log n)$。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 算法导论阅读笔记 --- 排序算法
- 算法导论学习笔记5 随机算法
- 『算法导论』第 7 章:快速排序
- js实现多种排序算法(算法导论第二章)
- 『算法导论』第 8 章:线性时间排序
- 机器学习的算法和普通《算法导论》里的算法有什么本质上的异同?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
明解C语言(第3版)
[日] 柴田望洋 / 管杰、罗勇、杜晓静 / 人民邮电出版社 / 2015-11-1 / 79.00元
本书是日本的C语言经典教材,自出版以来不断重印、修订,被誉为“C语言圣经”。 本书图文并茂,示例丰富,第3版从190段代码和164幅图表增加至205段代码和220幅图表,对C语言的基础知识进行了彻底剖析,内容涉及数组、函数、指针、文件操作等。对于C语言语法以及一些难以理解的概念,均以精心绘制的示意图,清晰、通俗地进行讲解。原著在日本广受欢迎,始终位于网上书店C语言著作排行榜首位。一起来看看 《明解C语言(第3版)》 这本书的介绍吧!