数据结构(用面向对象和C++描述)
happycock
这个作者很懒,什么都没留下…
展开
-
数据结构学习(C++)续——排序【4】选择排序
【4】选择排序基本思想是:每次选出第i小的记录,放在第i个位置(i的起点是0,按此说法,第0小的记录实际上就是最小的,有点别扭,不管这么多了)。当i=N-1时就排完了。直接选择排序直选排序简单的再现了选择排序的基本思想,第一次寻找最小元素的代价是O(n),如果不做某种特殊处理,每次都使用最简单的寻找方法,自然的整个排序的时间复杂度就是O(n2)了。template void S原创 2003-10-20 23:57:00 · 1592 阅读 · 0 评论 -
数据结构学习(C++)——二叉树【2】
线索化二叉树这是数据结构课程里第一个碰到的难点,不知道你是不是这样看,反正我当初是费了不少脑细胞——当然,恼人的矩阵压缩和相关的加法乘法运算不在考虑之列。我费了不少脑细胞是因为思考:他们干什么呢?很欣喜的看到在这本黄皮书上,这章被打了*号,虽然我不确定作者是不是跟我一个想法——线索化二叉树在现在的PC上是毫无用处的!——不知我做了这个结论是不是会被人骂死,^_^。为了证明这个结论,我们来看原创 2003-08-08 08:39:00 · 2193 阅读 · 2 评论 -
数据结构学习(C++)——二叉树【1】
这些天参与了CSDN论坛的讨论,改变了我以前的一些看法。回头看我以前的东西,我虽对这本书很不满,但我还是按照它的安排在一点点的写;这样就导致了,我过多的在意书中的偏漏,我写的更多是说“这本书怎样”,而偏离了我写这些的初衷——给正在学习数据结构的人一些帮助。正像我在前面所说的,虽然现有的教科书都不是很合理,但如果仅仅是抱怨这点,那无异于泼妇骂街。虽然本人的水平连初级都够不上,但至少先从我做一点尝试,原创 2003-08-01 19:04:00 · 2636 阅读 · 0 评论 -
数据结构学习(C++)——递归【3】(1)
迷宫关于迷宫,有一个引人入胜的希腊神话,这也是为什么现今每当人们提到这个问题,总是兴致勃勃(对于年青人,估计是RPG玩多了),正如虽然九宫图连小学生都能做出来,我们总是自豪的说那叫“洛书”。这个神话我不复述了,有兴趣的可以在搜索引擎上输入“希腊神话 迷宫”,就能找到很多的介绍。迷宫的神话讲述了一位英雄如何靠着“线团”杀死了牛头怪(玩过《英雄无敌》的朋友一定知道要想造牛头怪,就必须建迷宫,也原创 2003-07-21 18:34:00 · 1275 阅读 · 0 评论 -
数据结构学习(C++)——递归【2】(2)
原创 2003-07-20 13:14:00 · 1164 阅读 · 0 评论 -
数据结构学习(C++)——栈应用(表达式求值)
栈的应用很广泛,原书只讲解了表达式求值,那我也就只写这些。其实,栈的最大的用途是解决回溯问题,这也包含了消解递归;而当你用栈解决回溯问题成了习惯的时候,你就很少想到用递归了,比如迷宫求解。另外,人的习惯也是先入为主的,比如树的遍历,从学的那天开始,就是递归算法,虽然书上也教了用栈实现的方法,但应用的时候,你首先想到的还是递归;当然了,如果语言本身不支持递归(如BASIC),那栈就是唯一的选择了——原创 2003-07-02 16:24:00 · 1822 阅读 · 0 评论 -
数据结构学习(C++)——栈和队列(定义和实现)
栈和队列是操作受限的线性表,好像每本讲数据结构的数都是这么说的。有些书按照这个思路给出了定义和实现;但是很遗憾,这本书没有这样做,所以,原书中的做法是重复建设,这或许可以用不是一个人写的这样的理由来开脱。顺序表示的栈和队列,必须预先分配空间,并且空间大小受限,使用起来限制比较多。而且,由于限定存取位置,顺序表示的随机存取的优点就没有了,所以,链式结构应该是首选。栈的定义和实现#ifnd原创 2003-07-03 00:19:00 · 2030 阅读 · 1 评论 -
数据结构学习(C++)——循环链表
原书对循环链表的介绍很简略,实现部分也不完整(当然了,如果完整就又是重复建设)。而我也没觉得循环链表有什么别的用,他更应该是为了一个特殊的问题而产生的,这只是个人的看法。我从链表类派生出了循环链表,这需要注意几个细节。1. 构造函数:派生类实例化时,先调用基类的构造函数;因此,初始化循环链表的工作就是将带表头的空链表的表头节点的link指向表头节点,从而构成一个圈。2.原创 2003-06-20 13:51:00 · 1944 阅读 · 0 评论 -
数据结构学习(C++)——如何在一个链表中链入不同类型的对象
似乎你也注意到了,不管怎么定义,好像一个链表中的对象都是同一类型的。而实际上,这也是必须的,否则,返回节点中的数据这样的函数的返回值的类型是什么呢?但是,人的要求是无止境的……(省略本人感慨若干百字)。把不同的对象链在一个链表中的目的是为了方便使用,现在一定记住这个原则,后面的讨论都是基于这个原则的,否则,我们就是技术狂人了——偏偏实现一些看起来不可能的事情。达到这个目标的原理其实很简单,只要原创 2003-06-20 13:50:00 · 2307 阅读 · 2 评论 -
数据结构学习(C++)——图【3】(无向图)(上)
要是在纸上随便画画,或者只是对图做点示范性的说明,大多数人都会选择无向图。然而在计算机中,无向图却是按照有向图的方法来储存的——存两条有向边。实际上,当我们说到无向的时候,只是忽略方向——在纸上画一条线,难不成那线“嗖”的就出现了,不是从一头到另一头画出来的?无向图有几个特有的概念,连通分量、关节点、最小生成树。下面将分别介绍,在此之前,先完成无向图类的基本操作。无向图类templat原创 2003-08-26 20:51:00 · 1891 阅读 · 0 评论 -
数据结构学习(C++)续——排序【1】测试程序
后面的例程,都是对数组的排序,使用静态链表的也适用于链表的排序。为简单起见,只对单关键码排序,并且最后的结果都是从头到尾按升序排列。下面是统一的测试程序:#include #include using namespace std;#include #include #include #include "InsertSort.h"#define random(num)原创 2003-09-09 09:09:00 · 1740 阅读 · 0 评论 -
数据结构学习(C++)续——排序【2】插入排序
基本思想是,每步将一个待排序的记录,按其关键码大小,插入到前面已经排好序的记录的适当位置,从头做到尾就可以了。直接插入排序template void InsertSort(T a[], int N, int& KCN, int& RMN){ KCN = 0; RMN = 0; for (int i = 1; i {原创 2003-09-12 19:23:00 · 1594 阅读 · 1 评论 -
数据结构学习(C++)——后记
这回真的是后记了,也就是到了这些文章结束的时候了。虽然还有排序和查找两大算法系没有讲,但是对于“数据结构”而言,上面应该是全部了。并且这些文章加在一起已经很长了,每次打开WORD来编辑,跳到末页总是不那么顺畅,是到了结束的时候了。对于那两大算法系,我准备另外再开一个系列,姑且就叫做《数据结构学习(C++)续》吧。突然发现,在安排文章结构上不知不觉的受了《计算机编程艺术》的影响了。我的参考书主要原创 2003-09-05 22:41:00 · 2375 阅读 · 2 评论 -
数据结构学习(C++)——图(总结)
以上就是现在的教科书里面,图的全部内容了。写完之后,茫茫然,不知道学完之后有什么用……就像我在开篇写的,图的应用太广泛了,以至于现在觉得图“没什么用”——很奇怪的逻辑,只有仔细体味才能觉察到写教科书的人的无奈。不同于前面的链表和树,在图这里,储存方法不是重点,我们更多的注意力放在了算法上。我在写程序的时候,也尽量做到了算法和储存方法无关。然而算法实际上就是现实问题的抽象,如果我们的常识所不及,原创 2003-09-03 22:48:00 · 5332 阅读 · 3 评论 -
数据结构学习(C++)——图【5】活动网络(AOV、AOE)
这部分是和工程相关的,也就是说,当AOV、AOE很复杂的时候,才能显示出这部分的价值——简单的话,手工都要比程序快,输入数据那段时间手工结果就出来了。我也没什么例子好举,总给我一种没底气的感觉,勉为其难的把程序写完就算完事吧。和前边的相比,这部分专业了一点,换而言之,不是每个人都感兴趣,不想看就跳过去吧。准备工作活动网络主要有两个算法,拓扑排序和求关键路径,后者以前者为基础。仿照上篇,另外原创 2003-09-03 22:48:00 · 2639 阅读 · 0 评论 -
数据结构学习(C++)——图【2】(DFS和BFS)
对于非线性的结构,遍历都会首先成为一个问题。和二叉树的遍历一样,图也有深度优先搜索(DFS)和广度优先搜索(BFS)两种。不同的是,图中每个顶点没有了祖先和子孙的关系,因此,前序、中序、后序不再有意义了。仿照二叉树的遍历,很容易就能完成DFS和BFS,只是要注意图中可能有回路,因此,必须对访问过的顶点做标记。最基本的有向带权网#ifndef Graph_H#define Graph_H原创 2003-08-20 21:41:00 · 2518 阅读 · 0 评论 -
数据结构学习(C++)——递归【1】
按照黄皮书的安排,到了该讲递归的时候了。上网查了查,关于“递归”的文章可以说“汗牛充栋”——请原谅我在这里犯酸,我的意思是,写别人都写臭的东西让大家看,只是浪费大家的时间,所以我下面的东西应该是一些至少我看起来是新的东西,如果觉得有什么不清楚的,请参阅相关的文章(太多了)。即使这样,这篇文章还是不能把我想说的写完,看来我这人真的有废话的习惯。看过这样一道题,问,“程序结构化设计的三种基础结构,原创 2003-07-20 13:14:00 · 3105 阅读 · 0 评论 -
数据结构学习(C++)——线性链式结构总结(代后记)【1】
看到这个标题,有些人一定松了一口气——这小子可算白话完了,当然了,你要是略有惋惜之情,我真是受宠若惊。但不论你怎么想,写到这里只是告一段落,并没有完,后面还有很大一部分呢,比如树、图、查找、排序——这么多年了,还是这点东西。代后记的意思是,我觉得对前面线性链式结构的总结,对后面的学习有指导意义:从前面的学习中,你能得出如何学习数据结构,以及如何正确看待这门课——如果你能从重复建设中看到这样做的价值原创 2003-07-07 08:32:00 · 1036 阅读 · 0 评论 -
数据结构学习(C++)——稀疏矩阵(十字链表【2】)
如果你细想想,就会发现,非零元节点如果没有指示位置的域,那么做加法和乘法时,为了确定节点的位置,每次都要遍历行和列的链表。因此,为了运算效率,这个域是必须的。为了看出十字链表和单链表的差异,我从单链表派生出十字链表,这需要先定义一种新的结构,如下:class MatNode{public: int data; int row, col;原创 2003-07-02 23:08:00 · 2415 阅读 · 1 评论 -
数据结构学习(C++)续——续篇后记
我觉得续篇的写作我很不负责任,越到后面越是如此,可能是我没有打算写的缘故,或者说是“心浮气躁”——写了几个月有点熬不住了,^_^。但也可能我只能写到这样,毕竟这部分离我们太远,至少和前边的“数据结构”相比是太远。有人说,查找和排序的算法已经非常成熟了,大师们穷尽脑汁也不可能带来“质的飞跃”了,而像我们这些等着“吸收前人劳动果实”的人,能全盘吸收就甚为不易,更不要说“完成前人所未完成”了。因此,原创 2004-03-16 16:56:00 · 2296 阅读 · 2 评论 -
数据结构学习(C++)续——查找(搜索)【2】
树型查找折半查找所需要的,有序的、可以随机存取的、顺序结构的限制,导致了排序的额外负担(如果是逐个添加,主要的负担是移动数据,此时是折半插入排序)。通过观察折半查找的过程,发现实际上mid是从判定树的根走到了叶子节点,而这棵判定树和有相同节点的完全二叉树的高度是相同的。链式结构的好处就是不用大量移动数据,自然的用链树来做查找结构应该是个好选择。在前面我们曾经写过一个BSTree类,这个类大原创 2004-02-09 00:11:00 · 2397 阅读 · 1 评论 -
数据结构学习(C++)续——排序【3】交换排序
【3】交换排序基本思想是:两两比较待排序记录的关键码,如果发生逆序,则交换之,直到所有对象都排好为止。起泡排序起泡排序是比较相邻的两个记录,逆序则交换。这样的做法导致小的关键码一层层的浮上来,因此得名。CSDN的论坛曾经讨论过“冒泡”和“起泡”是不是一个东西,看来这是翻译惹的祸,英文名都是Bubble Sort,具体写的时候可以正着排,也可以倒着排。(严版是从后往前排,殷版是从前往后排原创 2003-10-20 23:56:00 · 1492 阅读 · 0 评论 -
数据结构学习(C++)——双向链表
原书这部分内容很多,至少相对于循环链表是很多。相信当你把单链表的指针域搞清楚后,这部分应该难不倒你。现在我的问题是,能不能从单链表派生出双向链表?你可以有几种做法:一种就是先定义一个双链节点——但是,它的名字必须叫Node,这是没办法的事;不然你就只好拷贝一份单链表的实现文件,把其中的Node全都替换成你的双链节点名字,但是这就不叫继承了。另一种做法就是先定义一种结构例如这样的:t原创 2003-06-21 13:35:00 · 1542 阅读 · 0 评论 -
数据结构学习(C++)——序言
题外话:先前有一篇文章叫《用C++模板描述的链表、栈、队列(声明与实现)》,当时是第一次发表文章(我才注册没几天),很不成熟,改了又改不说,还弄的老长,不利于阅读。于是我重写了一下,并且想做成一个系列,这从我的标题可以看出来。好,言归正传。本篇为后面一系列文章的序言,旨在说明写作的目的,以及写作的风格;或者说是为自己可能的错误,预先给个托词。如果您不想听我在这废话,请跳过本篇,直接阅读后面的文原创 2003-06-20 09:39:00 · 1920 阅读 · 0 评论 -
数据结构学习(C++)续——查找(搜索)【1】
相信每个人都曾感受过找东西的痛苦,大多数人也感受过计算机参与资料管理后所带来的便捷,而学过编程的也曾为了某个问题(比如实现“如果不存在则加入”这样的算法描述——排列组合算法的初级阶段)而实现过查找。在SGI-STL的stl_algo.h里面有这样一段代码:template inline _InputIter find(_InputIter __first, _InputIter __las原创 2004-01-04 10:22:00 · 1686 阅读 · 0 评论 -
数据结构学习(C++)续——排序【6】内部排序总结
基数排序本文后面将会提到,我觉得将其和前面的排序算法放在一起比较有些不伦不类。前面介绍了四类排序方法,每种都有基本型和改进型。对于内部排序,我们最关心的当然是速度,这也是为什么快排受欢迎的原因。考虑到快排的缺陷,有时候我们可能会用堆排或者希尔排序、归并排序。上面可能是选择排序方法最直接的思路了(我们的选择范围也不算广,就那几个翻过来调过去的,好一点的,综合一下搞一个“杂牌”),出于“赌徒”的思原创 2004-02-09 00:07:00 · 2292 阅读 · 1 评论 -
数据结构学习(C++)续——排序【5】归并排序
【5】归并排序当初学习链表的时候,我们都曾经做过将两个有序链表合成一个有序链表的练习。那时我们就知道了归并的特点就是,将分段有序的序列合成整体有序的序列。在内部排序中,归并的地位并不十分重要,主要是因为附加的O(n)的储存空间;但是,归并却是外部排序的不二法门——我们只能用内排得到分段有序的序列,为了得到最后的有序序列,必须使用归并的方法。迭代的2路归并排序2路归并是最简单的,并且单纯原创 2003-10-28 14:21:00 · 2320 阅读 · 0 评论 -
数据结构学习(C++)——平衡二叉树(AVL树)【1】 ——请孟岩审
这个恐怕是整个《数据结构》教科书里面最难的和最“没用”的数据结构了(现在的教科书还有部分算法内容)。说它没用,恰恰是因为它太有用——有着和普通的二叉搜索树完全一样的接口界面,绝大多数情况下比普通的二叉搜索树效率高(很多)。因此,通常情况下,人们都是一劳永逸的——写完后就重用,而不会再写了。所以说,你虽然学完了平衡二叉树,但很可能你永远也不会亲自写一个。你现在随便在身边拉个人,让他来写一个,原创 2003-08-15 15:07:00 · 16936 阅读 · 13 评论 -
数据结构学习(C++)——递归【2】(4)
#include #include using namespace std;class Needle{public: Needle() { a.push_back(100); }//每一个柱子都有一个底座 void push(int n) { a.push_back(n); } int top() { return a.back(原创 2003-07-20 13:13:00 · 1065 阅读 · 0 评论 -
数据结构学习(C++)——队列应用(事件驱动模拟)
我看的两本教科书(《数据结构(C语言版)》还有这本黄皮书)都是以这个讲解队列应用的,而且都是银行营业模拟(太没新意了)。细比较,这两本书模拟的银行营业的方式还是不同的。1997版的《数据结构(C语言版)》的银行还是老式的营业模式(毕竟是1997年的事了),现在的很多地方还是这种营业模式——几个窗口同时排队。这种方式其实不太合理,经常会出现先来的还没有后来的先办理业务(常常前面一个人磨磨蹭蹭,别的队原创 2003-07-02 16:08:00 · 1136 阅读 · 1 评论 -
数据结构学习(C++)——单链表应用(一元多项式【1】)
总算到了这里,这时,你会很得意的说,辛辛苦苦学的单链表总算知道能干点什么了。但是很不幸,如果你和我一样看的是那本书,到这里,你可能比学双向链表时还要痛苦。如果你是按照书上的介绍一步一步做到这里,你能把书上的多项式加法函数调试出来,我对你致以十二分的敬意。说到这里,我想起来我发单链表的时候,有人给我建议说:最好把链表和链表位置这两个分开。没错,C++标准库是这么做的,而我也不是什么专家,也不能证原创 2003-06-22 11:43:00 · 3647 阅读 · 0 评论 -
数据结构学习(C++)——单链表应用(一元多项式【2】)
按照原书的安排,对多项式的讲解到上一篇就应该结束了,但我还想做一些延伸。比如说,你很清楚多项式的系数肯定不总是整数,但为什么用整型呢?我看到原书用的是整型,我也有这个疑问。但是,一旦动起手来,就会发现改成浮点不仅仅只是在定义Term时把int coef;改成float coef;很多的细节都要考虑到(给个提示,你知道浮点零是多少吗)。我试了一下,最后放弃了;理由是,写这些只是为了学习,没必要搞的那原创 2003-06-22 11:43:00 · 2204 阅读 · 0 评论 -
数据结构学习(C++)——稀疏矩阵(十字链表【1】)
先说说什么叫稀疏矩阵。你说,这个问题很简单吗,那你一定不知道中国学术界的嘴皮子仗,对一个字眼的“抠”将会导致两种相反的结论。这是清华2000年的一道考研题:“表示一个有1000个顶点,1000条边的有向图的邻接矩阵有多少个矩阵元素?是否稀疏矩阵?”如果你是个喜欢研究出题者心理活动的人,你可以看出这里有两个陷阱,就是让明明会的人答错,我不想说出是什么,留给读者思考。姑且不论清华给的标准答案是什么,那原创 2003-06-23 17:05:00 · 2277 阅读 · 0 评论 -
数据结构学习(C++)——图【4】(最短路径)
最短路径恐怕是图的各种算法中最能吸引初学者眼球的了——在地图上找一条最短的路或许每个人都曾经尝试过。下面我们用计算机来完成我们曾经的“愿望”。在图的算法中有个有趣的现象,就是问题的规模越大,算法就越简单。图是个复杂的结构,对于一个特定问题,求解特定顶点的结果都会受到其他顶点的影响——就好比一堆互相碰撞的球体,要求解特定球体的状态,就必须考虑其他球体的状态。既然每个顶点都要扫描,如果对所有的顶点原创 2003-09-02 23:33:00 · 8212 阅读 · 1 评论 -
数据结构学习(C++)——图【3】(无向图)(下)
最小生成树说人是最难伺候的,真是一点不假。上面刚刚为了“提高可靠性”添加了几条多余的边,这会儿又来想办法怎么能以最小的代价把所有的顶点都连起来。可能正是人的这种精神才使得人类能够进步吧——看着现在3GHz的CPU真是眼红啊,我还在受500MHz的煎熬,然后再想想8086……正如图的基本元素是顶点和边,从这两个方向出发,就能得到两个算法——Kruskal算法(从边出发)、Prim算法(从顶点原创 2003-08-27 08:43:00 · 1903 阅读 · 0 评论 -
数据结构学习(C++)——图【1】(基本储存方法)
首先告诉大家一个好消息,数据结构到这里就要结束了!然后再来一个坏消息,这里是数据结构中“最没有意义”的部分和最难的部分。图的应用恐怕是所有结构中最宽泛的了,但这也注定了在讲“数据结构的图”的时候没什么好讲的——关于图的最重要的是算法,而且相当的一部分都是很专业的,一般的人几乎不会接触到;相对而言,结构就显得分量很轻。你可以看到关于图中元素的操作很少,远没有单链表那里列出的一大堆“接口”。——一个结原创 2003-08-26 15:26:00 · 1973 阅读 · 0 评论 -
数据结构学习(C++)——树(总结)
才刚开了个头,就要说再见了——在树这里,除了二叉树,别的都还没有讲。为什么可以总结了呢?因为前面已经涉及到了树的两个基本用途,而如果再讲B+、B-,就不能不提到搜索,如果是胜者树就不能不提到排序。为此,把这部分放到后面。我前面所做的努力,只是让你有个基本概念,什么时候记得用树。树的两个基本用途,可以用物质和精神来比喻。一个用途是做为数据储存,储存具有树结构的数据——目录、族谱等等。为了在实原创 2003-08-18 01:08:00 · 2115 阅读 · 0 评论 -
数据结构学习(C++)——平衡二叉树(AVL树)【2】
平衡化 显然的,平衡化后的子树应该是平衡的,以此为原则,很容易得知在各种情况下应该怎么旋转。private: void L_Balance(BTNode* &p) { if (p->right->bf == 1) R_Rotate(p->right); L_Rotate(p); current原创 2003-08-15 15:07:00 · 7260 阅读 · 13 评论 -
数据结构学习(C++)——二叉树【3】
递归遍历与非递归遍历前面写过一些关于递归的文章,因为那时还没有写到树,因此也举不出更有说服力的例子,只是阐述了“递归是一种思想”,正像网友评价的,“一篇入门的文章”。但只要能能让你建立“递归是一种思想”这个观念,我的努力就没有白费。现在,讲完了二叉搜索树,终于有了能说明问题的例子了。按照前面提供的代码,应该能调试通过下面的程序。#include using namespace std;原创 2003-08-05 10:59:00 · 1881 阅读 · 1 评论 -
数据结构学习(C++)——递归【2】(3)
1原创 2003-07-20 13:13:00 · 1070 阅读 · 0 评论