数据结构
文章平均质量分 66
xuguoli_beyondboy
只要笑一笑,没什么过不了。程序员懂得编程之美,也要懂得生活之美,艺术之美,心理之美。
展开
-
稀疏矩阵
在矩阵中,如果很多元素都是零,这种矩阵称为稀疏矩阵,在对稀疏矩阵存储中,常常不存储零元素来节省空间的,矩阵常用操作有转置,加法,乘法等操作,其中转置和乘法最常用。 假设有a和b两个矩阵,其中b是a的转置矩阵,a和b矩阵表示如图: 矩阵结构体typedef struct{ //矩阵对应的列值 int col; //矩阵对应的行值 int row; //矩阵行和列原创 2015-07-25 18:22:12 · 1424 阅读 · 1 评论 -
图
完全图是具有最多边数的图,一个具有n个顶点的完全无向图,其边数为n(n-1)/2,而一个具有n个顶点的完全有向图,其边数为n(n-1). 一条简单路径是指路劲上除了起点和终点可能相同外,其余顶点都互不相同。 在无向图G中,如果从顶点v0到v1存在一条路径,则称顶点v0和v1是连通的,如果无向图G中的每对顶点vi和vj,都存在一条从vi到vj的路劲,则称无向图G是连通的。 在有向图G中,如果每对原创 2015-09-20 14:39:50 · 1108 阅读 · 0 评论 -
最小生成树
一颗带权无向图的生成树的代价是该生成树中所有边的代价之和,最小代价生成树就是一颗代价最小的生成树,构建无向图的最小生成树就是采用贪心算法,不过对于最小生成树问题,需满足以下约束条件:只能使用图中的边只能使用恰好n-1条边不能使用产生环路的边 Kruskal算法通过每次向当前最小代价生成树T中加入一条边的方法构成最终的最小生成树T,算法按照边的代价非递减的顺序选取,并加入T中,如果所选取的边与原创 2015-10-24 13:27:22 · 823 阅读 · 0 评论 -
图的深度优先搜索和广度优先搜索
深度优先搜索首先访问起始顶点v,这里假设访问只是输出结点所对应的顶点序号字段,然后,从顶点v的邻接表中选取一个未访问过的顶点w进行访问,并从w开始继续进行深度优先搜索,将v的邻接表中的当前位置保存在一个栈中,当最终搜索到一个顶点u,且u的邻接表中的顶点全部被访问过时,就从栈中取出一个顶点,并按照上述方法处理该顶点的邻接表,整个过程类似树的前序遍历。 图G的结构图和邻接表图: 其图深度搜原创 2015-09-21 16:26:27 · 1513 阅读 · 0 评论 -
表验证
通常,我们需要比较表来验证他们是否相同,或者找出相异的元素,因此表验证问题实际上就是把一个表的每个关键字作为待查关键字,对另一个表进行重复查找,这里可以用随机表和有序表来设计表验证算法,假设有两个表list1和list2,其关键字分别为list1[i].key, 0<=i<=n和list2[i].key,0<= j//随机验证表算法void verify1(element list1[],elem原创 2015-10-26 14:18:00 · 634 阅读 · 0 评论 -
二分法查找(折半查找)
顺序查找并没有对表中的关键字域的顺序做出任何假设,与顺序查找不同,在折半查找中,表中的记录是按关键字域有序排列的,其比较会出现下面三种结果: searchumn< list[middle].key,此时,无需考虑位于list[middle]和list[n-1]之间的记录,而继续查找位于list[0]和list[middle-1]间的记录。searchnum=list[middle].key,此时原创 2015-10-26 13:18:23 · 2144 阅读 · 0 评论 -
顺序查找
假定有一个表list和一个待查找关键字searchnum,要找到表中关键字与 searchnum相匹配的记录,如果表中list有n个记录,且list[i].key表示记录i的关键字值,可以通过依次检查关键字值list[0].key,list[1].key,…list[n-1].key对其进行查找 ,直至找到该记录所在位置,或者检查完表中全部记录为止,这种方式就叫顺序查找,时间复杂度:∑i=0n−1(原创 2015-10-26 14:20:46 · 823 阅读 · 0 评论 -
插入排序
初始时,有序序列为R0R_0,有序序列R0R_0,然后依次插入R1R_1,R2R_2,…,Rn−1R_{n-1},由于每次插入都使得结果序列是有序,故叫插入排序,其实时间复杂度:O(∑i=0n−1i)=O(n2)O(\sum\limits_{i = 0}^{n - 1} i ) = O({n^2}). 假定n=5,且输入序列为(5,4,3,2,1),每次插入后的情况如下: i [0]原创 2015-10-27 12:58:45 · 568 阅读 · 0 评论 -
快速排序
快速排序根据整个文件,把控制当前排序进程的基准关键字放在正确的位置上,在快速排序总,如果把关键字k1k_1放置在位置s(i)s(i)处,那么,当j<s(i)s(i)时,则有kj<=ks(i)k_j<=k_{s(i)},而j>s(i)s(i)时,则有kj>=ks(i)k_j>=k_{s(i)},因此,当把基准关键字放置在此位置上后,原来的文件被划分为两个子文件,其中的一个文件包含记录R0R_0,…,R原创 2015-10-27 14:09:28 · 1672 阅读 · 0 评论 -
归并排序
在归并排序的迭代算法中,可以把输入序列看成是个n个已排序序列,其中每个序列的长度为1,将这些序列两两归并就得到了 n/2个长度为2的序列(如果n为奇数,则有一个序列长度为1),然后对这n/2这个序列进行两两归并,依次类推,直到只剩下一个序列为止。 归并排序是在输入记录上执行若干遍归并,其中第一遍归并的是长度为1的子序列,第二遍归并的是长度为2的子序列,而第i遍归并的是长度为2i−12^{i-1}原创 2015-11-14 11:03:46 · 1452 阅读 · 0 评论 -
基数排序
基数排序是把一个逻辑关键字看成是由多个关键字组合而成的,并且一步一步地按每个关键字排号顺序,如把这些关键字记为:K0K^0,K1K^1,…,Kr−1K^{r-1},其中K0K^0为该记录中最高有效关键字,而Kr−1K^{r-1}为最低有效关键字。如果从最高有效关键字开始排序成为MSD排序,如果从最低有效关键字开始排序成为LSD排序。 例如,一个整数由若干位组成,且各位都有次序的,从而使其最右边的数原创 2015-11-14 20:11:18 · 1849 阅读 · 0 评论 -
生成树
生成树:如果连通图G的一个子图是一棵包含G的所有顶点的树,则该子图称为G的生成树(SpanningTree)。 生成树是连通图的包含图中的所有顶点的极小连通子图,图的生成树不惟一(极小子图是指边数最少的子图,任意一个具有n个顶点的连通图至少含有n-1条边,具有n-1条边的连通图必是一棵树,因此n个顶点的生成树包含n-1条边),从不同的顶点出发进行遍历,可以得到不同的生成树,当采用深度搜索构造生成原创 2015-09-30 10:53:26 · 2927 阅读 · 3 评论 -
等价关系
定义:集合S上的关系≡\equiv ,称为S上为等价关系,当且仅当它在S上是对称的,自反的,传递的。 例如:x=xx=y意味着y=xx=y且y=z意味着x=z 可以使用等价关系将集合S划分为等价类,S的两个元素x和y属于同一等价类,当且仅当≡\equiv ,例如,有12个编号为0至11元素: 0≡\equiv 4,3≡\equiv 1,6≡\equiv 10,8≡\equiv 9,7≡\原创 2015-08-21 02:03:30 · 7303 阅读 · 1 评论 -
双向链表
双向链表容易查找前驱和后驱的结点,在双向链表中至少有三个域:左链域,数据域,右链域,该结构如图: 根据上面的结构我们可以知道一条关系:ptr=ptr->llink->rlink=ptr->rlink->llink 该双向链表的头结点如图: 双向链表的插入和删除操作的代码如下:#include <iostream>#include<stdio.h>#include<stdlib.h>原创 2015-08-25 01:17:28 · 699 阅读 · 0 评论 -
树的基本概述
一个结点的度是指该结点的子树个数,而树的度是树中所有结点的度的最大值,数的层规定根结点为第一层,其他所有结点的层都是其父结点的层号加1,树的高度或深度是树中所有结点的最大层号。 二叉树的性质:在二叉树中,第i层的结点数最多为2i−12^{i-1},i>=1.在深度为k的二叉树中,结点总数最多为2k2^k-1,k>=1.对任何非空的二叉树T,如果叶结点的个数为 n0n_0,而度为2的结点数为原创 2015-08-27 13:30:21 · 501 阅读 · 0 评论 -
二叉树的遍历
假设有一颗这样的二叉树,该结构如图: 中序遍历:其遍历顺序为左——根——右,其上面二叉树的中序遍历的输出结果为:A/B*C*D+E,整个遍历过程函数调用了19次。 前序遍历:其遍历顺序为左——根——右,其上面二叉树的前序遍历的输出结果为:A/B*C*D+E,整个遍历过程函数也被调用了19次。 后序遍历:其遍历顺序为左——右——根,其上面二叉树的后序遍历的输出结果为:AB/C*D*E+,整个原创 2015-08-27 14:56:36 · 756 阅读 · 0 评论 -
二叉树的其他操作
二叉树一个较实用的操作就是二叉树的复制,而二叉树的复制可以在后序遍历基础上实现。 代码实现://二叉树的复制操作tree_pointer copy(tree_pointer original){ if(original) { tree_pointer temp=(tree_pointer)malloc(sizeof(node)); if(IS_FULL(te原创 2015-08-31 14:08:45 · 564 阅读 · 0 评论 -
线索二叉树
二叉树在连接存储表示中,空链的数目是大于非空链的数目,即在2n个空链中,有n+1个是空链,如果利用这些空链来指向二叉树其他结点的指针,这结点称为线索,具体建立线索树过程:如果结点的左儿子ptr->left_child为空,则在中序遍历中,用指向在ptr之前访问的结点的指针代替ptr->left_child,即用指向ptr的中序遍历的前驱结点的指针代替空链。如果结点的右儿子ptr->right_c原创 2015-08-31 16:53:33 · 782 阅读 · 0 评论 -
KMP匹配算法
KMP匹配算法是当模式串在字符串发生匹配时,而不用在字符串回溯一种模式匹配查询方法。 假设pat=’a b c a b c a c a b’,如果有si=a且si+1!=b,那么进行si+1与a的比较,如果sisi+1=ab且si+2!=c,则出现如下情况: s=’a b ? ? ?…..?’,符号”?”表示不知道s中此处字符是什么,在s中第一个”?”代表si+2且Si+2!=c, 因此,索搜的原创 2015-08-16 20:16:41 · 668 阅读 · 2 评论 -
动态链栈和动态链队列
动态链栈可以动态申请空间,它不像数组那样,存在有效的顺序储存,它是由一种链表数据结构搭建起来,故在插入和删除效率比数组搭建的方式要高,其链表构建的栈如图: 假设每个栈的初始状态是: top[i]=NULL,0<=i#include <iostream>#include<stdlib.h>#include<stdio.h>#define IS_FULL(ptr) (!(ptr))#de原创 2015-08-18 13:18:29 · 877 阅读 · 2 评论 -
二叉查找树
虽然在需要优先级队列的应用程序中,堆非常合适,但它并不适用删除任意元素的应用,从具有n个元素的堆中删除任意元素的时间开销为O(n),并且查询任意元素的时间开销也是O(n),因此当进行插入,删除和查找操作,二叉查找树的性能就非常的适合。 二叉查找树,具有如下性质:每个元素都有关键字,任意两个元素的关键字都不相同,即,关键字是唯一的。非空左子树的关键字值一定小于其子树根结点的关键字值。非空右子树原创 2015-09-08 09:12:18 · 1091 阅读 · 0 评论 -
堆
最大堆:是指在一颗完全二叉树中,一个结点的关键值都不小于其儿子结点的关键字值,既满足(parent.value>=parent->left_child.value&&parent.value>=parent->right_child.value.). 最小堆:是指在一颗完全二叉树中,一个结点的关键值都不大于其儿子结点的关键字值,既满足(parent->left_child.value>=paren原创 2015-09-03 02:09:06 · 965 阅读 · 0 评论 -
森林
森林是n>=0个互不相交的树的集合,如:二叉树删除一个根,就可以转换为森林。 如果T1,….Tn是一个森林,则对应于该森林的二叉树记为B(T1,…..,Tn),那么就有以下定义: 若n=0,森林就为空。 根为森林中第一颗树T1的根,左子树是B(T11,T12,…..,T1n),其中T11,T12,…..,T1n是T1根的所有子树,右子树是B(T2,…..,Tn)。 如: 因此森林的原创 2015-09-09 19:19:45 · 2095 阅读 · 1 评论 -
静态散列
散列基础知识在静态散列方法中,把标识存储在一个固定大小的表中,使用一个函数f确定标识符x在散列表中的地址(或位置),散列表ht存放在一片连续的内容空间中,该空间被分割为b个散列通:ht[0],….,ht[b-1],每个散列桶可以初始化s个槽,如果s=1,就意味着每个散列桶恰好可容纳一个记录。 如: 标识符的长度限定为6个字符,且第一个字符必须是字母,其余的字符可以是字母也可以是数字,那么,标识符原创 2015-11-18 14:42:54 · 2873 阅读 · 0 评论