数据结构、算法分析与设计
文章平均质量分 71
Winston_wu
㊣
展开
-
字符串循环右移(一道面试题的代码实现)
#include void revStr(char* arr, const size_t N ){ for(int i=0;i char tmp = arr[i]; arr[i]=arr[N-1-i]; arr[N-1-i]=tmp; } } void moveStr(char* arr, const size_t N, const size_t K){原创 2013-04-17 20:21:10 · 678 阅读 · 0 评论 -
有向图的强连通分量
求有向图G的强连通分量的基本步骤是:⑴ 对G进行深度优先遍历,生成G的深度优先生成森林T。⑵ 对森林T的顶点按中序遍历顺序进行编号。⑶ 改变G中每一条弧的方向,构成一个新的有向图G’。⑷ 按⑵中标出的顶点编号,从编号最大的顶点开始对G’进行深度优先搜索,得到一棵深度优先生成树。若一次完整的搜索过程没有遍历G’的所有顶点,则从未访问的顶点中选择一个编号最大的顶点,由它开始再进行原创 2011-12-14 13:27:14 · 456 阅读 · 0 评论 -
无向图的生成树和生成森林算法
对图的深度优先搜索遍历DFS(或BFS)算法稍作修改,就可得到构造图的DFS生成树算法。 在算法中,树的存储结构采用孩子—兄弟表示法。首先建立从某个顶点V出发,建立一个树结点,然后再分别以V的邻接点为起始点,建立相应的子生成树,并将其作为V 结点的子树链接到V结点上。显然,算法是一个递归算法。(1) DFStree算法typedef struct CSNode{原创 2011-12-14 13:26:20 · 2377 阅读 · 0 评论 -
图的邻接矩阵的操作
图的邻接矩阵的实现比较容易,定义两个数组分别存储顶点信息(数据元素)和边或弧的信息(数据元素之间的关系) 。其存储结构形式定义如下:#define INFINITY MAX_VAL /* 最大值∞ */ /* 根据图的权值类型,分别定义为最大整数或实数 */#define MAX_VEX 30 /* 最大顶点数目 */typedef enum {DG,原创 2011-12-14 13:24:07 · 598 阅读 · 0 评论 -
线索化二叉树
仿照线性表的存储结构,在二叉树的线索链表上也添加一个头结点head,头结点的指针域的安排是: ◆ Lchild域:指向二叉树的根结点; ◆ Rchild域:指向中序遍历时的最后一个结点; ◆ 二叉树中序序列中的第一个结点Lchild指针域和最后一个结点Rchild指针域均指向头结点head。如同为二叉树建立了一个双向线索链表,对一棵线索二叉树既可从头结点也可从最后一个结点开始按寻找原创 2011-12-14 13:23:16 · 328 阅读 · 0 评论 -
二叉树的二叉链表创建
⑴ 按满二叉树方式建立 (补充) 在此补充按满二叉树的方式对结点进行编号建立链式二叉树。对每个结点,输入i、ch。i : 结点编号,按从小到大的顺序输入;ch : 结点内容,假设是字符。在建立过程中借助一个一维数组S[n] ,编号为i的结点保存在S[i]中。#define MAX_NODE 50typedef struct BTNode{ char原创 2011-12-14 13:21:48 · 1742 阅读 · 0 评论 -
遍历二叉树及其应用
先序遍历二叉树1 递归算法void PreorderTraverse(BTNode *T){ if (T!=NULL) { visit(T->data) ; /* 访问根结点 */ PreorderTraverse(T->Lchild原创 2011-12-14 13:20:56 · 406 阅读 · 0 评论 -
串
#define MAX_STRLEN 256typedef struct{ char str[MAX_STRLEN] ; int length;} StringType ; 1 串的联结操作Status StrConcat ( StringType s, StringType t)/* 将串t联结到串s之原创 2011-12-14 13:19:13 · 418 阅读 · 0 评论 -
冒泡排序
1 排序思想依次比较相邻的两个记录的关键字,若两个记录是反序的(即前一个记录的关键字大于后前一个记录的关键字),则进行交换,直到没有反序的记录为止。① 首先将L->R[1]与L->R[2]的关键字进行比较,若为反序(L->R[1]的关键字大于L->R[2]的关键字),则交换两个记录;然后比较L->R[2]与L->R[3]的关键字,依此类推,直到L->R[n-1]与L->R[n]的关键字比原创 2011-12-15 12:34:12 · 459 阅读 · 0 评论 -
希尔排序
希尔排序(Shell Sort,又称缩小增量法)是一种分组插入排序方法。1 排序思想① 先取一个正整数d1(d1② 取新的增量d2 2 排序示例设有10个待排序的记录,关键字分别为9, 13, 8, 2, 5, 13, 7, 1, 15, 11,增量序列是5, 3, 1,希尔排序的过程如图10-5所示。 3 算法实现先给出一趟希尔排序的算法,类似原创 2011-12-15 12:33:43 · 535 阅读 · 0 评论 -
有向无环图及其应用
有向无环图(Directed Acycling Graph):是图中没有回路(环)的有向图。对工程的活动加以抽象:图中顶点表示活动,有向边表示活动之间的优先关系,这样的有向图称为顶点表示活动的网(Activity On Vertex Network ,AOV网) 。拓扑排序由某个集合上的一个偏序得到该集合上的一个全序的操作。算法实现说明◆ 采用正邻接链作为AOV网的存储结构;原创 2011-12-15 12:26:12 · 711 阅读 · 0 评论 -
顺序查找(Sequential Search)
1 查找思想从表的一端开始逐个将记录的关键字和给定K值进行比较,若某个记录的关键字和给定K值相等,查找成功;否则,若扫描完整个表,仍然没有找到相应的记录,则查找失败。顺序表的类型定义如下:#define MAX_SIZE 100typedef struct SSTable{ RecType elem[MAX_SIZE] ; /* 顺序表原创 2011-12-15 12:27:56 · 1035 阅读 · 0 评论 -
折半查找(Binary Search)
前提条件:查找表中的所有记录是按关键字有序(升序或降序) 。1 查找思想用Low、High和Mid表示待查找区间的下界、上界和中间位置指针,初值为Low=1,High=n。⑴ 取中间位置Mid:Mid=(Low+High)/2 ;⑵ 比较中间位置记录的关键字与给定的K值:① 相等: 查找成功;② 大于:待查记录在区间的前半段,修改上界指针: High=Mid-原创 2011-12-15 12:28:20 · 451 阅读 · 0 评论 -
几个常见排序算法的代码实现(复习)
#include#define ARR_SIZE 20 #include using namespace std; void printArr(int arr[], int count){ for(int i = 0;i printf("%d ",arr[i]); } print原创 2013-04-14 14:41:59 · 524 阅读 · 0 评论 -
Coding一下“反转单链表”,当是下周面试的练笔
#include using namespace std;typedef char DataType; //分号 struct LinkNode{ DataType data; LinkNode* next;};void PrintLinkList(const LinkNode* l);LinkNode* InitLinkList(DataT原创 2012-04-15 15:19:07 · 344 阅读 · 0 评论 -
多关键字排序
设有n个记录{R1, R2, …,Rn},每个记录Ri的关键字是由若干项(数据项)组成,即记录Ri的关键字Key是若干项的集合: {Ki1, Ki2, …,Kid}(d>1) 。记录{R1, R2, …,Rn}有序的,指的是"i, j∈[1,n],i{Ki1, Ki2, …Kid} 多关键字排序思想先按第一个关键字K1进行排序,将记录序列分成若干个子序列,每个子序列有相同的K1值;原创 2011-12-16 12:25:52 · 1237 阅读 · 0 评论 -
归并排序
排序思想① 初始时,将每个记录看成一个单独的有序序列,则n个待排序记录就是n个长度为1的有序子序列;② 对所有有序子序列进行两两归并,得到én/2ù个长度为2或1的有序子序列——一趟归并;③ 重复② ,直到得到长度为n的有序序列为止。上述排序过程中,子序列总是两两归并,称为2-路归并排序。其核心是如何将相邻的两个子序列归并成一个子序列。设相邻的两个子序列分别为:{R[k]原创 2011-12-16 12:25:20 · 362 阅读 · 0 评论 -
各种内部排序的比较
各种内部排序按所采用的基本思想(策略)可分为:插入排序、交换排序、选择排序、归并排序和基数排序,它们的基本策略分别是:1 插入排序:依次将无序序列中的一个记录,按关键字值的大小插入到已排好序一个子序列的适当位置,直到所有的记录都插入为止。具体的方法有:直接插入、表插入、2-路插入和shell排序。2 交换排序:对于待排序记录序列中的记录,两两比较记录的关键字,并对反序的两个记录进行交换原创 2011-12-16 12:26:23 · 391 阅读 · 0 评论 -
简单选择排序
简单选择排序(Simple Selection Sort ,又称为直接选择排序)的基本操作是:通过n-i次关键字间的比较,从n-i+1个记录中选取关键字最小的记录,然后和第i个记录进行交换,i=1, 2, … n-1 。1 排序示例 例:设有关键字序列为:7, 4, -2, 19, 13, 6,直接选择排序的过程如下图10-8所示。 2 算法实现void sim原创 2011-12-15 12:34:46 · 492 阅读 · 0 评论 -
2-路插入排序
是对折半插入排序的改进,以减少排序过程中移动记录的次数。附加n个记录的辅助空间,方法是:① 另设一个和L->R同类型的数组d,L->R[1]赋给d[1],将d[1]看成是排好序的序列中中间位置的记录;② 分别将L->R[ ]中的第i个记录依次插入到d[1]之前或之后的有序序列中,具体方法: ◆ L->R[i].keyR[i]插入到d[1]之前的有序表中;◆ L->R[i].ke原创 2011-12-15 12:33:20 · 1261 阅读 · 0 评论 -
B_树(多路平衡查找树)
B_树主要用于文件系统中,在B_树中,每个结点的大小为一个磁盘页,结点中所包含的关键字及其孩子的数目取决于页的大小。一棵度为m的B_树称为m阶B_树,其定义是:一棵m阶B_树,或者是空树,或者是满足以下性质的m叉树:⑴ 根结点或者是叶子,或者至少有两棵子树,至多有m棵子树;⑵ 除根结点外,所有非终端结点至少有m/2棵子树,至多有m棵子树; ⑶ 所有叶子结点都在树的同一层上;原创 2011-12-15 12:31:19 · 763 阅读 · 0 评论 -
Fibonacci查找
Fibonacci查找方法是根据Fibonacci数列的特点对查找表进行分割。Fibonacci数列的定义是:F(0)=0,F(1)=1,F(j)=F(j-1)+F(j-2) 。 1 查找思想设查找表中的记录数比某个Fibonacci数小1,即设n=F(j)-1。用Low、High和Mid表示待查找区间的下界、上界和分割位置,初值为Low=1,High=n。⑴ 取分割位置原创 2011-12-15 12:29:19 · 904 阅读 · 0 评论 -
平衡二叉树(AVL)
平衡二叉树的定义平衡二叉树或者是空树,或者是满足下列性质的二叉树。⑴:左子树和右子树深度之差的绝对值不大于1;⑵:左子树和右子树也都是平衡二叉树。 平衡因子(Balance Factor) :二叉树上结点的左子树的深度减去其右子树深度称为该结点的平衡因子。 因此,平衡二叉树上每个结点的平衡因子只可能是-1、0和1,否则,只要有一个结点的平衡因子的绝对值大于1, 该二原创 2011-12-15 12:30:42 · 380 阅读 · 0 评论 -
BST树的删除
1 删除操作过程分析 从BST树上删除一个结点,仍然要保证删除后满足BST的性质。设被删除结点为p,其父结点为f ,删除情况如下:① 若p是叶子结点: 直接删除p。 ② 若p只有一棵子树(左子树或右子树):直接用p的左子树(或右子树)取代p的位置而成为f的一棵子树。即原来p是f的左子树,则p的子树成为f的左子树;原来p是f的右子树,则p的子树成为f的右子树。 ③ 若p既原创 2011-12-15 12:30:11 · 1813 阅读 · 1 评论 -
普里姆(Prim)算法
从连通网N=(U,E)中找最小生成树T=(U,TE) 。⑴ 若从顶点v0出发构造,U={v0},TE={};⑵ 先找权值最小的边(u,v),其中u∈U且v∈V-U,并且子图不构成环,则U= U∪{v},TE=TE∪{(u,v)} ;⑶ 重复⑵ ,直到U=V为止。则TE中必有n-1条边, T=(U,TE)就是最小生成树。设用邻接矩阵(二维数组)表示图,两个顶点之间不存在边的权值为机内原创 2011-12-14 13:27:41 · 551 阅读 · 0 评论 -
层次遍历二叉树
为保证是按层次遍历,必须设置一个队列,初始化时为空。设T是指向根结点的指针变量,层次遍历非递归算法是:若二叉树为空,则返回;否则,令p=T,p入队; ⑴ 队首元素出队到p; ⑵访问p所指向的结点; ⑶将p所指向的结点的左、右子结点依次入队。直到队空为止。#define MAX_NODE 50void LevelorderT原创 2011-12-14 13:21:23 · 352 阅读 · 0 评论 -
二叉树的性质
性质1:在非空二叉树中,第i层上至多有2i-1个结点(i≧1)。性质2:深度为k的二叉树至多有2k-1个结点(k≧1) 。性质3:对任何一棵二叉树,若其叶子结点数为n0,度为2的结点数为n2,则n0=n2+1。 满二叉树和完全二叉树 一棵深度为k且有2k-1个结点的二叉树称为满二叉树(Full Binary Tree)。 完全二叉原创 2011-12-14 13:20:01 · 485 阅读 · 0 评论 -
栈的链式存储表示
typedef struct Stack_Node{ ElemType data ; struct Stack_Node *next ;} Stack_Node ; (1) 栈的初始化Stack_Node *Init_Link_Stack(void){ Stack_Node *top ;原创 2011-12-14 13:18:05 · 365 阅读 · 0 评论 -
线性表的链式存储结构
typedef struct Lnode{ ElemType data; /*数据域,保存结点的值 */ struct Lnode *next; /*指针域*/}LNode; /*结点的类型 */ 1 建立单链表⑴ 头插入法建表LNode *create_LinkList(void) /* 头原创 2011-12-14 13:16:29 · 674 阅读 · 0 评论 -
直接插入排序
将待排序的记录Ri,插入到已排好序的记录表R1, R2 ,…., Ri-1中,得到一个新的、记录数增加1的有序表。 直到所有的记录都插入完为止。设待排序的记录顺序存放在数组R[1…n]中,在排序的某一时刻,将记录序列分成两部分:◆ R[1…i-1]:已排好序的有序部分;◆ R[i…n]:未排好序的无序部分。显然,在刚开始排序时,R[1]是已经排好序的。 2 算法实现v原创 2011-12-15 12:32:49 · 329 阅读 · 0 评论 -
克鲁斯卡尔(Kruskal)算法
设G=(V, E)是具有n个顶点的连通网,T=(U, TE)是其最小生成树。初值:U=V,TE={} 。对G中的边按权值大小从小到大依次选取。⑴ 选取权值最小的边(vi,vj),若边(vi,vj)加入到TE后形成回路,则舍弃该边(边(vi,vj) ;否则,将该边并入到TE中,即TE=TE∪{(vi,vj)} 。⑵ 重复⑴ ,直到TE中包含有n-1条边为止。Kruskal算法实现的关原创 2011-12-15 12:25:41 · 708 阅读 · 0 评论 -
邻接链表法操作图
结点及其类型定义#define MAX_VEX 30 /* 最大顶点数 */typedef int InfoType;typedef enum {DG, AG, WDG,WAG} GraphKind ;typedef struct LinkNode{ int adjvex ; // 邻接点在头结点数组中的位置(下标)原创 2011-12-14 13:24:54 · 927 阅读 · 0 评论 -
求二叉树的叶子结点数
只要将先序遍历二叉树算法中vist()函数简单地进行修改就可以。#define MAX_NODE 50int search_leaves( BTNode *T){ BTNode *Stack[MAX_NODE] ,*p=T; int top=0, num=0; if (T!=NULL) {原创 2011-12-14 13:22:11 · 981 阅读 · 0 评论 -
单源点最短路径
单源点最短路径对于给定的有向图G=(V,E)及单个源点Vs,求Vs到G的其余各顶点的最短路径。针对单源点的最短路径问题,Dijkstra提出了一种按路径长度递增次序产生最短路径的算法,即迪杰斯特拉(Dijkstra)算法。基本思想:从图的给定源点到其它各个顶点之间客观上应存在一条最短路径,在这组最短路径中,按其长度的递增次序,依次求出到不同顶点的最短路径和路径长度。即按长度递增的次序生原创 2011-12-15 12:27:25 · 700 阅读 · 0 评论 -
B+树
在实际的文件系统中,基本上不使用B_树,而是使用B_树的一种变体,称为m阶B+树。 它与B_树的主要不同是叶子结点中存储记录。在B+树中,所有的非叶子结点可以看成是索引,而其中的关键字是作为“分界关键字”,用来界定某一关键字的记录所在的子树。一棵m阶B+树与m阶B_树的主要差异是:⑴ 若一个结点有n棵子树,则必含有n个关键字;⑵ 所有叶子结点中包含了全部记录的关键字信息以及这些关键字记录的原创 2011-12-15 12:31:49 · 357 阅读 · 0 评论 -
哈希(散列)查找
基本思想:在记录的存储地址和它的关键字之间建立一个确定的对应关系;这样,不经过比较,一次存取就能得到所查元素的查找方法。哈希函数通常是一种压缩映象,所以冲突不可避免,只能尽量减少;当冲突发生时,应该有处理冲突的方法。设计一个散列表应包括:① 散列表的空间范围,即确定散列函数的值域;② 构造合适的散列函数,使得对于所有可能的元素(记录的关键字),函数值均在散列表的地址空间范围内,且出原创 2011-12-15 12:32:21 · 563 阅读 · 0 评论 -
BST树的查找
BST树的查找1 查找思想首先将给定的K值与二叉排序树的根结点的关键字进行比较:若相等: 则查找成功;① 给定的K值小于BST的根结点的关键字:继续在该结点的左子树上进行查找;② 给定的K值大于BST的根结点的关键字:继续在该结点的右子树上进行查找。2 算法实现⑴ 递归算法BSTNode *BST_Serach(BSTNode *T , KeyType ke原创 2011-12-15 12:29:47 · 623 阅读 · 0 评论 -
分块查找
分块查找(Blocking Search)又称索引顺序查找,是前面两种查找方法的综合。1 查找表的组织① 将查找表分成几块。块间有序,即第i+1块的所有记录关键字均大于(或小于)第i块记录关键字;块内无序;② 在查找表的基础上附加一个索引表,索引表是按关键字有序的,索引表中记录的构成是:最大关键字+起始指针;2 查找思想先确定待查记录所在块,再在块内查找(顺序查找)。3原创 2011-12-15 12:28:40 · 555 阅读 · 0 评论 -
与AOE有关的研究问题
与AOE有关的研究问题◆ 完成整个工程至少需要多少时间?◆ 哪些活动是影响工程进度(费用)的关键? 工程完成最短时间:从起点到终点的最长路径长度(路径上各活动持续时间之和) 。长度最长的路径称为关键路径,关键路径上的活动称为关键活动。关键活动是影响整个工程的关键。 设v0是起点,从v0到vi的最长路径长度称为事件vi的最早发生时间,即是以vi为尾的所有活动的最早原创 2011-12-15 12:26:50 · 669 阅读 · 0 评论 -
广度优先搜索算法
广度优先搜索(Breadth First Search--BFS)遍历类似树的按层次遍历的过程。设初始状态时图中的所有顶点未被访问,则:⑴:从图中某个顶点vi出发,访问vi;⑵:访问vi的所有相邻接且未被访问的所有顶点vi1,vi2,…,vim;⑶:以vi1,vi2, …,vim的次序,以vij(1≦j≦m)依此作为vi ,转⑴; ⑷:继续选取图中未被访问顶点vk作为起始顶点原创 2011-12-14 13:25:51 · 411 阅读 · 0 评论