1、数据结构的定义?
一、逻辑结构:反映数据元素之间的逻辑关系的数据结构,逻辑关系是指数据元素之间的前后件关系,而与他们在计算机中的存储位置无关。
逻辑结构包括:1.集合 2.线性结构 3.树形结构 4.图形结构
二、数据的物理结构:指数据的逻辑结构在计算机存储空间的存放形式。
2、栈的两个应用:括号匹配和表达式的计算?
1. #define m0 100
2. /*m0为算术表达式中最多字符个数*/
3. correct(exp,tag)
4. char exp[m0];
5. int tag; //tag用于标识是否匹配,tag=0标识不匹配,tag=1标识匹配
6. {
7. char st[m0];
8. int top=0,i=1;
9. tag=1;
10. while(i<=m0 && tag)
11. {
12. if(exp[i]=='('‖exp[i]=='['‖exp[i]=='{'
13. /*遇到'('、'['或'{',则将其入栈*/
14. {
15. top++;
16. st[top]=exp[i];
17. }
18. if(exp[i]==')') /*遇到')',若栈顶是'(',
19. 则继续处理,否则以不配对返回*/
20. if(st[top]=='(') top--;
21. else tag=0;
22. if(exp[i]==']') /*遇到')',若栈顶是'[',
23. 则继续处理,否则以不配对返回*/
24. if(st[top]=='[') top--;
25. else tag=0;
26. if(exp[i]=='}') /*遇到')',若栈顶是'{',
27. 则继续处理,否则以不配对返回*/
28. if(st[top]=='{') top--;
29. else tag=0;
30. i++;
31. }
32. if(top>0)tag=0; /*若栈不空,则不配对*/
33. }
1)不考虑空间时间复杂度,以最简单的看待问题的视角去解决。比如八皇后问题,使用8重循环来依依判断,比如全排列,使用多重循环枚举的方式等等。
假设文本字符串为T[1,,,n],模板字符串P[1,,,m]。m <= n;一般说来,我们认为文本和模板的字母表相同。如果存在整数s 使得0<= s <= n-m且T[s+1..s + m]=P[1..m],我们说模板P在文本T的偏移(shift) s出现,也可以说在位置s+1出现(因为T[s+1]=P[1])。
2)假设在模式匹配的进程中,执行T[i]和W[j]的匹配检查。若T[i]=W[j],则继续检查T[i+1]和W[j+1]是否匹配。若T[i]<>W[j],则分成两种情况:若j=1,则模式串右移一位,检查T[i+1]和W[1]是否匹配;若1<j<=m,则模式串右移j-next(j)位,检查T[i]和W[next(j)]是否匹配。重复此过程直到j=m或i=n结束。
4、哈希函数的种类?余数的取法?处理冲突的方法?闭散列方法有哪些?
在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使每个关键字和结构中一个唯一的存储位置相对应。
1)哈希表中元素是由哈希函数确定的。将数据元素的关键字K作为自变量,通过一定的函数关系(称为哈希函数),计算出的值,即为该元素的存储地址。表示为:Addr = H(key)。
为此在建立一个哈希表之前需要解决两个主要问题:
---构造一个合适的哈希函数
均匀性 H(key)的值均匀分布在哈希表中;
---冲突的处理
冲突:
在哈希表中,不同的关键字值对应到同一个存储位置的现象。即关键字K1≠K2,但H(K1)= H(K2)。均匀的哈希函数可以减少冲突,但不能避免冲突。发生冲突后,必须解决;也即必须寻找下一个可用地址。
---解决冲突的方法:
1)拉链法。
将具有同一散列地址的记录存储在一条线性链表中。例,除留余数法中,设关键字为 (18,14,01,68,27,55,79),除数为13。散列地址为 (5,1,1,3,1,3,1)。
2)开放定址法。
如果h(k)已经被占用,按如下序列探查:(h(k)+p⑴)%TSize,(h(k)+p⑵)%TSize,…,(h(k)+p(i))%TSize,…
其中,h(k)为哈希函数,TSize为哈希表长,p(i)为探查函数。
3)桶定址法。
桶:一片足够大的存储空间。
桶定址:为表中的每个地址关联一个桶。
如果桶已经满了,可以使用开放定址法来处理。例如,插入A5,A2,A3,B5,A9,B2,B9,C2,采用线性探查法解决冲突。
---哈希表的构造方法
1)直接定址法
2)数字分析法
3)平方取中法
4)折叠法
5)除留余数法
6)随机数法
---开放地址法
公式:Hi=(H(key)+di) MOD m i=1,2,...,k(k<=m-1)
其中,m为哈希表的表长。di 是产生冲突的时候的增量序列。
如果di值可能为1,2,3,...m-1,称线性探测再散列。
如果di取1,则每次冲突之后,向后移动1个位置.如果di取值可能为1,-1,4,-4,9,-9,16,-16,...k*k,-k*k(k<=m/2)称二次探测再散列。如果di取值可能为伪随机数列。称伪随机探测再散列。
---建域法
假设哈希函数的值域为[0,m-1],则设向量HashTable[0..m-1]为基本表,另外设立存储空间向量OverTable[0..v]用以存储发生冲突的记录。
5、二叉搜索树?
1)或者是一棵空树,或者是具有下列性质的二叉树:
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉排序树。
2)二叉排序树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉排序树的存储结构。中序遍历二叉排序树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索,插入,删除的复杂度等于树高,O(log(n))。
6、二叉平衡树?
又被称为AVL树(有别于AVL算法),且具有以下性质:
它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
构造与调整方法 平衡二叉树的常用算法有红黑树、AVL、Treap等。
最小二叉平衡树的节点的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。
7、红黑树的定义?
每个节点都带有颜色属性的二叉查找树,颜色或红色或黑色。在二叉查找树强制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求:
性质1. 节点是红色或黑色。
性质2. 根节点是黑色。
性质3 每个叶节点(NIL节点,空节点)是黑色的。
性质4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
8、图有哪些存储表示?
1)图的邻接矩阵表示法
① 用邻接矩阵表示顶点间的相邻关系。
② 用一个顺序表来存储顶点信息。
2)图的邻接表表示法
类似于树的孩子链表表示法。对于图G中的每个顶点vi,该方法把所有邻接于vi的顶点vj链成一个带头结点的单链表,这个单链表就称为顶点vi的邻接表(Adjacency List)。
9、外部排序的过程?
一般提到排序都是指内排序,比如快速排序,堆排序,归并排序等,所谓内排序就是可以在内存中完成的排序。
外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。
外部排序最常用的算法是多路归并排序,即将原文件分解成多个能够一次性装人内存的部分,分别把每一部分调入内存完成排序。然后,对已经排序的子文件进行归并排序。
1)一般来说外排序分为两个步骤:预处理和合并排序。
即首先根据内存的大小,将有n个记录的磁盘文件分批读入内存,采用有效的内存排序方法进行排序,将其预处理为若干个有序的子文件,这些有序子文件就是初始顺串,然后采用合并的方法将这些初始顺串逐趟合并成一个有序文件。
外部排序过程可以分成两个相对独立的阶段:
(1)按可用内存的大小,把外存上含有n个记录的文件分成若干个长度为L的子文件,把这些子文件依次读入内存,并利用有效的内部排序方法对它们进行排序,再将排序后得到的有序子文件重新写入外存;
(2)对这些有序子文件逐趟归并,使其逐渐由小到大,直至得到整个有序文件为止。
步骤如下:
1.初始化堆
(1)从磁盘读入M个记录放到数组RAM中
(2)设置堆末尾标准LAST=M-1
(3)建立最小值堆
2.重复以下步骤直到堆为空
(1)把具有最小关键码值的记录Min也就是根节点送到输出缓冲区
(2)设R是输入缓冲区中的下一条记录,如果R的关键码大于刚刚输出的关键码值Min,则把R放到根节点,否则使用数组中LAST位置的记录代替根节点,并将刚才的R放入到LAST所在位置,LAST=LAST-1;
(3)重新排列堆,筛出根节点
10、B树、B+树、Trie树的概念及用途?
---B树是一种平衡的多分树,通常我们说m阶的B树,它必须满足如下条件:
(1)每个结点至多有m个子结点;
(2)除根结点和叶结点外,其它每个结点至少有 个子结点;
(3)若根结点不是叶子结点,则至少有两个子结点;
(4)所有的叶结点在同一层;
(5)有k个子结点的非根结点恰好包含k-1个关键码。
B树上的查找是一个顺指针查找结点和在结点内的关键码中查找交叉进行的过程。从根结点开始,在结点包含的关键码中查找给定的关键码,找到则查找成功;否则确定给定关键码可能在的子树,重复上面的操作,直到查找成功或者指针为空为止。
---B+树是B树的一种变形树,它与B树的差异在于:
1)有k个子结点的结点必然有k个关键码;
2)非叶结点仅具有索引作用,跟记录有关的信息均存放在叶结点中。
---Trie树,又称单词查找树,是一种树形结构,是一种哈希树的变种。
典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。
--它有3个基本性质:
根节点不包含字符,除根节点外每一个节点都只包含一个字符;
从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串;
每个节点的所有子节点包含的字符都不相同。
--搜索字典项目的方法为:
(1) 从根结点开始一次搜索;
(2) 取得要查找关键词的第一个字母,并根据该字母选择对应的子树并转到该子树继续进行检索;
(3) 在相应的子树上,取得要查找关键词的第二个字母,并进一步选择对应的子树进行检索。
(4) 迭代过程……
(5) 在某个结点处,关键词的所有字母已被取出,则读取附在该结点上的信息,即完成查找。