一、算法级基础知识
1.算法的基本概念
解决问题的确定方法和有限步骤称为算法,对于计算机科学来说,算法指的是对特定问题的求解步骤的一种描述,是若干条指令的有穷序列。并有以下特性:输入、输出、确定性、有限性、可行性
算法与程序的区别:程序是算法用某种程序设计语言的具体实现,程序设计的实质就是构造解决问题的算法。算法+数据结构=程序,算法的结构和选择依赖于数据结构,所以数据结构是算法设计的基础。
2.算法设计的一般过程(8步骤)
1.充分理解要解决的问题
在设计算法的时候,一定要先搞清楚算法要求处理什么问题、实现哪些功能、预期获得的结果等。
2.数学模型拟制
简单地说,数学模型就是对实际问题的一种数学表达,是数学理论与实际相结合的一门学科。
3.算法详细设计
算法详细设计指的是把算法具体化,即设计出算法的详细规格说明。
4.算法描述
根据前三部分的工作,采用描述工具将算法的具体过程描述下来。
5.算法思路的正确性验证
通过公式定理来验证算法所选择的设计策略及设计思路是否正确。
6.算法分析
算法分析是对算法的效率进行分析,主要是时间效率和空间效率。
7.算法的计算机实现和测试
采用某种程序设计语言来实现算法,并在计算机上进行运行和测试。
8.文档资料的编制
撰写算法的整个设计过程。
3.算法分析(时间、空间复杂度)
算法分析:分析的是性能、效率
1.时间复杂性
时间复杂性是对算法运行时间长短的度量
2.空间复杂性
空间复杂性是对一个算法在运行过程中所占用存储空间大小的度量。
递归算法要分析空间复杂性
4.递归(必考)
子程序(或函数)直接或间接调用自己称为递归。可能分析空间复杂度。
递归算法运行的过程分为两个阶段:递推和回归
(1)递归原理:
1.当子程序(函数/方法)被调用的时候,在数据栈的栈顶 分配 它的 局部变量和形式参数的 存储空间。
2.当子程序返回时,才从栈顶 释放 它的 局部变量和形式参数的 存储空间。
3.子程序运行使用的是栈顶的那一份变量和形式参数。
4.全局变量、静态局部变量和动态分配的变量(new 分配的),分配在"堆"里,不随程序的调用返回而变化。
(2)递归算法的复杂性分析:
1.递归算法的时间复杂性分析
最常用的就是后向代入法
以全排列问题的为例:
全排列算法的时间=复杂性为:O(n!)
2.递归算法的空间复杂性分析
是指算法的递归深度,即算法在执行过程中所需要的用于存储“调用记录”的递归栈的空间大小。
5.基本的数据结构
所谓数据结构,可以定义为:组织一系列相关数据元素的某种方式(组织数据的方式)。
无关系:集合结构
一对一:线性结构,例如:顺序表与链表,栈与队列
一对多:树型结构
多对多:图型结构
(1)顺序表与链表
线性表是最简单、最常用的一种数据结构,一个线性表是n个数据元素的有限序列。
顺序表:把线性表的元素按逻辑次序依次存放在一组地址连续的存储单元,用这种方法存储的线性表简称为顺序表。
链表:链表是线性表的另一种存储方式,其特点是用一组任意的存储单元存储线性表的数据元素,它由一系列的节点组成,节点可以在运行时动态生成。主要有单链表、循环链表、双向链表。
(2)栈与队列
栈:栈可以看成是一种“特殊”的线性表,该线性表限定仅在表尾进行插入和删除操作(先进后出),栈主要应用于表达式的计算、子程序嵌套调用、递归调用等。栈的性质:通常称插入、删除的这一端称为栈顶(Top),另一端称为栈底(Button)。
队列:和栈相反,队列是一种先进先出的线性表,它只允许在表的一端插入 元素,而在另一端删除元素。队列的性质:允许删除的一端称为队头(Front),允许插入的一端称为队尾(Rear)。
(3)树与图
树:数型结构是以分支关系定义的层次结构,它是一种重要的非线性结构。
图:图是一种比线性表和树更为复杂的数据结构,可以用二元组表示,图中的数据元素通常被称为顶点(或节点),数据元素之间的关系称为边,其形式定义为:G=(V,E),集合V是顶点集,集合E是边集。
在线性表中,数据元素之间仅存在线性关系,即每个元素只有一个直接前驱和一个直接后继
在树型结构中,元素之间具有明显的层次关系,每个元素只能和上一层的一个元素相关,但也可以和下一层的多个元素相关。
在图型结构中元素之间的关系可以是任意的,一个图中任意两个元素都可以相关,即每个元素可以有多个前驱和多个后继。
(4)集合
从逻辑结构上看,集合的元素之间没有任何确定的依赖关系,主要考虑集合之间的并、交、和差操作。
二、分治法
概念:分治法,字面上解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同子问题,再把子问题分成更小的子问题,直到最后各个子问题可以简单地直接求解,对各个子问题的解进行合并即得原问题的解。
通常分治法的求解过程都要遵循两大步骤:分解和治理
1.二分查找
二分查找又称为折半查找,它要求待查找的数据元素必须是按关键字大小有序排列的。
(1)二分查找算法实现的非递归形式
int binSearch1(int arr[], int n, int key) {
int left = 0;
int right = n - 1;
int mid;
while (left <= right) {
mid = (left + right) / 2;
if (arr[mid] == key) {
return mid;}
else if (arr[mid] > key) {
right = mid - 1;}
else if (arr[mid] < key) {
left = mid + 1;}
}
return -1;
}
(2)二分查找算法实现的递归形式
int binSearch2(int arr[], int key, int left, int right) {
int mid = (left + right) / 2;
if (left > right) {
return -1;}
if (arr[mid] == key) {
return mid;}
else if (arr[mid] > key) {
return binSearch(arr, key, left, mid - 1);}
else if (arr[mid] < key) {
return binSearch(arr, key, mid + 1, right);}
}
2.快速排序
快速排序是一种划分交换排序。
int Partition(int arr[], int left, int right) {
int temp = arr[left];
int i = left;
int j = right;
while (i<j) {
while (i<j && arr[j]>temp)
j--;
if(i<j){
swap(arr[i], arr[j]);}
while (i<j && arr[i] <= temp)
i++;
if (i<j) {
swap(arr[i], arr[j--]);}
}
return j;
}
void QuickSort(int arr[], int left, int right) {
int mid;
if (left < right) {
mid = Partition(arr, left, right);
QuickSort(arr, left, mid - 1);
QuickSort(arr, mid + 1, right);
}
}