1、数据结构报告计算机科学与技术学院课程设计报告课程名称:数据结构专业:软 件 工 程班级:2010级1001班学号:201013138026 姓名:邓仕军指导老师:袁嵩仓库管理系统【问题描述】使用链表实现一个仓库管理系统,仓库商品的属性包括(商品编号,商品名称,商品数量),借助计算机来完成如下功能:(1)入库:可以录入商品信息,包括:商品编号,商品名称,商品数量,商品价格;(2)出库:可以删除一定数量的指定商品名称的商品,商品不够给出提示;(3)修改:修改指定商品编号或者商品名称的价格;(4)删除:可以删除指定商品编号、商品名称的商品记录;(5)查询:可以查询所有商品信息;或指定商品编号、商品名
2、称的商品信息;(6)排序:可以根据价格或数量对商品进行排序,并显示排序结果;【基本要求】1、 实现问题描述中所有需求;2、 从文件中读取数据;【设计方案】设计方案方案编号内容优点缺点一程序启动读文件关闭写文件1)文件读写只一次,减少对存储设备的访问(空间复杂度);2)没有频繁的堆存数设备访问,加快了需求实现响应速度(时间复杂度);1)整个数据加载在内存中,对内存要求高;2)一次读入,整个程序一直用在开始指定的存储结构,整个数据在内存中,就不能适时的选择算法,对对应的要求可能无法选择最优的算法,如果要在内存中临时转变存储结构,要么费时(一次转换少量),要么费内存(空间复杂度)3)突发的程序终止,
3、丢失数据问题;二随时读取文件1)可以对相应的要求可以选择最适合的算法;2)对内存要求较低;1)频繁的访问存储设备;2)响应慢;三定位在文件中实现需求对内存要求很低,只需加载少量的数据更频繁的访问存储设备,响应更慢 分析:1)多用户同时访问,需要响应速度快,能够及时的完成请求(时间复杂度);2)频繁的读取存储设备,缩短使用周期,要维护和修补其造成的不良后果难度更大;3)较高的内存要求,在一定程度容易满足(空间复杂度);结果:选择方案一,以双向链表作存储结构并附折中处理办法:a.哈希表存指针,弥补查询效率(时间复杂度)不足,与链表结合,又可以提高删除效率(双向链表删除效率低主要是要先查找);b.在
4、有更新后立即写入文件;系统架构图【实现】整体规划设计思路1、使用双向链表存储所有结点,哈希表仅仅存储结点指针:双向链表可以快速增、删、改、排序,哈希表的查新效率高,可以结合二中节后的优点,同时一定顶程度上减少对内存的开销;2、表层应用由java完成,数据操作由CPP完成; 说明 a.底层数据结构:执行数据的增删改查操作和存储;b.用户图形界面:将用户的请求转化分解为对底层的基本操作的组合,将处理结果显示在图形界面上;c.由于项目的出发点是数据结构,故而本程序中不使用java中“屏蔽数据结构”的集合,只使用数组;逻辑结构typedefstruct Commodity IdType id; Nam
5、eType name; AmountType amount; PriceType price; Commodity *prior,*next; CommNode,*CommLinkList;typedef Commodity ElemType;structHashTable CommLinkList *elem; / ElemType* int count; / 当前数据元素个数 int size;/当前HashTable的大小 doubleloadFactor;/负载因子,以此可以控制查询效率 ;存储结构XML文档存储结构步骤搭建开发环境 a.导入开发包: dom4j beanUtils 相
6、关文档资源包 b.创建组织程序的包 cn.xiaodeng.domain :javabean cn.xiaodeng.dao cn.xiaodeng.dao.impl: 数据访问对象(Data Acess Object) cn.xiaodeng.app.controller :处理请求 cn.xiaodeng.app.UI : 给用户提供界面 cn.xiaodeng.utils :工具 cn.xiaodeng.exception :异常处理 junit.test c.创建代表数据库的 xml 文件编程实现 1、读取数据,建双向链表、哈希表:ElemType&InsertAscend(CommL
7、inkList&L,ElemType e) 按非降序排列的线性表L已存在,在L中按非降序插入新的数据元e,返回其引用,取地址插入hashTable /产生一个字符串哈希码值,算法来自网上收录资料jintHashCode(char* key) unsignedint hash = 1315423911; while (*key) hash = (hash 2); return (hash & 0x7FFFFFFF); /根据hashCode,确定该插入元素的位置intindexFor(inthashCode, int length) returnhashCode& (length-1); int
8、 collision(intp,intd,int size) / 线性探测再散列 / 开放定址法处理冲突 return p=(p+d)%size; Status InsertHash(HashTable&H,ElemType&e,int tag) if(/*e已经存在*/) /返回重复elseif(/*探测次数next; exchange=0; while (p-next!=tail) if(p-amountp-next-amount) /交换两结点指针,涉及6条链 temp=p-next; exchange=1;/有交换 p-next=temp-next; temp-next-prior=p
9、; /先将结点从链表上摘下 temp-next=p; p-prior-next=temp;/将temp插到p结点前 temp-prior=p-prior; p-prior=temp; else p=p-next; /无交换,指针后移 tail=p;p=tail-prior;/准备向上起泡 while (exchange & p-prior!=head) /向上(左)起泡,一趟有一最小元素冒出 if(p-amountprior-amount)/ temp=p-prior; exchange=1; /有交换 p-prior=temp-prior;temp-prior-next=p; temp-pr
10、ior=p; p-next-prior=temp; temp-next=p-next; p-next=temp; else p=p-prior; head=p; /准备向下起泡 / while (exchange)3、 删除:/以按id删除为例Commodity STATU_VAR;Commodity * DELKEY =&STATU_VAR;/标志该位置被删除过元素哈希表中的删除CommLinkList&DeleteHash(HashTable&H,KeyType K)/删除Hash表中的元素e,并返回其指针的引用,不具通用性,前提/是已有函数确定e必定在Hash表中存在 int p; Fi
11、nd(H,K,p);/寻找/前提是e必定存在,故在这里不作判断 ElemType *s=H.elemp; H.elemp=DELKEY; /设置数量标志为DELKEY(-1),表明该元素已被删除,但是删除/点的释放工作并不在这里进行,而是由链表去做 H.count-; /哈希表当前长度减一 return s; jobjectArrayDeleteById(jstring id) if(!Search(hashTable,id) return NULL;/在哈希表中查找,没找到,说明删除的元素不存在,返回空 CommLinkListdete_com=DeleteHash(hashTable,id
12、); ListDelete(dataL,dete_com); /双向链表中删除 /其它处理4、 查找:/以按id查找为例ElemType* Search(HashTableH,KeyType K) / 在开放定址哈希表H中查找关键码为K的元素,若查找成功,以p指/示待查数据元素在表中位置,并返回SUCCESS;否则,返回UNSUCCESS int c=0; int p=indexFor(Hash(K),H.size); / 求得哈希地址while(H.elemp|H.elemp=DELKEY)&!Equals(K,H.elemp- id)/H.elemp=DELKEY 标志的被删除过 / 该位
13、置中填有记录并且关键字不相等 c+; if(cid) returnH.elemp; / 查找成功,p返回待查数据元素位置 else return NULL; / 查找不成功(H.elemp.id=NULLKEY) 5、 增加、修改:/以按id查找为例/*增加:现在哈希表中查找,如果要增加元素不存在,探测,插入,否则插入失败修改:现在哈希表中查找,再进行修改,涉及到的主要函数代码在前面已经给出,不在重复给出*/6、 数据交互(java C+):/以其中一个函数为例java本地方法: public static native Object deleteById(String id); /C+实现方
14、法JNIEXPORT jobjectArray JNICALL Java_cn_xiaodeng_dao_utils_DataProcessUtils_deleteById (JNIEnv *env, jclass _j_class, jstring id) /实现代码注:在java与C+交互中涉及到数据转换,相关函数不在此处给出【运行结果展示】1. 主界面2. 排序(以数量从高到低为例)3.按范围查找:(以价格为例)4.查找:(按名称、编号查找)5.按名称、编号删除,添加6.修改:【算法评估】 增:直接插在表头或尾O(1),指定位置或者按顺序(升、降)表O(n);删:改进后(建立在查的基础上
15、) 改(建立在查的基础上):按id:按名称:O(n)查(建立在查的基础上):按id:按名称:O(n) 排序:最好n,(实质就是快速排序)【总结及提升】1.处理装填因子的时候抛出异常更好;2.因为存的是地址的地址,故而先检验该地址是否为空;3.是否正负或者整数,不应该有底部CPP空值,CPP需要做的只是操作安全上的维护,管理数据即可,因为它可能服务的的对象并不仅仅是这个系统,而其他系统对数据的现实意义的要求可能又不一样,如果在底层处理数据的现实意义(用户自定义约束)会极大限制程序的灵活性,故而用户自定义的约束留到表层去处理;4.各个函数之间的“耦合性”;5.题目最底层的抽象就是增删改查,没有其它
16、的,用户的一切要求都可以有这些操作组合而成,因而不能将“表层”的要求影响到底层,底层应该追求最合理的的分离和抽象,这样程序上层组合的灵活性就越大;6.本地方法虽是CPP实现,但它并不是最底层,最分离的方法,它介于表层和底层之间,有分离和组合的共同特征,可以涉及少数的自定义约束,最底层的就是:数据结构,数据操作,约束条件(不带与需求相关色彩的抽象约束条件);7.为了在局部提高程序的执行效率,在底层采用了几个“分离度低”、“耦合度高”、“不择手段”的方法,主要表现在:返回、传入相关指针引用(不安全)如:ElemType* DeleteHash(HashTable&H,ElemType e);简单的
17、增加int参数区分重载,如:CommLinkList&DeleteHash(HashTable&H,ElemTypee,int tag)(代码复用性低、耦合度高、针对性太强);教学计划安排【问题描述】学校每学期开设的课程是有先后顺序的,如开设数据结构课程之前,必须开设离散数学和程序设计基础。给定课程先后顺序如下图所示,选择物理存储方式,存储该课程关系图。编程实现拓扑排序算法,合理安排开设各门课程的先后顺序。【基本要求】1、 实现问题描述中所有需求;2、 从文件中读取数据;【设计方案】点信息用一条单向链表储存,每个顶点又是一个“头结点”,依附于每个顶点的是它的先修课:依附于该顶点的众多结点中,如
18、果某个结点的入度变为零,则该顶点的入度减一,直至该顶点的入度为零,它所依附的结点入度也减一.直至判定完毕。系统架构图【实现】整体规划设计思路在顶点信息链表中,每个顶点又是一个“头结点”,依附于每个顶点的是它的先修课,那么就应该注意到在逻辑上是:依附于该顶点的众多结点中,如果某个结点的入度变为零,则该顶点的入度减一,直至该顶点的入度为零,它所依附的结点入度也减一.直至判定完毕。现实意义就是:一门课的先修课都被选修了,这门课也就可以选修了,而同时它也可能作为其它课程的先修课,因而它的选修也进一步影响到以它作为先修课的课程。单从数据结构和时间复杂度上看,完全没必要这么做,但是,在现实中,一个老师往往
19、更了解选修自己教授的这门课需要哪些预备知识(先修课),而不是这门课会作为哪些课程的先修课。 说明 a.底层数据结构:执行拓扑排序;b.用户图形界面:将用户的请求转化分解为对底层的基本操作的组合,将处理结果显示在图形界面上;逻辑结构/课程结构体typedefstructVertexType jstringnum; jstring name; jstringpnum;/先修课程号VertexType;structVNode;/前向声明typedefstructArcNode VNode* adjvex; / 该弧所指向的顶点的指针 ArcNode *nextarc; / 指向下一条弧的指针 Arc
20、Node; / 表结点 typedefstructVNode VertexType data; / 顶点信息 ArcNode *firstarc;/ 第一个表结点的地址,指向第一条依附该顶点的弧的指针 VNode *next; intindegree; *AdjList; / 头结点 typedefstruct ALG AdjList vertices; jintvexnum,arcnum; / 图的当前顶点数和弧数 ALGraph;存储结构步骤搭建开发环境 a.导入开发包: dom4j beanUtils 相关文档资源包 b.创建组织程序的包 cn.xiaodeng.domain :java
21、bean cn.xiaodeng.dao cn.xiaodeng.dao.impl: 数据访问对象(Data Acess Object) cn.xiaodeng.app.controller :处理请求 cn.xiaodeng.app.UI : 给用户提供界面 cn.xiaodeng.utils :工具 cn.xiaodeng.exception :异常处理 junit.test c.创建代表数据库的 xml 文件编程实现1、读取数据,建双顶点信息表、建有向图将”#C1012#C5652#”形式的记录中课程编号提取出来,建有向图说明:除处理”#”外,其它算法思想来源于教材voidCreateA
22、LG(ALGraph&G) G.vexnum=ListLength(G.vertices); AdjList p=G.vertices-next; while(p) ArcNode *q=NULL;/必须显式的置NULL boolisFisrt=true; char *pnums=JstringToCharP(p-data.pnum); char *pnum =newcharNUMLENGTH; int index=0; while(*pnums) if(*pnums=#) if(index0) pnumindex=0; jstringjsnum=CharPToJstring(pnum); A
23、rcNode* arc=(ArcNode*)malloc(sizeof(ArcNode); arc-adjvex= LocateElem(G.vertices,jsnum); if(isFisrt=true) p-firstarc=arc; q=arc; isFisrt=false; else q-nextarc=arc; q=arc; G.arcnum+; index=0; deletepnum; pnum =newcharNUMLENGTH; else pnumindex+=*pnums; pnums+; if(q=NULL)/假如#q就不会被实例化,这是q是空的 p-firstarc=N
24、ULL; else q-nextarc=NULL; p=p-next; deletepnum; 2、求入度voidFindInDegree(ALGraph G) AdjList p=G.vertices-next; while(p) p-indegree=0; p=p-next; p=G.vertices-next; while(p) ArcNode *q=p-firstarc; while(q) p-indegree+; q=q-nextarc; p=p-next; p=G.vertices-next; 3、拓扑排序Status TopologicalSort(ALGraphG,jobjectArray&arrayObjectData) /初始化 FindInDegree(G); /入度为零的顶点的地址入栈 while(S.empty()=false) /弹栈,假设其课程编号为NUM +count; /遍历,所有先修课程包含NUM的课程入度减一 if(countG.vexnum) /图有会路 return ERROR;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1