数据结构期末复习笔记
绪论
我相信大家都厌烦了只讲解决方法,而不讲原理的博客了,本篇力求将将难点的原理和容易让人困惑的地方加上原理和原因。
数据结构的概念
非数值计算解决方法的一般步骤:
- 数据间的关系如何表示 :利用数据的逻辑结构。
- 数据在计算机内如何存储:数据的存储结构(物理结构)。
- 求解问题,即数据的操作:数据的运算,定义在数据的逻辑结构上的抽象的操作。
因此:.数据结构是研究数据的物理结构、逻辑结构以及它们之间的相互关系。
数据结构的分类
- 按数据元素之间的关系分:线性结构和非线性结构。‘
- 按逻辑结构分:集合结构,线性结构,树型结构,图型结构。
- 按存储方式分:顺序存储、链式存储、索引存储结构、散列存储结构。
数据结构研究的内容
逻辑结构、存储结构和操作。
算法的重要特性
有穷性、确定性、可行性、输入、输出。
算法的设计要求
正确性、可读性、健壮性、效率与低存储量要求。
题目汇总
- 二元组 Date = (D,S) : D 表示 数据元素的有限集 ,S 表示D上的关系的有限集。
- 数据元素相互之间的关系称为 :结构。
- 非线性结构是元素之间存在一种 : 多对多关系。
- 算法分析的目的是:分析算法的效率以求改进。
- 计算机算法指的是:解决问题的有限运算序列。
- 数据元素是数据的基本单位,数据项才是数据不可分割的最小单位。
线性表
首元结点:指链表中存储第一个数据元素a1的结点。
头结点:是为了操作方便在首元结点前复设的结点。
头指针:指向链表中第一个结点(或为头结点或为首元结点)的指针。
如何没有头指针,那么不带头结点的线性链表只有在删除第一个节点,即首元结点时,需要更改头指针。如果删除其他结点,则不需要更改头指针。而如果带了头结点的话就不用特判了,便于处理。
- 在顺序表中插入和删除一个结点平均移动多少个结点:在等概率情况下,顺序表中插入一个结点需要平均移动n/2个结点。删除一个结点需要平均移动(n-1)/2个结点。
原因:1、当对n个元素进行插入操作时,有n+1个位置可以进行插入,如下所示(“.”代表可以插入的位置)。
.1.2.3.4. -- .n.
在每个位置插入时需要移动的元素个数分别为n,n-1,n-2…,1,0,所以,总共需要移动的元素个数为(1+2+3+4+…+n)=n*(n+1)/2。
故平均需要移动的元素个数为n*(n+1)/2(n+1)=n/2;
2、当对N个元素进行删除操作时,有N个位置可以删除。
1,2,3,4…n
每个位置需要移动的元素个数分别为n-1,n-2,n-3…1,0个。所以平均需要移动的元素个数为(n-1)n/2n=(n-1)/2个。 - 任意单元的地址: a i = a 1 + ( i − 1 ) d a_i = a_1 + (i - 1) d ai=a1+(i−1)d
- 在一个长度为n的顺序表中,在第i个元素之前插入一个元素 ,需要向后移动:n - i + 1 个元素。原因:第i个元素之前那么后边元素为i~n ,那么n - i 得到的是是i后边的元素个数,因此加上i , 故为 n - i + 1 。
- t指向最后一个元素的意思是,t就是最后一个元素的指针,切记。
- 在一个长度为n的顺序表中,删除第i个元素 ,需要向前移动:n - i 个元素。原因:第i个元素之前那么后边元素为i+1~n ,那么n - (i + 1 ) 得到的是是i+1后边的元素个数,因此加上i+1这个元素 , 故为 n - (i + 1 ) + 1 = n - i 。
- 10.链接存储的特点是利用__指针______来表示数据元素之间的逻辑关系。
11.顺序存储结构是通过__物理上相邻______表示元素之间的关系的;链式存储结构是通过___指针_____表示元素之间的关系的。
-
对于双向链表,在两个结点之间插入一个新结点需修改的指针共 __4____个,单链表为____2___个。
-
循环单链表的最大优点是:从任一结点出发都可访问到链表中每一个元素。
-
带头结点的双循环链表L中只有一个元素结点的条件是:___ L->next->next==L _____
-
在单链表L中,指针p所指结点有后继结点的条件是:__ p->next!=null
-
带头结点的双循环链表L为空表的条件是:___ L->nextL && L->priorL_____。
-
带头结点的单循环链表L为空表的条件是:___ L->next==L _____。
栈和队列
栈
- 对于顺序表,设base 为栈底指针,top为栈顶指针,则判断栈空的条件是:
base == top,栈中元素个数top - base.(当栈顶指针指向当前栈顶元素) - 当栈顶指针指向当前栈顶元素,那么插入(进栈)操作是 :
top++ , base[top] = val, 退栈操作是:top--; 当栈顶指针指向栈顶元素的下一个位置,那么 进栈操作是base[top] = val , top++, 退栈操作是top--。感觉没啥用,不过就是这样。。。 - 前缀表达式、中缀表达式和后缀表达式:(以运算符所在的位置来命名的)

