【数据结构与算法分析】复习笔记(1)
2014-03-17 20:14
162 查看
目前为止,PAT初级题目和题解已经全部发完了。 鼓掌!撒花!
初级题目几乎不需要用到复杂的数据结构,只需要基础的编程知识和简单的逻辑就可以完成。按姥姥的话说,“排序就是最复杂的了”(原话不记得了,不过是这个意思)。为了完成PAT的填坑大业,为了在9月份的PAT甲级比赛中不被题虐名列前茅并被优秀公司免试录取出任CEO迎娶白富美走上人生巅峰,果断开始走上备考甲级的不归之路!
甲级涉及的知识点比较多,要求的能力比较高,更需要一些稍微复杂一些的编程思想。参考biaobiaoqi前辈的文章,可以发现,涉及的数据结构有链表(List)、栈(Stack)、映射(Map)、树(Tree)、图(Graph)等,涉及的编程思想和算法有Hash、游标、倒排索引、排序、递归、搜索(广度优先、深度优先、二分搜索)、最短路径算法、并查集等。当时学DS和ADS的时候上课尽顾着睡觉了,所以现在不得不重新拿起尘封已久的《数据结构与算法分析(C语言版)》(Mark
Allen Weiss著 陈越姥姥改编),复习一下基本的东西,就把复习笔记发在这里好了,以便学完以后什么都不记得了。给出的示例代码有的是书上的代码,大部分是自己编写的测试代码,以便更深入理解。
第一章为“简介”,介绍了递归的基本概念。此处省略。
第二章“算法分析”,介绍算法的时间复杂度和空间复杂度的计算方法。作为例子书中介绍了四种常见的问题,分别是二分搜索、求最大公约数的欧几里得算法、最大子序列和问题、求幂问题。分别记录如下:
1. 二分搜索
二分搜索充分利用数组已经排过序的特性,将搜索的时间复杂度降为O(log2(n))。
【示例代码】
2. 求最大公约数的欧几里得算法
即辗转相除法。下面给出的示例是Gcd的一个应用,即求任意两数互质的概率。
【示例代码】
下面的代码给出了两种方法,一种时间复杂度为O(n),一种用了分治思想,时间复杂度为O(nlog2(n))。
【示例代码】
如果直接用循环求,时间复杂度为O(n),改用递归实现,复杂度降为O(nlog2(n))。
【示例代码】
To be continued...
初级题目几乎不需要用到复杂的数据结构,只需要基础的编程知识和简单的逻辑就可以完成。按姥姥的话说,“排序就是最复杂的了”(原话不记得了,不过是这个意思)。为了完成PAT的填坑大业,为了在9月份的PAT甲级比赛中不被题虐名列前茅并被优秀公司免试录取出任CEO迎娶白富美走上人生巅峰,果断开始走上备考甲级的不归之路!
甲级涉及的知识点比较多,要求的能力比较高,更需要一些稍微复杂一些的编程思想。参考biaobiaoqi前辈的文章,可以发现,涉及的数据结构有链表(List)、栈(Stack)、映射(Map)、树(Tree)、图(Graph)等,涉及的编程思想和算法有Hash、游标、倒排索引、排序、递归、搜索(广度优先、深度优先、二分搜索)、最短路径算法、并查集等。当时学DS和ADS的时候上课尽顾着睡觉了,所以现在不得不重新拿起尘封已久的《数据结构与算法分析(C语言版)》(Mark
Allen Weiss著 陈越姥姥改编),复习一下基本的东西,就把复习笔记发在这里好了,以便学完以后什么都不记得了。给出的示例代码有的是书上的代码,大部分是自己编写的测试代码,以便更深入理解。
第一章为“简介”,介绍了递归的基本概念。此处省略。
第二章“算法分析”,介绍算法的时间复杂度和空间复杂度的计算方法。作为例子书中介绍了四种常见的问题,分别是二分搜索、求最大公约数的欧几里得算法、最大子序列和问题、求幂问题。分别记录如下:
1. 二分搜索
二分搜索充分利用数组已经排过序的特性,将搜索的时间复杂度降为O(log2(n))。
【示例代码】
#include <iostream> using namespace std; int BinarySearch(const int A[], int x, int n) { int left = 0; int right = n - 1; while (left <= right){ int middle = (left + right) / 2; if (x < A[middle]){ right = middle -1; } else if (x > A[middle]){ left = middle + 1; } else{ return middle; } } return -1; } int main() { int n = 8; int A[] = {1, 5, 8, 9, 11, 13, 14, 18}; cout << BinarySearch(A, 11, n) << endl; cout << BinarySearch(A, 10, n) << endl; system("pause"); return 0; }
2. 求最大公约数的欧几里得算法
即辗转相除法。下面给出的示例是Gcd的一个应用,即求任意两数互质的概率。
【示例代码】
#include <iostream> using namespace std; unsigned int Gcd(unsigned int M, unsigned int N) { unsigned int Rem; while (N > 0){ Rem = M % N; M = N; N = Rem; } return M; } void PrimePair(unsigned int N) { int Rel = 0; int Tot = 0; for (int i = 1; i <= N; ++i){ for (int j = i + 1; j <= N; ++j){ ++Tot; if (Gcd(i, j) == 1){ ++Rel; } } } cout << "The probability that two random numbers are relatively prime is about:" cout << (double)Rel / Tot << endl; } int main() { cout << Gcd(1989, 1590) << endl; unsigned int N = 10000; PrimePair(N); system("pause"); return 0; }3. 最大子序列和问题
下面的代码给出了两种方法,一种时间复杂度为O(n),一种用了分治思想,时间复杂度为O(nlog2(n))。
【示例代码】
#include <iostream> /* method 1*/ int MaxSubSum1(const int A[], int n) { int thissum = 0; int maxsum = 0; for (int i = 0; i < n; ++i){ thissum += A[i]; if (thissum > maxsum){ maxsum = thissum; } else if(thissum < 0){ thissum = 0; } } return maxsum; } /*method 2*/ int MaxSubSum2entry(const int[], int, int); int MaxSubSum2(const int A[], int n) { return MaxSubSum2entry(A, 0, n - 1); } int max3(int, int, int); int MaxSubSum2entry(const int A[], int left, int right) { /*base case*/ if (left == right){ if (A[left] > 0){ return A[left]; } else{ return 0; } } int middle = (left + right) / 2; int maxleft = MaxSubSum2entry(A, left, middle); int maxright = MaxSubSum2entry(A, middle + 1, right); int maxboardsumL = 0; int thisboardsumL = 0; for (int i = middle; i >= left; --i){ thisboardsumL += A[i]; if (thisboardsumL > maxboardsumL){ maxboardsumL = thisboardsumL; } } int maxboardsumR = 0; int thisboardsumR = 0; for (int i = middle+1; i <= right; ++i){ thisboardsumR += A[i]; if (thisboardsumR > maxboardsumR){ maxboardsumR = thisboardsumR; } } return max3(maxleft, maxright, maxboardsumL+maxboardsumR); } int max3(int a, int b, int c) { int max = a > b ? a : b; int res = max > c ? max : c; return res; } int main() { int n = 6; int A[] = {-2, 11, -4, 13, -5, -2}; std::cout << MaxSubSum1(A, n) << std::endl; std::cout << MaxSubSum2(A, n) << std::endl; system("pause"); }4. 求幂问题
如果直接用循环求,时间复杂度为O(n),改用递归实现,复杂度降为O(nlog2(n))。
【示例代码】
#include <iostream> using namespace std; long int pow(long int x, unsigned int n) { if (n == 0){ return 1; } if (n == 1){ return x; } if (n % 2 == 0){ return pow(x*x, n / 2); } else{ return pow(x*x, n - 1)*x; } } int main() { cout << pow(2, 10) << endl; system("pause"); return 0; }
To be continued...
相关文章推荐
- 汇编复习笔记
- 算法复习笔记 | 排序算法比较
- 计算机网络复习笔记
- Java复习笔记-第一部分
- 自学笔记-C语言复习2015年7月4日
- 排序算法复习笔记
- c/c++复习笔记--002
- python复习笔记(1)
- Java复习笔记(四)——Java基本类型的类型转换
- .Net学习笔记----2015-07-08(基础复习和练习01)
- JDBC 复习笔记2
- 【郝斌数据结构自学笔记】27-29_链表插入和删除算法的演示_复习
- 基础复习笔记
- Hibernate 复习笔记二
- linux复习笔记 之bash shell (3) 通配符
- 系统分析员考试复习笔记-4:第四章 数据通讯与计算机网络
- 【复习笔记】贝叶斯学习
- 复习笔记总结
- 计量经济学复习笔记(二)