一.数据结构与算法
1)数据结构
1.数据结构的概念
**数据:**即信息的载体,是对客观事物的符号表示,指能输入到计算机中并被计算机程序处理的符号的总称。比如整数,实数,字符,文字,声音,图形,图像等都是数据。
数据元素:是数据的基本单位,一般由一个或多个数据项组成
数据项: 是不可分割的、含有独立意义的最小数据单位
数据结构: 是反映数据元素之间存在一种或多种特定关系的数据元素的集合的表示,即带有结构的数据元素的集合。
数据的四种基本结构:
2.数据的逻辑结构
线性结构:
特征:若结构是非空集,则有且仅有一个开始结点和一个终端结点,并且所有结点都最多只有一个直接前趋和一个直接后趋。线性表是一个典型的线性结构。栈、队列、串等都是线性结构
非线性结构:
特征:一个结点可能有多个直接前趋和直接后趋。数组、广义表、树和图等数据结构都是非线性结构。
3.数据存储方式
顺序、链式、索引和散列
2)算法与算法分析
1.算法
算法是对特定问题求解步骤的一种描述,是用来解决某个问题的一些指令的集合。它是指令的有限序列,其中每条指令表示一个或多个操作。
算法 + 数据结构 = 程序
**算法的特性:**有穷性、确定性、可行性、输入和输出
评价算法优劣标准:正确性、可读性、健壮性、高效率与低存储量需求。
2.算法分析
算法分析是对一个算法需要多少计算时间和存储空间作定量的分析。算法分析的目的在于改进算法的设计。 时间与空间的占用是一对矛盾。因此,很难设计出一个算法不占太多存储空间,运行时间又短,并且其他方面的性能也很好。
3.时间复杂度
影响程序运行时间的主要因素:
(1)问题的规模
(2)编译程序所产生的机器代码的质量
(3)机器执行一条指令的时间长短
(4)程序中语句的执行次数
其中(1)(2)(3)与硬件、软件、问题有关,(4)与算法有关。 因此,把算法中语句执行的次数作为算法时间多少的度量。 时间复杂度f(n)=O(n)在机器执行一条语句的时间固定的情况下,n可看成执行语句的次数(特别是循环语句次数)。
二.线性表、栈和队列
1)线性表
1.线性表的概念
线性表是n(n≥0)个数据元素a1,a2,...,an组成的有限序列,n=0时称为空表。
非空的线性表,有以下特征:
(1)有且仅有一个开始结点a1,没有直接前趋,有且仅有一个直接后继a2
(2)有且仅有一个终结结点an,没有直接后继,有且仅有一个直接前趋an-1
(3)其余的内部结点ai(2≤i≤n-1)都有且仅有一个直接前趋ai-1和一个直接后继ai+1。
2.线性表的链式存储结构
链表是用一组任意的存储单元来存放线性表的结点,这组存储单元既可以是连续的,也可以是不连续的,甚至是零散分布在内存的任意位置上,因此,链表中结点的逻辑次序和物理次序是不同的。
【补充】 数据的逻辑结构是指数据元素之间的逻辑关系,它与所使用的计算机无关;
**数据的物理结构,又称存储结构,**是指数据结构在计算机中的表示,它包括数据元素的表示和元素的表示。
为了能正确表示结点间的逻辑关系,链表中的结点结构为:
2)栈
栈的概念: 栈是限制仅在表的一端进行插入和删除运算的线性表,通常插入、删除的这一端为栈顶,另一端称为栈底。
栈的操作原则: 栈的操作原则是后进先出或先进后出。
3)队列
队列是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表
当队列中没有元素时称为空队列
队列和栈一样,只允许在端点进行操作
一般有两种存储结构:顺序存储结构和链式存储结构。 队列的修改是按照先进先出的原则进行的。
三.二叉树
1)二叉树
二叉树是n(n≥0)个结点的有限集,它可以是空集(n=0),或者由一个根结点及两棵互不相交的、分别称作这个根的左子树和右子树的二叉树组成。
二叉树的性质:
(1)深度为k的二叉树上至多含有2k-1个结点(k≥1)
(2)对任何一棵二叉树,度为0的结点(叶子结点)总比度为2的结点多一个。
若它含有n0个叶子结点、n2个度为2的结点,则必存在关系式:n0= n2+1。
2)完全二叉树
满二叉树: 除最后一层外,每一层上的所有结点都有两个子结点;深度为k(k≥1)且有2k-1个结点的二叉树称为满二叉树
**完全二叉树:除最后一层外,每一层上的所有结点都有两个子结点;在最后一层上只缺少右边的若干结点。**如果在一棵深度为k(k≥1)的满二叉树上删去第k层上最右边的连续j(0≤j < 2k-1)个结点,就得到一棵深度为k的完全二叉树。满二叉树也是完全二叉树。

