摘要: 之前在冒泡排序的附录中提到可以在每次循环时候,不用交换操作,而只需要记录最小值下标,每次循环后交换哨兵与最小值下标的书,这样可以减少交换操作的时间。这种方法针对冒泡排序中需要频繁交换数组数字而改进。以此类推。。。代码: 1 void selectionSort(myDataType *ary,int len) 2 { 3 int i,j; 4 int mymin; //记录最小值下标 5 for (i=0;i ary[j])11 {12 mymin = j;13 14 ... 阅读全文
posted @ 2013-12-04 16:20 sjdang 阅读(278) 评论(0) 推荐(0) 编辑
摘要: 冒泡排序应该是最常用的排序方法,我接触的第一个排序算法就是冒泡,老师也经常那这个做例子。冒泡排序是一种交换排序,基本思想:通过两两比较相邻的记录,若反序则交换,知道没有反序的记录为止。例子:依次类推。这里可以看出,每次比较从最后一个开始,向前比较,若反序则交换;每次都保证了是两两相邻的记录比较。冒泡排序的代码: 1 void bubble_sort (myDataType *ary,int len) 2 { 3 int i,j; 4 for (i=0;i=i;j--) 7 { 8 if (ary[j] > ary[j+1]) 9 ... 阅读全文
posted @ 2013-12-04 16:04 sjdang 阅读(462) 评论(0) 推荐(0) 编辑
摘要: 排序是非常基本的一个操作。排序也分许多方法,可能会有人想,为什么不用最一种最快最好的方法而非要搞出那么多方法呢?因为各种方法有各种方法的用处,适用于不同的情况。排序分:内排序 和 外排序内排序:在排序整个过程中,所有的欲排序记录都存放在内存中。外排序:欲排序的个数多,不能同时放置内存,整个排序过程需要在内外存之间多次交换。内排序:在排序过程中,所有元素调到内存中进行的排序,称为内排序。内排序是排序的基础。内排序效率用比较次数来衡量。按所用策略不同,内排序又可分为插入排序、选择排序、交换排序、归并排序及基数排序等几大类。外排序:在数据量大的情况下,只能分块排序,但块与块间不能保证有序。外排序用读 阅读全文
posted @ 2013-12-04 14:40 sjdang 阅读(212) 评论(0) 推荐(0) 编辑
摘要: 之前我们介绍过,在一个工程中我们关心两个问题:(1)工程是否顺利进行(2)整个工程最短时间。之前我们优先关心的是顶点(AOV),同样我们也可以优先关心边(同理有AOE)。(Activity On Edge Network)看看百度百科上解释:AOE网:Activity on edge network若在带权的有向图中,以顶点表示事件,以有向边表示活动,边上的权值表示活动的开销(如该活动持续的时间),则此带权的有向图称为AOE网。 如果用AOE网来表示一项工程,那么,仅仅考虑各个子工程之间的优先关系还不够,更多的是关心整个工程完成的最短时间是多少;哪些活动的延期将会影响整个工程的进度,而加速这些 阅读全文
posted @ 2013-12-02 17:29 sjdang 阅读(36283) 评论(1) 推荐(9) 编辑
摘要: 这一篇写有向无环图及其它的应用:清楚概念:有向无环图(DAG):一个无环的有向图。通俗的讲就是从一个点沿着有向边出发,无论怎么遍历都不会回到出发点上。有向无环图是描述一项工程或者系统的进行过程的有效工具,比如办公室,到工商局里面注册的时候,他会提示你一个流程,这个流程就是一个有向无环图。第一步不做,第二步就做不了。在其期间关心两个问题:1.工程是否顺利?(拓扑排序)2.估算整个工程所必须的最短时间。(关键路径)拓扑排序:数学语言:某个集合上的一个偏序得到该集合上的一个全序的操作过程。(迷糊中。。。看下离散数学。。。)百度百科:拓扑序列通常,这样的线性序列称为满足拓扑次序(Topological 阅读全文
posted @ 2013-11-25 12:18 sjdang 阅读(2443) 评论(0) 推荐(0) 编辑
摘要: floyd算法:解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的传递闭包。设为从到的只以集合中的节点为中间节点的最短路径的长度。若最短路径经过点k,则;若最短路径不经过点k,则。因此,。在实际算法中,为了节约空间,可以直接在原来空间上进行迭代,这样空间可降至二维。我的理解为:folyd算法是每次选定一个点,查看任意两个顶点的距离是否都小于经过这个点之和的距离。即:假如ABC三个顶点相连,选定C的时候,查AB的距离是否大于 AC + CB 的距离之和,如果大于说明找到了一个更短的路径,即A->C->B。下面是我的例子:floyd算法 阅读全文
posted @ 2013-11-18 19:08 sjdang 阅读(475) 评论(0) 推荐(0) 编辑
摘要: 在网图中,最短路径的概论:两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点是源点,最后一个顶点是终点。维基百科上面的解释:这个算法是通过为每个顶点v保留目前为止所找到的从s到v的最短路径来工作的。初始时,原点 s 的路径长度值被赋为 0 (d[s]= 0),若存在能直接到达的边(s,m),则把d[m]设为w(s,m),同时把所有其他(s不能直接到达的)顶点的路径长度设为无穷大,即表示我们不知道任何通向这些顶点的路径(对于V中所有顶点v除s和上述m外d[v]= ∞)。当算法退出时,d[v]中存储的便是从s到v的最短路径,或者如果路径不存在的话是无穷大。Dijkstra 算法的 阅读全文
posted @ 2013-11-17 14:22 sjdang 阅读(769) 评论(0) 推荐(0) 编辑
摘要: 之前的Prim算法是基于顶点查找的算法,而Kruskal则是从边入手。通俗的讲:就是希望通过 边的权值大小 来寻找最小生成树。(所有的边称为边集合,最小生成树形成的过程中的顶点集合称为W) 选取边集合中权值最小的边,查看边的两个顶点是否能和集合W构成环路,若能构成环路,则舍去;否则选取下一条最小权值边重复上一步。 这里需要注意一个问题,我们从最小权值的边开始寻找最小生成树, 判断当即将选入的边的两个顶点是否会和已经在集合中的顶点构成环路,这个是我们需要解决的问题。先说下Kruskal算法的数学语言:假设连通网N={V,{E}},则令最小生成树的初始状态只有n个顶点而无边的非连... 阅读全文
posted @ 2013-11-14 21:31 sjdang 阅读(626) 评论(0) 推荐(0) 编辑
摘要: 一个连通图的生成树是一个极小的连通子图,它包含图中全部的顶点(n个顶点),但只有n-1条边。最小生成树:构造连通网的最小代价(最小权值)生成树。prim算法在严蔚敏树上有解释,但是都是数学语言,很深奥。最小生成树MST性质:假设N=(V,{E})是一个连通网,U是顶点集V的一个非空子集。若(u,v)是一条具有最小权值(代价)的边,其中u∈U,v∈V-U,则必存在一颗包含边(u,v)的最小生成树。prim算法过程为:假设N=(V,{E})是连通图,TE是N上最小生成树中边的集合。算法从U={u0}(u0∈V),TE={}开始,重复执行下述操作:在所有u∈U,v∈V-U的边(u,v)∈E中找一条代 阅读全文
posted @ 2013-11-14 00:20 sjdang 阅读(1984) 评论(0) 推荐(0) 编辑
摘要: 图:目录:1.概念2.邻接矩阵(结构,深度/广度优先遍历)3.邻接表(结构,深度/广度优先遍历)图的基本概念:数据元素:顶点1.有穷非空(必须有顶点)2.顶点之间为边(可空)无向图:边没有方向,用(vi,vj)表示,(vj,vi)也可。有向图:边有方向,称为弧,用表示。vi尾,vj头简单图:不存在顶... 阅读全文
posted @ 2013-11-12 17:11 sjdang 阅读(844) 评论(0) 推荐(0) 编辑
摘要: 二叉树的结构中可以看到,会有许多空指针,这有浪费了资源。n个节点的二叉树共有n-1条分支。(除了根没有分支)对于这样的结构: | left-child | data | right-child |,总分支指针(2n),空闲指针有(2n-(n-1))=n+1个分支。能不能利用空闲指针呢?通过利用这些空闲指针,方便我们索引这颗二叉树呢?比如我们找到了头,就能够通过头节点的孩子节点和线索索引来访问整颗树,这有就没有必要像上篇文章那样,通过递归的调用 前序/中序/后序遍历整棵树。这里注意:线索化二叉树实质上通过一种遍历方式,将空闲指针指向该遍历方法下一个要访问的节点。即节约了空间,也提高了某些操作的效 阅读全文
posted @ 2013-11-09 17:47 sjdang 阅读(319) 评论(0) 推荐(0) 编辑
摘要: 树:是n(n>=0)个节点的有限集。n=0时称为空树。在任意一颗非空树中: (1)有且仅有一个特定的称为根的节点; (2)当n>1时,其余节点可分为m(m>0)个互不相交的有限集T1,T2、...、Tm,其中 每一个集合本身又是一棵树,并且称为根的子树。节点:a.根节点b.内部节点c.叶结点度:一个节点拥有的子节点个数。深度:树的层数。二叉树特点:a.每个节点最多两个子树。度=1)2.深度为k的二叉树至多有2k-1个节点(k>=1)3.任意二叉树,终端节点为n0,度为2的节点数位n2;则n0=n2+14.具有n个节点的完全二叉树的深度为【log2n】+15.如果对一颗有 阅读全文
posted @ 2013-11-07 19:01 sjdang 阅读(656) 评论(0) 推荐(0) 编辑
摘要: 栈的应用在进制转化过程中,其中10进制转化各种进制用处比较多。原理就是拿十进制的数不停的 去除 进制的模数 得到余数组合就是转化后的数。比如 (255)10 转化为 16进制 时候254/16=15 ...14 ---> E15/16=0...15 ---> F255 即为 0XFE注意到各个结果反过来才是最后的结果。想到栈的特点,这里可以用栈的结构,最先算出来的结果现存入到栈底,最后算出的在栈顶。然后出栈就可以得到最后的结果。这里我做一个10进制转16进制转化的程序。添加之前写的栈的程序:#include "stdafx.h"#includetypedef s 阅读全文
posted @ 2013-11-05 15:58 sjdang 阅读(419) 评论(0) 推荐(0) 编辑
摘要: 队列与栈不同的是,队列是先进先出(First In First Out),这种结构在操作系统底层调用中广泛应用,比如:键盘输入abc,先输入的a最先显示出来,依次b、c。再比如:在操作系统中,将要处理的任务加入队列中,当cpu有空闲时,出队进行处理。队列和栈一样,也有顺序队列和队链(不知道这个称呼对不对)。这里我们讨论队链:栈中使用的栈顶做标记,因为它只需要一个口就可以进出。队列使用两个元素做标记,分别是队头和队尾(front and rear)。通过这两个指针的指向来指示队列的进出。front 负责出队列(EnQueue)。rear 负责进队列(DeQueue)。看一个队列示意图:这里需要两 阅读全文
posted @ 2013-11-05 14:56 sjdang 阅读(197) 评论(0) 推荐(0) 编辑
摘要: 栈栈是一个重要的数据结构,在操作系统中应用非常广泛,特别在多任务操作系统中,进程与进程间的调用都需要用到栈。现实中最好的例子我认为是枪的弹夹,把子弹压入到弹夹盒子里面,先放进去的最后才能出来(FILO)frist in last out ,压入子弹的过程叫做进栈。开枪的过程叫出栈。用c来实现栈,主要操作是 初始化,判断空,出栈,进栈等。栈和链表一样可以分为两种,顺序栈和链栈。顺序栈实质上就是数组,移动栈顶指针指向就能操作顺序栈的基本操作,主要是对数组的下标判断和操作。0.链栈的数据结构:typedef struct stNode{ //栈的数据结构,一个数据和一个指针 int data;... 阅读全文
posted @ 2013-11-05 11:19 sjdang 阅读(222) 评论(0) 推荐(0) 编辑
摘要: 单链表缺点是每次都要从头开始索引,不能往回索引,很自然就会想一个办法,希望能够往回索引。这有双链表就产生了。0.双链表结构:typedef struct lNode{ int data; struct lNode* pri; struct lNode* next;}ltNode,*ptNode;增加了一个前驱指针,这有就可以向回索引了。1.双链表的初始化//1.双向链表的initvoid dlist_init(ptNode* head){ *head = (ptNode)malloc(sizeof(ltNode)); (*head)->data = 0; (... 阅读全文
posted @ 2013-11-01 15:56 sjdang 阅读(227) 评论(0) 推荐(0) 编辑
摘要: 最近学算法,做一个简单记录。把容易出错和混淆的地方记录一下。这里编程语言选择为C。什么是链表? 要搞清楚链表,首先要知道顺序表。顺序表也是我们常说的数组,数组有个最大的特点,它的存储空间在内存上是连续的。数组解决了我们编程中许多问题,如果我们事前不知道需要多大的内存,而我们在C中编程的时候不能够动态的申请数组(不能在程序中这样写:int array[n],其中n是你上一个计算中得出的值)。有人说,我申请大点,不需要的用其他数据填,针对我们现在的PC机貌似可以,但是为了节省空间和程序的优化性能考虑,我们需要能够动态的申请需要的空间。所以我们需要一个方能,能够动态申请空间。 C语言中malloc. 阅读全文
posted @ 2013-11-01 12:51 sjdang 阅读(277) 评论(0) 推荐(2) 编辑