补充一个:利用栈将中缀转化为后缀的方法:从左到右遍历中缀表达式的每个数字和符号,若是数字则直接输出,若是符号,则判断其与栈顶符号的优先级,是右括号或者优先级低于栈顶符号,则栈顶元素依次出栈并输出,直到遇到左括号或栈空才将低优先级的那个符号入栈。
- 表达式求值。第一步先将中缀转化为后缀。然后利用后缀进行计算。计算方法如下:
建立两个栈,一个为数值栈,一个为运算符栈。当遇到数值就直接压入数值栈中。当遇到运算符,分为两种情况,一种是输入运算符优先级大于栈顶优先级,直接压栈,另一种是输入运算符优先级小于栈顶优先级(符号相同也算),先从数据栈中弹出两个元素,与运算符弹出的栈顶符号相运算,运算结果压入,后将运算符压入栈。
队列
- 在循环队列中,队空标志为
front == rear, 队满标志为:(reat + 1 ) % m == front; 当 rear >= front 时 ,队列长度为rear - front, 反之 为(rear + m - front) % m - 带头结点的链队列Q , 判定队列中只有一个元素的条件是:
Q.front - > next = Q.rear - 顺序队列 ,对于一个一维数组 ,有两种实现方法,一种是 front 与 rear 最初同时指向一个位置(一般是0) 即rear 指向的是队尾下一个元素的位置, 那么 进队操作是 :
q[rear] = val , rear++, 出队操作是:if(front < rear) front ++对空操作是 :rear == front; 另一种实现方式是 front = 0 ,rear = - 1 ; 即rear 指向的是队尾元素的位置. 进队操作:q[++rear] = val, 出队操作是:if( front <= rear) front++ - 对于链式队列 , 起初 front 和 rear 指针同时指向一个起始地址 , 入队操作:
p->data = val , p->next = NULL , Q.rear->next = p ; Q.rear = p;所以 rear 指针指向的是队尾元素的位置 , 判断对空操作:Q.rear == Q.front
题目
- 空间大小为n 的循环队列 ,执行出队操作后,
front = (front+1) % n - 长度为N的循环队列,其队头指针为P , 头尾指针为R ,则 当前队列中元素个数为:(R-P + N )% N;
数组与广义表
树
二叉树
- 对于完全二叉树,如果节点个数为奇数,那么就不存在度为1的节点。当节点个数为偶数的时候,当且仅当存在一个度为1的节点。
- 二叉树的第k层最多有 2 k − 1 2^{k-1} 2k−1 个节点。因为第1层即根节点有 2 0 2^{0} 20 ,而下一层最多是上一层的两倍。
- 高度为k的二叉树最多有 2 k − 1 2^{k} - 1 2k−1个节点。依次为 2 0 、 2 1 . . . . 2 k 这 是 一 个 首 项 为 1 公 比 为 2 , 项 数 为 k 的 等 比 数 列 2^0 、2^1 .... 2^k 这是一个首项为1 公比为2,项数为k的等比数列 20、21....2k这是一个首项为1公比为2,项数为k的等比数列
- 对于任意一颗二叉树, n 2 为 度 为 2 的 节 点 , n 1 为 度 为 1 的 节 点 , n 0 为 度 为 0 得 节 点 ( 即 叶 子 ) n_2 为度为2的节点 , n_1 为度为1的节点 , n_0 为度为0得节点(即叶子) n2为度为2的节点,n1为度为1的节点,n

最低0.47元/天 解锁文章
741

被折叠的 条评论
为什么被折叠?



