
数据结构与算法
文章平均质量分 83
学习严蔚敏《数据结构》全程实录。
rowandjj
阿里巴巴资深移动开发工程师
展开
-
希尔排序
希尔排序(Shell Sort)是插入排序的一种。是针对直接插入排序算法的改进。该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2希尔排序是基于插入排序的以下两点性质而提出改进方法的:1.插入排序在对几乎已原创 2014-07-19 11:03:33 · 1723 阅读 · 0 评论 -
快速排序
原理:基本思想:1.从待排序列中任选一个元素作为轴点;2.将序列中比轴点的值小的放到轴点左边,比轴点的值大的放到轴点右边;3.以轴为分界线,分别对轴左边和右边部分递归进行1、2操作。平均时间复杂度 尽管快速排序的最坏时间为O(n2),但就平均性能而言,它是基于关键字比较的内部排序算法中速度最快者,快速排序亦因此而得名。它的平均时间复杂原创 2014-07-22 14:27:31 · 1668 阅读 · 0 评论 -
堆排序
二叉堆:二叉堆是完全二叉树或者是近似完全二叉树。二叉堆满足二个特性:1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆堆排序: 由二叉堆的定义可知,堆顶元素(即原创 2014-07-23 22:08:45 · 1408 阅读 · 0 评论 -
归并排序
归并排序还是比较好理解的。归并的含义是将两个或者两个以上的有序表组合成一个新的有序表。具体方式是:假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到若干长度为2或者1的有序子序列,再两两归并。。。直至得到一个长度为n的有序序列为止,这就称之为2路归并排序。复杂度:归并排序的最好最坏和平均时间复杂度都是O(n*logn),但是需要原创 2014-07-24 10:51:06 · 1587 阅读 · 0 评论 -
折半插入排序
之间介绍插入排序时漏掉一种插入方式,那就是折半插入。这种方式是采用二分查找法去查找插入点,可以减少元素比较次数,但是并不能减少移动次数,复杂度跟直接插入一样,都为O(n^2).直接上代码://二分插入排序void binary_insert_sort(int arr[],int len){ if(arr == NULL || len <= 1) { return; }原创 2014-07-27 11:27:28 · 1671 阅读 · 0 评论 -
简单插入排序
直接插入排序是一种最简单的排序方式,它的基本操作是将一个记录插入已排好序的有序表中,从而得到一个新的、记录数增1的有序表。时间复杂度为O(n^2),跟冒泡、选择一样。核心代码://按非降序排列void Insert_Sort(int arr[],int len){ if(arr == NULL || len <= 0) { return; } int i,j,t原创 2014-07-18 12:48:20 · 1841 阅读 · 0 评论 -
冒泡排序、选择排序
下面是两种最基本的排序:冒泡排序、选择排序.复杂度均为O(n^2)。冒泡排序:bool BubbleSort(int arr[],int len){ if(arr == NULL || len <= 0) { return false; } int i,j,temp; int flag = 1; for(i = 0; i < len -1 && fla原创 2014-07-16 10:22:31 · 1491 阅读 · 0 评论 -
hash表、hash算法
概念:散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为原创 2014-07-14 14:24:17 · 2131 阅读 · 0 评论 -
二分查找算法
概念:二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。原创 2014-07-11 11:23:40 · 1798 阅读 · 0 评论 -
二叉排序树(BST)
二叉排序树:二叉排序树(Binary Sort Tree)又称二叉查找树(Binary Search Tree),亦称二叉搜索树。 它或者是一棵空树;或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值; (3)左、右子树也分别为二叉排序树;注:中序遍历一棵二叉排序原创 2014-07-11 20:21:34 · 1701 阅读 · 0 评论 -
平衡二叉树(AVL树)
平衡二叉树或者是一颗空树,或者它的左右子树都是平衡二叉树,且左子树和右子树的深度之差不超过1 。BF(Balance Factor)我们将二叉树上节点的左子树深度减去右子树深度的值成为平衡因子。那么平衡二叉树上所有节点的平衡因子只可能是-1,0,1.只要二叉树上有一个节点的平衡引子的绝对值大于1,则该二叉树就是不平衡的。转载 2014-07-12 15:51:27 · 1974 阅读 · 0 评论 -
最小生成树之克鲁斯卡尔算法
克鲁斯卡尔算法:假设连通网N = {V,{E}},则令最小生成树的初始状态为只有n个顶点而无边的非连通图T = {V,{}},图中每个顶点自成一个连通分量。在E中选择一个最小代价边,若该边依附的顶点落在T中的不同连通分量上,则将此边加入到T中,否则舍去此边而选择下一条最小代价边【最小生成树不存在环】。依次类推,直至T中所有顶点都在同一连通分量上为止。【连通分量:无向图的极大连通子图】原创 2014-07-09 17:55:05 · 6241 阅读 · 0 评论 -
最短路径之Dijkstra算法
Dijkstra算法:首先,引进一个辅助向量D,它的每个分量D[i]表示当前所找到的从始点v到每个终点vi的的长度:如D[3]=2表示从始点v到终点3的路径相对最小长度为2。这里强调相对就是说在算法过程中D的值是在不断逼近最终结果但在过程中不一定就等于长度。它的初始状态为:若从v到vi有弧,则D为弧上的权值;否则置D为∞。显然,长度为 D[j]=Min{D | vi∈V} 的路径就是从原创 2014-07-10 19:31:15 · 2708 阅读 · 0 评论 -
最小生成树之Prim算法
Prim算法:假设N = (V,{E})是连通网,TE是N上最小生成树中边的集合。算法从U={u0}(u0属于V),TE={}开始,重复执行下述操作:在所有u属于U,v属于V-U的边(u,v)属于E中找到一条代价最小的边(u0,v0)并入集合TE,同时v0并入U,直至U=V为止,此时TE中必有n-1条边,则T=(V,{TE})为N的最小生成树.为实现这个算法,需附设一个辅助数组cl原创 2014-07-01 13:11:40 · 2350 阅读 · 0 评论 -
有向图的十字链表存储形式
十字链表是有向图的另一种链式存储结构。可以看成是将有向图的邻接表和逆邻接表(只考虑入度)结合起来得到的一种链表。在十字链表中,对应于有向图中每一个顶点有一个节点,每一条弧也有一个结点。顶点之间是数组顺序存储,而弧是链式存储。弧结点结构:顶点结点结构:十字链表形态:实现:/************原创 2014-06-29 16:32:14 · 6494 阅读 · 0 评论 -
图的存储形式——邻接表
邻接表:邻接表是图的一种链式存储结构。在邻接表中,对图中每个顶点建立一个单链表,第i个单链表中的节点表示依附于顶点vi的边(对有向图是以顶点vi为尾的弧)。每个结点有三个域组成,其中邻接点域指示与顶点vi邻接的点在途中的位置,链域指示下一条边或者弧的结点;数据域存储和边或者弧相关的信息,如权值等。每个链表上附设一个表头结点。在表头结点中,除了设置链域指向链表第一个结点之外,还设置有存储顶点vi的名原创 2014-06-26 12:36:09 · 2784 阅读 · 0 评论 -
图的存储形式——邻接矩阵(数组)
邻接矩阵:用两个数组分别存储数据元素(顶点)的信息和数据元素之间的关系(边或弧)的信息。比如考虑下面这个有向图:如果用邻接矩阵存储可以表示为:1.顶点数组:2.邻接矩阵:图的遍历:深度优先(DFS):深度优先搜索遍历类似于树的先根遍历,是树的先根遍历的推广。假设初始状态是图中所有顶点未曾访问过,原创 2014-06-24 13:56:06 · 5078 阅读 · 0 评论 -
使用优先队列构建赫夫曼树
关于赫夫曼编码和赫夫曼树的相关知识可参考之前两篇文章(由二叉树构造赫夫曼树、赫夫曼编码)。本文介绍另一种构建赫夫曼树的方式,采用优先队列.步骤:1.首先我们需要统计不同字符出现的次数。一个字符出现的次数越多,说明其优先级越高,其赫夫曼编码应该越短;2.将待编码的字符(即带权节点)存入优先级队列,优先级即字符出现的次数;3.不断迭代队列,直到队列中剩下一个元素原创 2014-06-18 12:20:03 · 2827 阅读 · 0 评论 -
找重复数字问题
这是两道面试题,我觉着很有意思。题目本身并不难,只是思路的问题。题目1:现有0-99共100个整数,各不相同,将所有的数放入一个数组,随机排布。数组长度101,多余的数字是0到99其中任意一个数,将重复数字找出。解决方案:暴力迭代那种方式就不说了,这里提供两种比较好的方式:public class Algo1{ public sta原创 2014-06-16 09:27:15 · 2344 阅读 · 0 评论 -
赫夫曼编码
构造过程:1.给定一组带权值的节点:2.生成赫夫曼树:3.根据“左0右1”的约定生成编码表实现:/*************************************************赫夫曼编码by Rowandjj2014/6/2**************************原创 2014-06-02 20:23:11 · 1716 阅读 · 4 评论 -
由二叉树构造赫夫曼树
赫夫曼树:假设有n个权值{w1,w2,w3....},试构造一棵具有n个叶子节点的二叉树,每个叶子节点带权为wi,则其中带权路径长度最小的二叉树称为最优二叉树或者叫赫夫曼树。构造赫夫曼树:假设有n个权值,则构造出的赫夫曼树有n个叶子节点,n个权值分别设置为w1,w2,....wn,则赫夫曼树的构造规则为:1.将w1,w2...看成是有n棵树的森林;2.在森林原创 2014-06-02 16:38:50 · 1995 阅读 · 0 评论 -
孩子兄弟表示法(二叉链表树)
考虑下面这森林:如果用孩子兄弟表示法可以表示为:顾名思义,孩子兄弟表示法的每个节点有两个指针域,一个指向其长子,另一个指向其兄弟.实现:/**************************************************树的孩子兄弟表示法(二叉链表树)by Rowandjj2014/5/25***********原创 2014-06-02 16:36:23 · 52794 阅读 · 1 评论 -
二叉树的三叉存储
形态:实现:/***************************************8二叉树的三叉链表存储by Rowandjj2014/5/23*****************************************/#includeusing namespace std;typedef int ElemType; //------原创 2014-05-24 12:53:37 · 2358 阅读 · 0 评论 -
二叉树的线性存储
/***************************************************二叉树的线性存储by Rowandjj2014/5/23***************************************************/#include#includeusing namespace std;#define MAX 255#define原创 2014-05-24 12:51:21 · 2416 阅读 · 0 评论 -
二叉树的二叉链表存储
节点形态:实现:/******************************************二叉树的二叉链表存储by Rowandjj2014/5/18******************************************/#includeusing namespace std;/*二叉树的二叉链表存储表示*/typedef int T原创 2014-05-19 08:24:53 · 2466 阅读 · 0 评论 -
广义表存储
节点形态:存储结构:每个节点都包含一个标志域,如果为0(即原子),那么仅含一个值域,如果是1(列表),那么说明该节点包含两个指针域。需要注意的是求广义表长度的操作,其实计算的是根节点及其兄弟的个数,比如图2中广义表的长度为2,图3中广义表的长度为4。深度的定义方式是递归式的,定义空表深度为1,原子深度为0,广义表的深度原创 2014-05-14 23:46:30 · 3305 阅读 · 0 评论 -
稀疏矩阵的十字链表存储表示
十字链表用的不多,但是面试可能会出现,故而记录一下。十字链表节点形态:十字链表形态:实现:/***************************************稀疏矩阵的十字链表存储表示by Rowandjj2014/5/7***************************************/#include原创 2014-05-08 12:07:28 · 4047 阅读 · 1 评论 -
矩阵压缩存储之三元组顺序表
形态:实现:/*****************************************稀疏矩阵的三元组顺序表存储表示by Rowandjj2014/5/3******************************************/#includeusing namespace std;#define MAXSIZE 12500//非零元个数的最大值原创 2014-05-04 23:19:45 · 3562 阅读 · 0 评论 -
数组顺序存储表示和实现
实现:/***************************************数组的顺序表示和实现by Rowandjj2014/5/2----------------不管是多少维的数组,在内存中都是线性存储的,数组中每个元素都对应着一个物理地址,它们之间满足一个线性的关系。比如,3维数组,3*3*2架构,即A[3][3][2],对应常量为6,2,1bounds原创 2014-05-02 23:10:29 · 4288 阅读 · 0 评论 -
串的模式匹配算法(KMP)
算法:#includeusing namespace std;#define MAXSIZE 100void calNext(const char *T,int *next);//T为模式串,next为预判数组int kmp_match(const char *S,const char *T);//在主串S中寻找模式串T,如果找到返回其位置,否则返回-1。位置从0开始void原创 2014-05-01 22:45:34 · 1475 阅读 · 0 评论 -
串的堆分配存储表示
示意图:形态:插入:删除:实现:/***********************************************串的堆分配存储表示by Rowandjj2014/4/21***********************************************/#inc原创 2014-04-22 09:53:29 · 2255 阅读 · 0 评论 -
循环队列
约定:1.以队列头指针在队列尾指针下一位置为队列满的标志.(即少使用一个空间)2.头指针始终指向队列头元素,尾指针始终指向队列尾元素的下一个位置./********************************队列的顺序存储结构by Rowandjj2014/4/19**********************************/#includeusing原创 2014-04-19 13:03:52 · 1743 阅读 · 0 评论 -
链队列
/***********************************************队列的链式存储by Rowandjj2014/4/11***********************************************/#include using namespace std;#define OK 1#define TRUE 1#define ERR原创 2014-04-11 19:25:49 · 1387 阅读 · 0 评论 -
栈的应用之迷宫求解
迷宫求解的思路很简单,即所谓的“穷举求解”,从入口出发,顺某一方向探索,若能走通,则继续往前走,否则沿着原路退回,换一个方向继续探索,直至所有可能的通路都探索到为止。为了保证在任何位置上都能沿着原路返回,需要使用栈来保存从入口到当前位置的路径。这里采用之前介绍的顺序栈作为容器存储路径。具体实现:/*****************************原创 2014-04-10 12:30:45 · 2731 阅读 · 0 评论 -
栈的应用
栈的实现基于上篇的链式栈。10进制转8进制:void conversion(){ Stack S; InitStack(S); unsigned n;//非负整数 ElemType e; cin>>n; while(n) { Push(S,n%8); n = n/8; } while原创 2014-04-10 12:26:55 · 1320 阅读 · 0 评论 -
链式栈
下面使用单链表实现链式栈:形态:实现:/*******************************************链式栈实现by Rowandjj2014/4/9*******************************************/#includeusing namespace std;#define OVERF原创 2014-04-10 12:24:15 · 1445 阅读 · 0 评论 -
顺序栈
形态:实现:/***********************************************栈的顺序存储形式by Rowandjj2014/4/7***********************************************/#includeusing namespace std;#define STACK_INIT_SIZE原创 2014-04-07 12:23:11 · 1522 阅读 · 0 评论 -
多项式的加法
实现:/*********************************多项式加法by Rowandjj2014/4/6*********************************/#includeusing namespace std;typedef struct _POLYNNODE_{ int coef;//系数 int expn;//指数原创 2014-04-07 12:20:55 · 2216 阅读 · 0 评论 -
具有实际意义的线性链表
从实际应用角度出发重新定义线性链表及其基本操作。/**********************************************具有实际意义的线性链表by Rowandjj2014/4/6***********************************************/#includeusing namespace std;#define OK 1原创 2014-04-06 12:36:16 · 1573 阅读 · 0 评论 -
设置尾指针的单循环链表
形态:实现:/************************************* 设立尾指针的的单循环链表 by Rowandjj 2014.4.5*************************************/#includeusing namespace std;#define OK 1 #define OVERFLOW 0原创 2014-04-06 12:34:50 · 9559 阅读 · 1 评论