算法分析与数据结构
文章平均质量分 79
张十五
这个作者很懒,什么都没留下…
展开
-
散列(Hash)
散列表的实现常称为散列(hashing)。散列是一种用于以常数平均时间执行插入、删除和查找的技术。但是,那些需要元素间任何排序信息的操作将不会得到有效的支持。因此,诸如findMin、findMax以及在线性时间内按顺序打印整个表的操作都是散列表所不支持的。基本概念理想的散列表数据结构只不过是一个包含一些项的具有固定大小的数组。查找一般是对项的某个部分(即数据成员)进行,这部分称为键(key)。例如,项可以由字符串(它可以作为键)和附加的数据成员组成。我们把表的大小记作TableSize,并将其理解为原创 2021-11-04 12:35:26 · 2469 阅读 · 0 评论 -
树.(三)
本篇主要介绍一下常用的树结构二叉树每个结点至多拥有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。二叉树的性质1.若二叉树的层次从0开始,则在二叉树的第i层至多有2i个结点(i>=0)2.高度为k的二叉树最多有2(k+1) - 1个结点(k>=-1)(空树的高度为-1)3.对任何一棵二叉树,如果其叶子结点(度为0)数为m,度为2的结点数为n ,则m - n + 1满二叉树除叶子节点外,所有节点都有左右两孩子完全二叉树如果对满二叉树原创 2021-11-02 14:56:16 · 73 阅读 · 0 评论 -
树.(二)
线索二叉树线索二叉树原理我们现在提倡节约型社会,一切都应该节约为本。对待我们的程序当然也不例外,能不浪费的时间或空间,都应该考虑节省。我们先来观察一颗二叉树,会发现指针域并不是都充分的利用了,有许许多多的“^”,也就是空指针域的存在,这实在不是好现象,应该要想办法利用起来。在二叉链表上,我们只能知道每个结点指向其左右孩子结点的地址,而不知道某个结点的前驱是谁,后继是谁。要想知道,必须遍历一次。以后每次需要知道时,都必须先遍历一次。为什么不考虑在创建时就记住这些前驱和后继呢,那将是多大的时间上的节省。原创 2021-11-02 13:43:43 · 197 阅读 · 0 评论 -
树.(一)
树的定义树(tree)可以用几种方式定义。定义树的一种自然的方式是递归的方法。一棵树是一些结点的集合。这个集合可以是空集;若不是空集,则树由称作根(root)的结点r以及零个或多个非空的(子)树T,T2,…,T组成,这些子树中每一棵的根都被来自根r的一条有向的边(edge)所连接。每一棵子树的根叫作根r的儿子(child),而r是每一棵子树的根的父亲(parent)。从递归定义中可以发现,一棵树是N个结点和N-1条边的集合,其中的一个结点叫作根。存在N-1条边的结论是由下面的事实得出的:每条边都将某个原创 2021-10-27 20:07:34 · 123 阅读 · 0 评论 -
排序(三)
堆排序堆排序(Heap Sort)就是利用堆(假设利用大顶堆)进行排序的方法。它的基本思想是,将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根结点。将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次小值。如此反复执行,便能得到一个有序序列了。void Heapify(ElemType* arr, int size ,int pos = 0){ while (pos * 2 + 1 <原创 2021-10-26 17:50:48 · 77 阅读 · 0 评论 -
排序(二)
希尔排序谢尔排序使用一个序列h1, h2,… ,hi,叫作增量序列(increment sequence)。只要h= 1,任何增量序列都是可行的,不过,有些增量序列比另外一些增量序列更好。在使用增量h的一趟排序之后,对于每一个i我们有a[i]≤a[i +h],所有相隔h的元素都被排序。h排序的一般做法是,对于h, h+1,…,N-1中的每一个位置i,把其上的元素放到i, i -h, i-2h,…中间的正确位置上。虽然这并不影响最终结果,但是仔细的观察显示出,一趟h排序的作用就是对h个独立的子数组执行一次原创 2021-10-25 21:31:39 · 108 阅读 · 0 评论 -
排序(一)
排序的基本概念排序是我们生活中经常会面对的问题。同学们做操时会按照从矮到高排列;老师查看上课出勤情况时,会按学生学号顺序点名;高考录取时,会按成绩总分降序依次录取等。那排序的严格定义是什么呢?假设含有n个记录的序列为{r1,r2……rn},其相应的关键字分别为{k1,k2……,kn},需确定1,2,……,n的一种排列 p1,p2……pn,使其相应的关键字满足kp1≤kp2≤……≤kpn(非递减或非递增)关系,即使得序列成为一个按关键字有序的序列rp1,rp2……rpn},这样的操作就称为排序。这里关键原创 2021-10-24 16:36:42 · 75 阅读 · 0 评论 -
堆
堆我们一般所说的堆,指的是二叉堆,数据结构(严蔚敏)是这样定义的。除二叉堆以外也有很多种类的堆,d堆,左氏堆,斜堆等我们可用一个数组来表示二叉堆很显然的完全二叉树优先队列(priority_queue)什么是优先队列呢?在优先队列中,元素被赋予优先级,当访问元素时,具有最高级优先级的元素先被访问。即优先队列具有最高级先出的行为特征。它可以说是队列和排序的完美结合体,不仅可以存储数据,还可以将这些数据按照我们设定的规则进行排序。我们可以结合二叉堆与队列的思想,用一个数组(队列)来实现一个优先原创 2021-10-23 22:09:49 · 63 阅读 · 0 评论 -
双向队列
双向队列(deque)故名思意,就是不论从那边看都是一个队列。(我觉得像是两个栈,栈底拼在一起),两端都能进行插入和删除。双向队列也是基于线性表的,因此数组和链表都可以实现它,在此我就仅用链表实现一下。typedef int ELemType; //用int来模拟数据项类型typedef struct Node//数据节点{ ELemType data; struct Node* pre; struct Node* next;}*DuList;typedef struct{ in原创 2021-10-23 17:42:38 · 2575 阅读 · 0 评论 -
队
队的定义队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的-端称为队尾,允许删除的一端称为队头。假设队列是q= ( a1,a2,……,an),那么a就是队头元素,而 an是队尾元素。这样我们就可以删除时,总是从a1开始,而插入时,列在最后。这也比较符合我们通常生活中的习惯,排在第一个的优先出列,最后来的当然排在队伍最后。如同栈的情形一样,对于队列而言任何表的实现都是合法的。像栈一样原创 2021-10-23 12:01:36 · 67 阅读 · 0 评论 -
栈
栈的定义栈(stack)是限定仅在表尾进行插入和删除操作的线性表。我们把允许插入和删除的一端称为栈顶( top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构。理解栈的定义需要注意:首先它是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系。只不过它是一种特殊的线性表而已。定义中说是在线性表的表尾进行插入和删除操作,这里表尾是指栈顶,而不是栈底。它的特殊之处就在于限制了这个线性表的插入和删除位置原创 2021-10-22 21:48:15 · 110 阅读 · 0 评论 -
循环链表,双向链表
循环链表对于单链表,由于每个结点只存储了向后的指针,到了尾标志就停止了向后链的操作,这样,当中某一结点就无法找到它的前驱结点了,不能回到从前。将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环链表,简称循环链表( circuar linked list)。循环链表解决了一个很麻烦的问题。如何从当中一个结点出发,访问到链表的全部结点。为了使空链表与非空链表处理一致,我们通常设一个头结点,当然,这并不是说,循环链表一定要头结点,这需要注意。循环链表带原创 2021-10-22 16:49:09 · 311 阅读 · 0 评论 -
线性表的链式存储结构
单链表(线性表的链式存储)顺序存储结构不足的解决办法前面我们讲的线性表的顺序存储结构。它是有缺点的,最大的缺点就是插入和删除时需要移动大量元素,这显然就需要耗费时间。能不能想办法解决呢?要解决这个问题,我们就得考虑一下导致这个问题的原因。为什么当插入和删除时,就要移动大量元素,仔细分析后,发现原因就在于相邻两元素的存储位置也具有邻居关系。它们编号是1,2,3,…, n,它们在内存中的位置也是挨着的,中间没有空隙,当然就无法快速介入,而删除后,当中就会留出空隙,自然需要弥补。问题就出在这里。使用数组原创 2021-10-22 15:11:36 · 2365 阅读 · 0 评论 -
线性表的顺序存储结构
顺序存储定义说这么多的线性表,我们来看看线性表的两种物理结构的第一种——顺序存储结构。线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。线性表(a1,a2……,an)的顺序存储示意图如下:顺序存储方式线性表的顺序存储结构,说白了,就是在内存中找了块地儿,通过占位的形式,把一定内存空间给占了,然后把相同数据类型的数据元素依次存放在这块空地中。既然线性表的每个数据元素的类型都相同,所以可以用C语言(其他语言也相同)的一维数组来实现顺序存储结构,即把第一个数据元素存到数组下标原创 2021-10-22 13:06:16 · 3390 阅读 · 0 评论 -
线性表
定义线性表,从名字上你就能感觉到,是具有像线一样的性质的表。线性表的数据对象集合为{a1,a2. …… an },每个元素的类型均为DataType(简单起见,我们以后都用int)在较复杂的线性表中,一个数据元素可以由若干个数据项组成。其中,除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。线性表(List ):零个或多个数据元素的有限序列。这里需要强调几个关键的地方。首先它是一个序列。也就是说,元素原创 2021-10-21 22:04:31 · 188 阅读 · 0 评论 -
数据结构的基本概念和术语
数据数据:是描述客观事物的符号,是对客观事物的逻辑归纳,是用于表示客观事物的未经加工的原始素材。是计算机中可以操作的对象,是能被计算机识别,并输入给计算机处理的符号集合。数据不仅仅包括整型、实型等数值类型,还包括字符及声音、图像、视频等非数值类型。在计算机系统中,数据以二进制信息单元0、1的形式表示。在计算机科学中,数据是所有能输入计算机并能被计算机程序处理的符号的介质的总称,是用于输入电子计算机进行处理,具有一定意义的数字、字母、符号和模拟量等的通称。数据元素它是数据的基本单位,数据元素也叫做结原创 2021-10-21 21:30:37 · 354 阅读 · 0 评论 -
算法效率的度量方法
算法是为求解一个问题需要遵循的,被清楚地指定的简单指令的集合。对于一个问题,一旦某种算法给定并且(以某种方式)被确定是正确的,那么重要的一步就是确定该算法将需要多少诸如时间或空间等资源量的问题。如果一个问题的求解算法竟然需要长达一年时间,那么这种算法就很难能有什么用处。同样,一个需要几吉字节(gigabyte)内存的算法在当前的大多数机器上也是没法使用的。事后统计方法这种方法主要是通过设计好的测试程序和数据,利用计算机计时器对不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。但这种方法显然原创 2021-10-21 20:43:11 · 1003 阅读 · 0 评论