3)二叉树的遍历
先序遍历: 根左右
中序遍历: 左根右
后序遍历: 左右根
先中后指的是"根"的位置
四.查找与排序
1)查找
1.查找的概念
查找表是由同一类型的数据元素(或记录)构成的集合。分为两类:静态查找表和动态查找表。
2.线性表的查找
(1)顺序查找:从表的一端开始,顺序扫描线性表,依次将扫描到的结点关键字和给定值K相比较。若当前扫描到的结点关键字与K相等,则查找成功;若扫描结束后,仍未找到关键字等于K的结点,则查找失败。时间复杂度O(n)
(2)二分查找(折半查找):要求线性表是有序表,每次将查找区间中间位置上的数据元素的键值与给定值K比较,若不等则缩小查找区间,并在新的区间内重复上述过程,直到查找成功或查找区间长度为0(查找不成功)为止
二分查找的基本思想是: 将n个元素分成个数大致相同的两半,取a[n/2]与欲查找的x作比较,如果x=a[n/2]则找到x,算法终止。如果x < a[n/2],则我们只要在数组a的左半部继续搜索x(这里假设数组元素呈升序排列)。如果x > a[n/2],则我们只要在数组a的右半部继续搜索x。 二分查找比顺序查找算法则更优,因为其查找时间为O(lgn)
2)排序
1.排序概述
排序,就是使文件中的记录按关键字递增(或递减)次序排列起来。 按是否访问外存,可将排序方法分为内部排序和外部排序。 对于内部排序,根据设置有序序列的方式的不同,又可以划分为插入排序、交换排序、选择排序、归并排序和其他排序方法。
2.常用排序方法
**1. 插入排序:**插入排序的基本思想是每步将一个待排序的记录按其排序码值的大小,插到前面已经排好的文件中的适当位置,直到全部插入完为止。插入排序方法主要有直接插入排序和希尔排序。
(1)直接插入排序: 每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。
第一趟比较前两个数,然后把第二个数按大小插入到有序表中;第二趟把第三个数据与前两个数从后向前扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。
直接插入排序属于稳定的排序,时间复杂性为o(n²)。
(2)希尔排序: 基本思想:已知一组无序数据a[1]、a[2]、......a[n],需将其按升序排列。发现当n不大时,插入排序的效果很好。
首先取一增量d(d < n),将a[1]、a[1+d]、a[1+2d]......列为第一组,a[2]、a[2+d]、a[2+2d]......列为第二组......,a[d]、a[2d]、a[3d]......列为最后一组以此类推,在各组内用插入排序,然后取d' < d,重复上述操作,直到d=1。 一般取d₁=n/2,dᵢ₊₁=dᵢ/2。如果结果为偶数,则加1,保证dᵢ为奇数。
希尔排序不稳定,希尔排序的执行时间依赖于增量序列,其平均时间复杂度O(n¹·²⁵)
优点:快,数据移动少; 缺点:不稳定,d的取值是多少,应取多少个不同的值,都无法确切知道,只能凭经验来取。
2. 交换排序: 两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,直到没有反序的记录为止。**(1)冒泡排序:**已知一组无序数据a[1]、a[2]、......a[n],需将其按升序排列。首先比较a[1]与a[2]的值,若a[1]大于a[2]则交换两者的值,否则不变。再比较a[2]与a[3]的值,若a[2]大于a[3]则交换两者的值,否则不变。再比较a[3]与a[4],以此类推,最后比较a[n-1]与a[n]的值。这样处理一轮后,a[n]的值一定是这组数据中最大的。再对a[1] ~ a[n-1]以相同方法处理一轮,则a[n-1]的值一定是a[1] ~ a[n-1]中最大的。再对a[1] ~ a[n-2]以相同方法处理一轮,以此类推。共处理n-1轮后a[1]、a[2]、......a[n]就以升序排列了。
优点:稳定,比较次数已知; 缺点:慢,每次只能移动相邻两个数据,移动数据的次数多。
(2)快速排序: 快速排序是冒泡排序的改进版,是目前已知的最快的排序方法。
已知一组无序数据a[1]、a[2]、......a[n],需将其按升序排列。首先任取数据a[x]作为基准。比较a[x]与其它数据并排序,使a[x]排在数据的第k位,并且使a[1] ~ a[k-1]中的每一个数据<a[x],a[k+1] ~ a[n]中的每一个数据>a[x],然后采用分治的策略分别对a[1] ~ a[k-1]和a[k+1] ~ a[n]两组数据进行快速排序。
优点:极快,数据移动少; 缺点:不稳定。
(3)选择排序:
①初始状态:无序区为R[1..n],有序区为空
②第1趟排序 在无序区R[1..n]中选出关键字最小的记录R[k],将它与无序区的第1个记录R[1]交换,使R[1..1]和R[2..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区
③第i趟排序 第i趟排序开始时,当前有序区和无序区分别为R[1..i-1]和R[i..n](1≤i≤n-1)。该趟排序从当前无序区中选出关键字最小的记录R[k],将它与无序区的第1个记录R交换,使R[1..i]和R[i+1..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。这样,n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果。
优点:稳定,比较次数与冒泡排序一样; 缺点:相对之下还是慢。
**(4)归并排序算法:**合并排序是又一类不同的排序方法,合并的含义就是将两个或两个以上的有序数据序列合并成一个新的有序数据序列,因此它又叫归并算法。
它的基本思想就是假设数组A有N个元素,那么可以看成数组A是由N个有序的子序列组成,每个子序列的长度为1,然后再两两合并,得到了一个N/2个长度为2或1的有序子序列,再两两合并,比如此重复,值得得到一个长度为N的有序数据序列为止,这种排序方法称为2-路合并排序。
各算法的时间复杂度①平均时间复杂度:
插入排序O(n²),冒泡排序O(n²),选择排序O(n²)
快速排序O(n log n),堆排序O(n log n),归并排序O(n log n)
基数排序O(n),希尔排序O(n¹·²⁵)
②算法稳定性: 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法;
冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。

