数据结构与算法
文章平均质量分 88
C++实现的数据结构与算法,线性表,栈,队列,串,数组,广义表,树,图,排序算法,查找算法,递推算法,迭代算法,递归算法,枚举算法,贪心算法,回溯算法,实用算法等
凌空的桨
https://github.com/marsmarcin/
展开
-
排序算法2——折半插入排序
编写折半插入排序算法,对元素序列 75、61、82、36、99、26、41进行从小到大排序。【算法思想】折半插入排序算法是对直接插入排序的一种改进。主要思想是在查找插入位置过程中引入折半查找算法思想,利用折半查找法在有序集中确定待排序元素插入位置。【与直接插入排序的区别】*直接插入排序:从右到左按照顺序查找插入的位置。*折半插入排序:在有序集中查找插入的位置。【示例】假设有...原创 2019-07-04 22:11:10 · 9006 阅读 · 0 评论 -
排序算法1——直接插入排序
插入排序的算法思想是:将待排序元素分为两个部分,即已排序集合和未排序集合,每趟排序是从未排序集合中选择一个元素插入已排序集合中,使已排序集合仍然有序。重复上述过程,直到所有元素都有序为止。---直接插入排序编写算法,利用直接插入排序对元素序列17,46,32,87,58,9,50,38进行从小到大排序。【算法思想】直接插入排序是一种简单的插入排序。它的基本思想描述如下:#...原创 2019-07-03 21:44:13 · 1731 阅读 · 2 评论 -
图11——判断图中是否为一棵树
编写算法,判断一个无向图是否是一颗树。【分析】一个无向图G是一棵树的条件为:G必须是无回路的连通图或n-1条边的连通图,这里我们采用后者作为判断条件。例如下图所示:上面的无向图就是一棵树,它有6个顶点,5条边。code:#include<stdlib.h>#include<stdio.h>#include<malloc.h>#inc...原创 2019-06-29 20:46:30 · 4854 阅读 · 1 评论 -
图10——判断顶点u和顶点v是否存在简单路径
已有邻接表表示的有向图,编程判断从顶点u到顶点v是否存在简单路径若有,则打印出该路径上的顶点。要求先描述图中的存储结构,并简述算法思路;查找邻接顶点等图运算要自己实现(尽量采用非递归算法)【分析】这是浙江大学考研试题。主要考查图的广度优先遍历。通过从顶点u开始对图进行广度优先遍历,如果访问到顶点v,则说明从顶点u到顶点v存在一条路径。因为在图的遍历过程中,要求每个顶点只能访问一次,所以该路径...原创 2019-06-28 22:43:21 · 4914 阅读 · 2 评论 -
图9——求距离顶点v0的最短长度为k的所有顶点
设计算法求出无向连通区图中距离顶点v0的最短路径长度(最短路径长度以边数为单位计算)为K的所有顶点,要求尽可能的节省时间。【分析】这是西北大学考研试题。本题应用广度优先遍历求解,若以v0作为生成树的根为第1层,则距离顶点v0最短路径长度为K的顶点均在第K+1层。可用队列存放顶点,将遍历访问顶点的操作改为入队操作。队列中设头尾指针分别为f和r,用level表示层数。主要考查图的遍历。可以采...原创 2019-06-26 21:48:16 · 4899 阅读 · 0 评论 -
图8——判断有向图中是否有根
在有向图G中,如果r到G中每个结点都有路径可达,则称结点r为G的跟结点。编写一个算法判断有向图G中是否有根,如果有则打印出所有根节点的值。【分析】这是东北大学和浙江大学的考研试题。主要考查对图的深度优先搜索的理解。若从某结点出发可比案例到所有其他顶点,则该结点为根结点,否则不是根节点。对每个顶点遍历一次即可完成任务。code:#include <stdlib.h>#i...原创 2019-06-23 21:46:35 · 6616 阅读 · 2 评论 -
图7——图的广度优先遍历
假设一个无向图按照邻接表存储,编写一个广度优先搜索遍历的算法。【分析】定义一个数组visited[],用来标记顶点是否被访问。初始时,标志数组初始化为0,表示顶点未被访问。为1时,表示顶点已被访问。第一个顶点v0出发,访问该顶点位置并置visited[v0]为1,然后将v0入队。若队列不为空,将队头元素(顶点)出队,依次访问该顶点的所有邻接点,同时将这些顶点标记为已访问,并将其邻接顶点依次入...原创 2019-06-23 10:57:07 · 332 阅读 · 0 评论 -
图6——深度遍历无向图
设计一个递归算法,采用深度优先搜索对无向图进行遍历,并对算法中的无向图的存储结构予以简单的说明。这是大连理工考研试题。在深度优先的遍历过程中,图中可能存在回路,因此,在访问了某个顶点后,沿着某条路径遍历,有可能又回到该顶点。例如,对于下图中的无向图G在访问了顶点a之后,接着访问顶点b、e、h、i、f、j、d。因为d的邻接顶点是a,沿着<d,a>会再次访问顶点a。为了避免再次...原创 2019-06-22 21:18:29 · 1761 阅读 · 0 评论 -
图5——判断有向图中是否存在回路
假设以邻接矩阵作为图的结构,编写算法,判别在给定的有向图中是否存在一个简单的有向回路,若存在,则以顶点序列的方式输出该回路(找到一条即可)(注意:图中不存在顶点到自身的弧)这是清华大学的考研试题。为了判断有向图是否存在环,可以通过深度优先搜索的方法来实现。从编号0的顶点出发,若两个顶点间存在路径,则记录下源顶点标记为已访问(标记为-1)。在遍历的过程中,若有顶点与源顶点相同,则说明存在环。...原创 2019-06-22 09:32:13 · 23505 阅读 · 5 评论 -
图4——图的遍历(基本概念)
1.图的深度遍历图的深度优先遍历与树的深度优先遍历类似,是树的先根遍历的推广。图的深度优先遍历的思想是:从图中某个顶点v0出发,访问顶点v0的第一个邻接点,然后以该邻接点为新的顶点,访问该顶点的邻接点。重复执行以上操作,直到当前顶点没有邻接点为止。返回到上一个已经访问过且还有未被访问的邻接点的顶点,按照以上步骤继续访问该顶点的其他未被访问的邻接点。依此类推,直到图中所有的顶点都被访问过。图的...原创 2019-06-19 23:04:01 · 420 阅读 · 0 评论 -
图3——把邻接矩阵转换为邻接表
【分析】这是哈工大的考研题。由于有向图和无向图的邻接存储结构不同,并与带权图的存储存在一定差别,这里给出有向图的邻接矩阵到邻接表的转换。#include <stdio.h>#include <string.h>#include <malloc.h>#include <stdlib.h>#include <iostream>...原创 2019-06-18 18:34:53 · 8486 阅读 · 0 评论 -
图2——利用邻接表创建有向图
图2——利用邻接表创建有向图图假设以邻接表作为图的存储结构,编写算法,创建有向图并输出邻接表。主要考查对邻接表的理解。图的邻接表分为两个部分:表头结点和边表结点,因此创建有向图也分成两部分:一是创建表头结点,二是创建边表结点构成的边表。创建表头结点就是根据输入的结点信息,将结点信息直接存入对应的数据域中,并且将该结点的指针域置为NULL。for(int i=0;i<G-...原创 2019-04-05 19:42:58 · 15255 阅读 · 1 评论 -
图1——用邻接矩阵表示法创建有向图
图可分两部分:一个是创建顶点信息,可用一个一维数组存储;另一个是创建弧的信息,包括弧的相关顶点和权值,可存储到二维数组里,其中,二维数组的下标分别表示两个顶点的弧尾和弧头编号,权值存放在对应的数组中。创建一个网:请输入有向网N的顶点数和弧数:6 9请输入6个顶点的值:a b c d e f请分别输入9条弧的弧尾 弧头 权值(以空格分隔):a b 6a e 5a f 9f c 7...原创 2019-04-05 15:57:40 · 11513 阅读 · 0 评论 -
树12——构造哈夫曼树并输出哈夫曼编码
树12——哈夫曼树哈夫曼树为一组权值分别为2、4、7、15的结点序列构造一棵哈夫曼树,然后输出相应的哈夫曼编码。为了便于设计,可利用一个二维数组实现哈夫曼树的算法。因为需要保存字符的权重、双亲结点位置、左孩子结点位置和右孩子结点的位置。所以需要将数组设计成n行四列。因此,哈夫曼树的类型定义如下:typedef struct{ unsigned int weight;...原创 2019-04-04 21:00:23 · 28200 阅读 · 3 评论 -
树11——求根结点到任一结点之间的路径
树11——求根结点到任一结点之间的路径二叉树已知一棵二叉树用二叉树用二叉链表存储,t指向根结点,p指向树中任一结点,要求编写算法,输出从t到p之间路径上的结点。这是南京航空航天大学考研题,主要考查二叉树的后序遍历。由于后序遍历二叉树的过程中,访问到r所指结点时,此时栈中所有结点均为r所指的祖先,由这些祖先便构成了一条从根结点到r所指结点之间的路径,故可采用后序遍历。code:#...原创 2019-04-03 18:26:02 · 4324 阅读 · 1 评论 -
树10——求二叉树的高度和宽度
二叉树二叉树采用二叉链表存储。(1)编写计算整个二叉树高度的算法。(2)编写计算二叉树最宽的算法。二叉树的最大宽度是指二叉树左右层中结点个数的最大值。这是西北大学考研试题。二叉树的高度递归定义为:当二叉树为空时,其深度为0。当二叉树只有根结点时,即结点的左、右子树为空,二叉树的深度为1。其他情况下,二叉树的左、右子树高度的最大值再加1(根结点)就是二叉树的高度。求二叉树的最大...原创 2019-04-02 20:38:47 · 3016 阅读 · 0 评论 -
树9——求二叉树的结点个数
求二叉树的结点个数二叉树已知二叉树采用二叉链表存储,要求编写算法,完成计算二叉树中度为0和度为1的结点数目。这是西北大学考研题。求二叉树中度为0的结点个数即求叶子结点的个数,递归定义为:当二叉树为空时,叶子结点个数为0。当二叉树只有一个根结点时,根结点就是叶子结点,叶子结点个数为1。其他情况下,计算左子树与右子树中叶子结点的和。求二叉树中度为1的结点个数定义如下:当二...原创 2019-04-02 19:43:03 · 3428 阅读 · 0 评论 -
树8——判断是否为完全二叉树
判断是否为完全二叉树(1)写出一个建立二叉树的算法;(2)写出一个判别给定的二叉树是否为完全二叉树的算法。完全二叉树定义为:深度为K,具有N个结点的二叉树的每个结点都与深度为K的满足二叉树中编号为1~N的结点一一对应。这是西北大学考研试题。主要考察创建二叉树的算法思想及完全二叉树的性质。创建二叉树可以通过递归实现,可以利用先序输入顺序按照先序方式创建二叉树,也可以根据广义表输入方式创建二叉...原创 2019-04-01 09:51:04 · 944 阅读 · 0 评论 -
树7——交换二叉树的左右子树
交换二叉树的左右子树二叉树编写算法,要求实现以下功能:(1)写一个建立二叉树的算法,要求二叉树按照二叉链表存储;(2)已知二叉树用二叉链表存储,要求写出算法,实现将该二叉树左右子树交换。这是西北大学考研试题。例如,一颗二叉树在左右子树交换前后的情况如下图所示。这是西北大学考研试题。本题考查二叉树的建立算法思想和左右子树交换算法思想。左右子树交换可用递归实现,类似二叉树的先序...原创 2019-03-31 21:19:43 · 12593 阅读 · 2 评论 -
树6——由中序和后序序列构造二叉树
二叉树这是西北大学考研试题。我们知道,由先序序列和中序序列可以唯一地确定一棵二叉树,同样,由中序序列和后序序列也可以唯一地确定一棵二叉树。先来分析中序序列和后序序列有什么特点。根据二叉树遍历的递归定义,二叉树的后序遍历是先后序遍历左子树,然后后序遍历右子树,最后访问根结点。因此,在后序遍历的过程中,根结点位于后序序列的最后。在二叉树的中序遍历过程中,先中序遍历左子树,然后是根结点,左后遍历右子...原创 2019-03-31 20:37:39 · 10515 阅读 · 0 评论 -
树5——输出树的各条边
输出树的各条边普通树树采用孩子兄弟方式存放,结点结构为:其中fch表示表示指向第一个孩子,nsib表示指向下一个兄弟。编写算法,要求由根结点开始逐层输出树中的各条边,边输出格式为(Ki,Kj)。例如下图所示的树。这是西北大学考研题。这个题目主要考察考生对树的孩子兄弟表示法的理解和树的遍历算法设计思想。首先根据树结构画出孩子兄弟表示,其次再考虑如何按照以上顺序输出各条边。具体...原创 2019-03-30 20:19:54 · 1202 阅读 · 6 评论 -
树3——二叉树的先序遍历
二叉树的先序非递归遍历二叉树这是同济大学的考研试题。算法实现:从二叉树的根结点开始,访问根结点,然后将根结点的指针入栈,重复执行以下步骤:①如果该结点的左孩子结点存在,访问左孩子结点,则将左孩子结点指针入栈。重复执行操作直到结点的左孩子不存在;②将栈顶的元素(指针)出栈,如果该指针指向的右孩子结点存在,则将当前指针指向右孩子结点。重复执行以上两个步骤,直到栈空为止。如图所示的先序遍历...原创 2019-03-29 15:16:11 · 394 阅读 · 0 评论 -
树4——二叉树的层序遍历
这是西北大学的考研题。算法思想:定义一个队列queue,从二叉树的根结点开始,依次将每一层指向结点的指针入队。然后将队头元素出队,并输出该指针指向的结点值,如果该结点的左、右孩子不空,则将左右孩子结点的指针入队。重复执行以上操作,直到队空为止。最后得到的序列就是二叉树的层次输出序列。code:#include <stdio.h>#include <malloc.h&...原创 2019-03-29 16:30:51 · 242 阅读 · 0 评论 -
树2——创建二叉树及三种遍历(先序、中序、后序)
建立二叉树编写建立二叉树的算法,要求二叉树按照链式方式存储。 该题是西北大学考研题。可以按照先序序列的输入建立二叉树,即先输入根结点,然后是左子树,然后是右子树。输入时如果有左孩子(或右孩子)结点,则输入结点元素;如果没有,则输入“#”。例如对于下图的所示的二叉树,它的输入结点序列就是对应右边二叉树的先序遍历,即ABE##FG###D#G##。code:#includ...原创 2019-03-27 09:45:21 · 891 阅读 · 0 评论 -
树1——根据广义表形式创建二叉树
已知某二叉树采用广义表形式作为输入,请写一个非递归算法,建立二叉树的二叉链表存储结构。采用广义表形式表示二叉树的约定如下:(1)表中的一个字母表示一个结点的数据信息;(2)每个根节点作为由子树构成的表的名字放在表的前面;(3)每个结点的左子树与右子树之间用逗号分开;如果只有右子树而无左子树,则逗号不能省略;(4)整个广义表的末尾由一个特殊符号‘@’作为表的结束标志。A(B(D),C(F...原创 2019-03-26 21:37:09 · 21283 阅读 · 2 评论 -
广义表3——广义表的扩展线性链表表示
【结点结构】用扩展线性链表表示时,广义表也可以包含两种结点:表结点和原子结点,这两种结点都包含三个域。其中,表结点由标志域tag、表头指针域hp、表尾指针域tp构成:原子结点由指针域、原子的值域和表尾指针域构成。标志域tag用来区分当前结点是表结点还是原子结点,当tag=0时为原子结点,tag=1时为表结点;hp和tp分别指向广义表的表头和表尾;atom用来存储原子结点的值。扩展线性链表...原创 2018-12-21 19:10:19 · 3628 阅读 · 0 评论 -
广义表2——创建广义表
编写一个算法,使用头尾链表表示法创建广义表,并求该广义表的长度和深度。【分析】主要考察对广义表的头尾链表存储结构的表示及基本操作。因为广义表是递归定义的所以可以使用递归方法创建广义表、求广义表的表头元素、长度和深度。 SeqString.h#define MaxLen 255typedef struct{ char str[MaxLen]; int l...原创 2018-12-20 19:54:07 · 1544 阅读 · 0 评论 -
广义表1——基本内容
广义表与数组一样,广义表也是线性表的推广。它是一种递归定义的数据结构,但其数据元素的结构类型可以不同,其元素可以是普通元素,也可以是广义表。广义表被广泛应用于人工智能等领域的表处理语言Lisp中它把广义表作为基本的数据结构,就连程序也表示成一系列的广义表。【广义表的定义及头尾链表表示】广义表,简称表(lists),是由n个元素(a1,a2,a3,…,an)组成的有限序列。当n=0时称为空...原创 2018-12-19 22:09:23 · 1446 阅读 · 0 评论 -
数组12——稀疏矩阵的压缩存储2——稀疏矩阵的相加
设有两个4*4的稀疏矩阵A和B,相加得到C,如图所示,请编写算法,要求利用三元组表示法实现两个稀疏矩阵的相加,并用矩阵形式输出结果。 【分析】先比较两个稀疏矩阵的 先比较两个稀疏矩阵A和B的行号,如果行号相等,则比较列号;如果行号与列号都相等,则将对应的元素值相加,并将下标m与n下标都加1比较下一个元素;如果行号相等,列号不相等,则将列号较小的矩阵的元素赋给矩...原创 2018-12-18 21:12:13 · 1058 阅读 · 0 评论 -
数组11——稀疏矩阵的压缩存储1——基本内容
【定义】所谓稀疏矩阵,假设在m×n矩阵中,有t个元素不为零,令δ=t/(m×n),δ为矩阵的稀疏因子,如果δ≤0.05,则称矩阵为稀疏矩阵。通俗的来讲,若矩阵中大多数元素的值为零,只有很少的非零元素,这样的矩阵就是稀疏矩阵。如图就是一个稀疏矩阵【三元组表示】为了节省内存单元,需要对稀疏矩阵进行压缩存储。在进行压缩存储的过程中,我们可以只存储稀疏矩阵的非零元素,为了表示非零元素...原创 2018-12-17 19:30:29 · 1718 阅读 · 0 评论 -
数组10——数组的压缩存储2——上三角阵的压缩存储
编写一个算法,将一个以行为主序存储的一维数组转换为以列为主序压缩存储的一维数组。例如,设有n×n的上三角矩阵A的上三角元素已按行为主序连续存放在数组b中,请设计一个算法Trans将b中元素按列为主序存放在数组c中。当n=5时,矩阵A如图所示:其中b=(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15),c=(1,2,6,3,7,10,4,8,11,13,5,...原创 2018-12-16 20:37:40 · 6802 阅读 · 0 评论 -
数组9——数组的压缩存储1——基本内容
【压缩存储】有些高阶矩阵中,非零的元素非常少,此时若使用二维数组将造成存储空间的浪费,这时,可只存储部分元素,从而提高存储空间的利用率。通常的做法是为多个相同值的元素只分配一个存储单元,对值为零的元素不分配存储单元。这种存储方式称为矩阵的压缩存储。我们把非零元素非常少(远小于m×n)或元素分布呈一定规律的矩阵称为特殊矩阵。对称矩阵、三角矩阵和对角矩阵都属于特殊矩阵。【对称矩阵】如果一...原创 2018-12-15 19:34:38 · 2819 阅读 · 1 评论 -
数组8——二维数组6——打印蛇形方阵
打印蛇形方阵,将自然数1,2,··· ,N的平方按照蛇形方式依次存入N×N矩阵中。例如,N=5时的蛇形方阵如图所示。【分析】这是南京航空航天大学的考研试题。从a11开始到ann为止,依次填入自然数,交替对每一斜行从左上元素到右下元素或者从右下元素到左上元素填数。通过观察,发现蛇形矩阵有以下特点:对于每一斜行的元素来说:(1)对于奇数的斜行来说,下一个数的行号比上一个数的行号增1...原创 2018-12-14 18:27:40 · 2040 阅读 · 1 评论 -
数组7——二维数组5——打印拉丁方阵
打印拉丁方阵。N×N的拉丁方阵的每一行,每一列均为自然数1,2,3,... ,N的全排列,每一行和每一列均无重复数字。一个5×5的拉丁方阵如图所示【分析】生成拉丁方阵的方法如下:(1)第一行元素由随机数产生,从1开始,依次将自然数1--N填充到第一行,填入的列号由随机数产生。(2)以第一行作为方阵的索引,即如果第一行的第i个元素值为j,则a[0][j]在各行中的列号是在第一行...原创 2018-12-13 20:05:30 · 1685 阅读 · 0 评论 -
数组6——二维数组4——打印螺旋矩阵
打印一个螺旋矩阵。例如,一个5×5的螺旋矩阵如图【分析】通过观察,发现一个n×n的螺旋矩阵可以分为(n+1)/2圈,可以使用一个循环控制圈数。每圈的元素可以分为上、右、下、左4个方向,在内层循环中可以使用4个循环控制每圈的四个方向的元素输出。其中:△上:行号不变,列号依次增1;△右:行号依次增1,列号不变;△下:行号不变,列号依次减1;△左:行号依次减1,列号不变。mai...原创 2018-12-12 20:56:10 · 1516 阅读 · 0 评论 -
数组5——二维数组3——打印魔方阵
3阶的魔方阵在四千年前中国科学家就知道了,河图正是一个3阶魔方阵的例子。打印魔方阵。魔方阵,又称“纵横图”,是指组成元素为自然数1,2,... ,n^2的n×n的方阵,其中每个元素值都不相等,且每行,每列及主、副对角线上元素之和都相等。例如,3×3的魔方阵如图【分析】构造魔方阵的方法如下:(1)将1放在第一行中间一列;(2)从2开始直到n×n为止各数依次按照下列规则存放:每一...原创 2018-12-11 22:00:37 · 1200 阅读 · 0 评论 -
数组4——二维数组1——将矩阵顺时针旋转90度
【定义】二维数组也称为矩阵(Matrix),关于矩阵的算法经常在各种考试及面试中出现,它主要考查被测试者的逻辑思维能力、下标的灵活应用及对C语言的掌握程度,这种题目通常有较高的难度,通常需要二重循环实现。经典的矩阵算法有将矩阵旋转90度、魔方阵、拉丁方阵、蛇形方阵、内螺旋矩阵、外螺旋矩阵、逆螺旋矩阵。【问题】将矩阵顺时针旋转90度如图【分析】这题是北京航天大学考研试题。对于...原创 2018-12-10 21:27:40 · 11067 阅读 · 4 评论 -
数组3——将奇数移动到偶数的左边
将数组c[1:n]中的所有奇数移动到偶数之前,要求时间复杂度为O(n)。【分析】这是西北大学考研试题。设置两个指示器i和j,分别从第一个元素向右从最后一个元素开始向左扫描,i遇到奇数略过,遇到偶数暂停,j遇到偶数略过,遇到奇数暂停,如果i<j,则交换i和j指向的元素,直到i≥j将结束,这样左边的元素就为奇数,右边的元素就为偶数。 main.cpp#include <...原创 2018-12-09 16:19:59 · 499 阅读 · 0 评论 -
数组2——查找第k小元素
在数组a的前n个元素中找出第k(1≤k≤n)小的元素,例如,数组{98, 33, 21, 102, 45, 5, 32, 11, 65, 82, 193, 321, 34, 72}中第5小的元素是33。【分析】这是上海大学考研试题。要查找第k小的元素,并不需要完全对数组中的元素进行排序,可以利用快速排序算法思想,只对部分元素进行排序就可以找到第k小元素。一趟排序结束后,若i==k,说明找...原创 2018-12-08 21:13:50 · 2647 阅读 · 0 评论 -
数组1——数组的定义及表示
前面介绍的线性表、栈、队列和串都属于线性结构,本章的数组和下一章的广义表并不属于线性结构,但可以看作是线性结构的推广。数组中的元素可以具有某种元素,并且元素的结构相同。数组中的数据元素可以上单个元素,也可以是一个线性表。数组的定义及表示【定义】数组(array)是由类型相同的数据元素构成的有序集合,每个元素称为一个数组元素,数组中的元素依次存储在n个连续内存单元中。数组中的元素本身可以...原创 2018-12-08 20:05:55 · 4333 阅读 · 0 评论