库存管理系统表结构

2024-08-08

库存管理系统表结构(精选6篇)

1.库存管理系统表结构 篇一

优化库存结构、降低库存占用实施方案

当前企业物资仓储库存高居不下,库存资金占用严重,存货损失控制困难,影响企业现金流动,呆滞库存风险加大等问题迫切需要得到解决,作为物流领域的从业人员如何优化库存结构,降低库存资金占用,是当前工作的首要任务,结合工作实践对库存控制工作梳理了如下几条措施,希望对企业库存压降工作有所帮助。

一、加强物资需求计划管理、强化计划审核复核力度、努力提高计划准确率

1.库存增加的首要原因是因为计划提报依据不充分、不细致、管理不到位、审核不严格、计划准确率过低、主要负责人不重视造成,各级计划审核部门要根据生产建设用料需求实际,加强物资需求计划管理,严把审核关,确保计划准确率和到货物资领用率达到100%,此项工作的落实与执行列入主要负责人绩效考核体系,物资管理部门组织相关部门随时抽查,对没有落实到位的单位通报批评,并对主要负责人进行处罚。

二、加强平衡利库管理、避免重复采购、减少库存积压 构建MRP库存控制机制,要强化平衡利库管控,形成计划为主,采购和仓储协同配合的平衡利库工作体系,达到同一采购组相关人员共同参与利库的目的,避免重复采购,减少库存积压。

三.深入调查所需物资市场供求情况、严控物资需 1

求计划集中到货、避免因集中到货造成库存积压

由采购部门对市场进行深入调研,形成市场物资供需分析报告,对已经完成招标的物资建立供货周期表,采购部门以供货周期分析表为依据,在避免缺货损失的情况下,采取计划按需到货的发货方式,避免因相关生产建设项目变更或取消造成库存积压。

四、编制物资采购作业周期指导书、有效指导计划提报和物资发运工作

根据物资采购流程相关节点时限,编制物资采购作业周期指导书,为用料单位计划提报提供时限依据,避免因计划提报不及时造成的缺货损失和计划提报过早造成的库存增加,减少缺货成本和仓储成本。

五、构建一物多码控制机制、确保物资编码的唯一性 应用物资ERP系统的企业,要立即开展重码物资清理工作,对库存物资数据进行优化,建立一物多码物资数据统计通报制度,以本企业物资数据为依据,编制通用物资编码使用手册,指导计划提报时物资编码的选用,让平衡利库的数据更加准确,杜绝因一物多码现象造成库存积压。

六、启动物资计划提报和物资主数据管理、物资消耗管理从业人员素养提升计划

按照物资管理工作实施计划,组建物资从业人员素养提升培训团队,全面提高物资系统从业人员业务水平,减少因从业人员素质不高、数据选择不准确、系统操作不熟练、物资通用性和替代性不清楚造成的库存积压。

七、加强对三年以上库龄库存物资的分析、鉴定、调剂和优化工作

全面梳理分析积压库存形成的原因、积压物资的品类属性、类别,形成分析报告,组织专业人员对呆滞库存物资进行分析和鉴定,让呆滞的库存动起来、活起来、减少库存资金占用。

八、全面构建机电设备全生命周期管理体系 机电管理部门会同设备使用单位对设备的运行生命周期进行分析和研究,对即将淘汰和报废的设备建立通报和预警机制,有效指导备品备件的计划提报和采购工作,为机电设备的备件储备提供可靠依据,避免因设备淘汰和报废造成的物资积压。

九、积极推行寄售采购模式、拓展寄售范围

对物资品类属性进行全面分析、积极推行通过公开招标形成的寄售采购,将广电器材、金属材料制品、起重搬运设备、工具、办公用品、杂品、仪器仪表、油脂、劳保用品与消防器材等物资采购纳入到寄售采购范畴,利用科学合理的采购方式,使库存压降到最低。

十、搭建库存信息共享平台、对各用料单位的库存进行统一调配

利用企业物资查询平台使各用料单位的库存物资信息实现共享,使相关单位的库存物资能够顺畅流动、合理调剂,达到互通有无的目的,减少积压的可能。

十一、科学制定物资储备定额

根据企业生产用料实际情况,设定各类别物资安全库存量、最低和最高库存量、使储备定额更加科学合理,既能满足用料需求,又能避免存储损失。

十二、加强库存物资盘点、及时处理呆滞物料 建立有效盘点机制,使盘点工作常态化,对呆滞的物料及时处理,制定呆滞物料处理计划,特别是及时处理贵重的呆滞物料,避免因处理不及时造成的存货损失。

十三、全面推行仓库7S现场管理模式、提高库存物资周转效率

引进推行仓库7S现场管理模式将仓库的整理、整顿、清扫、清洁、素养、安全、节约七项工作进行到底,合理规划库房和货位布局得,提升仓库管理人员整体素养,拓展优化库存结构与降本增效工作理念,提高工作效率,改善物资在库周转率,缩短作业周期,实现仓库现场管理与降本增效工作有机结合,消除积压物品,提高经济效益,降低管理成本。

2.库存管理系统表结构 篇二

对客观事物未来发展状况的分析、估计、设想和推断称为预测。预测的目的是对未来事物的发展做出科学的估计,从而掌握事物的发展规律,为制定政策、拟订规划等重大决策提供科学依据。

时间序列预测法就是利用过去的历史数据,推断未来事物的发展规律。它有下面两个基本特点:一是承认事物发展的延续性。二是承认事物发展的不规律性,它不考虑事物发展的因果关系。因此,这种方法本身着眼于如何消除事物发展不规律因素(偶然性因素)的干扰和影响,把时间序列作为随机变量序列,运用数学平均或加权平均的方法,作出趋势预测。

航空器材的库存管理在很大程度上需要掌握器材的消耗规律,从而为合理地确定库存结构提供依据。由于航材的消耗随机性比较大,我们又积累了长期的器材消耗数据,因此,应用时间序列预测法可以很好地掌握库存器材的消耗规律。

1 时间序列预测法

常用的时间序列预测法有简单滑动平均法、加权滑动平均法和指数平滑法。

1.1 简单滑动平均法

简单滑动平均法是假定预测事物的未来状况只与邻近几期的状况有关,而与较远期的状况无关,因此,只要选用近期的几个数据加以数学平均,即可预测下期的数据。

其预测模型如下:

式中:Vt———第t个周期(年)的实际值;

Ft+1———第(t+1)个周期(年)的预测值;

n———与预测期邻近的有关的周期(年)数。

式(1)是把过去的数据对预测值的影响等同看待。预测期数n可以根据实际数据情况选取。

1.2 加权滑动平均法

简单滑动平均法把过去数据对预测值的影响作用等同看待,实际上远近不同的历史数据对预测值的影响作用是不同的。一般来说,距预测期越近的数据的影响作用越大,为了加强近期数据的作用,提高预测的准确程度,将简单滑动平均法修正为加权滑动平均法,则式(1)计算方法可修正如下:

式中,Wt是与Vt对应的权重。式(2)为加权滑动平均法的预测模型。

1.3 指数平滑法

由于最近的观测值对未来事件的预测影响作用比较大,所以这些最近的观测值应该比旧的观测值得到更多的权重。指数平滑法可以任意选择近期数据的权值,但是并未完全忽视远期数据的作用。这种方法也可以说是滑动平均法的一种改进型。

指数平滑法假定越久远的数据对预测的相关性越差,因而应该给予较低的权重。有时,指数平滑法按照数据的“年龄”增长给予一系列递减的权重。如图1所示。

可以通过采用最近一期的实际需求数据和以前各期的预测数据来达到这样一种权重递减效果。我们可以给最新的需求数据权重α,给前一期的预测值权重1-α来做出新一期的预测,所以指数平滑法的预测模型为:Ft+1=αVt+(1-α)Ft(3)

式中α称为平滑系数,其值介于0与1之间,(0<α<1)。

式(3)又可写成Ft+1=Ft+α(Vt-Ft)

式(3)中的Ft又可写成Ft=αVt-1+(1-α)Ft-1

而Ft-1=αVt-2+(1-α)Ft-2

…………

如此连续推算下去,然后再将不同期的预测值代入式(3),展开后得Ft+1=αVt+α(1-α)Vt-1+α(1-α)2Vt-2+…(4)

由式(4)可以看出指数平滑法实际上随着数据的“变老”,而给予越来越低的权重。另外,式中α值的大小要根据实际情况选取,如果要加强近期数据的作用,α值可取的大些。[1]

2 误差度量方法

预测精度是用误差来衡量的,衡量预测误差的方法包括误差均值、离差绝对数均值和误差平方均值。[2]设:

t表示时间;Vt表示时间t的实际值;Ft表示时间t的预测值;n表示与预测期邻近的有关的周期(年)数;Et表示预测值和实际值的误差。

2.1 误差均值如果Ft是时间t时的预测值,Vt是同一时间的实际值,则误差为:Et=Vt-Ft

如果我们在若干期,比如n期中重复这一计算,则计量预测误差的方法便是误差均值:误差均值=

误差均值的一个缺点是正的误差和负的误差会相互抵消,从而,精确性很差的预测,误差均值也可能很小。但它会度量出预测的偏态。如果误差均值是正值,说明预测值偏低,如果误差均值是负值,说明预测值偏高。

2.2 离差绝对数均值

离差绝对数均值的含义很明确:它说明预测值与实际值的平均差距。

3 应用时间序列分析法预测航材的消耗规律

某单位从2002~2010年间每年的刹车钢圈的实际消耗数据如表1,下面利用时间序列分析法中的各种预测法,对该项器材2011年的消耗数进行预测。并比较各种方法的优劣,选出最优方法和最优参数。

3.1 滑动平均法

首先,运用简单滑动平均法(取n=3、n=4、n=

5、n=6)和加权滑动平均法(n=3,权重分别为3、2、1)计算其预测数据,如表2。

根据表2的结果描绘出时间序列分析图,如图2。

3.2 指数平滑法

下面,我们再用指数平滑法对上例进行计算。分别取α=0.1~0.9,计算每期的预测值。

根据表3中的结果描绘成时间序列分析图,如图3。

从表3和图3可以看出,平滑系数α的值非常关键,它决定了预测值对变化的敏感性:(1)较高的α值(比如说0.7~0.9)给最新的实际需求值比较大的比重,从而使预测对新的变化更为强烈。(2)较低的α值(比如说0.1~0.3)给前期的预测值以更多的比重,从而使预测值对新的变化反映性较差。

4 误差分析

下面我们用离差绝对数均值对上例中滑动平均法和指数平滑法预测的结果进行计算和分析。将历史数据的预测误差均值作为2011年的预测误差。

(单位:个)

由表4可知,当n=6时误差较大,n=3时误差较小,说明近期数据对预测影响较大;由加权滑动平均法的计算结果也可得出同样的结论。所以,该例适合应用加权滑动平均法进行预测,并应给近期数据以较大的权重。即2011年的预测值为182±21个。

(单位:个)

由表5可以看出,当α较小时,误差较大,而α较大时,误差也较大,说明预测结果依赖于上期的实际消耗值和预测值。所以在本例中,若应用指数平滑法,α取0.5~0.6比较合适。若取α=0.5,也就是将上期的预测值和实际值的平均值作为下一期的预测值。所以,本例应用指数平滑法α取0.5时的预测结果为179±22个。

5 结论

从以上对2011年器材消耗情况的预测和分析,我们得出如下结论:(1)简单滑动平均法将历史数据不论其距预测时间远近都等同看待,取其简单平均值,往往使结果偏差较大。但这种方法比较简单,在有足够的有价值的实际数据时,对随机波动不大的事物进行预测有一定的实用价值。(2)加权滑动平均法在这方面做了改进,给各期数据以不同的权数,距预测期近的影响大,权值大;反之则小。把求得的加权平均数作为预测值,权值的选择和分配是任意的,实用中要经过反复应用检验,选择加权值使预测值尽可能接近实际值为原则。(3)指数平滑法比加权滑动平均法更为灵活,增强了主观性,适用于数据量较少情况下的预测。(4)指数平滑法的应用主要是确定α值,它的选定主要取决于实际情况,主观因素、定量表达和定性估计也影响α值的确定。

综上所述,时间序列预测法在实际应用中,应结合实际情况,选择合适的参数,使得预测误差最小。

摘要:航空器材的库存结构受许多因素影响,如何使库存结构合理是航材管理人员长期以来一直在探索的问题。时间序列预测法就是利用过去的历史数据,推断未来事物的发展规律,它可以消除随机因素对库存数量的影响,使预测更加准确,从而使航材管理人员作出更加合理的决策。

关键词:历史数据,预测数量,决策

参考文献

[1]唐纳德.沃特斯著.管理科学实务教程.北京:华夏出版社,2000:125-148.

3.酒店工资结构方案表 篇三

级别岗位工资(60%)考核工资(40%)绩效工资工资标准合计元)

总助总监A16201080根据各部门经营指标的完成情况,将部门超额或未完成的部分按比例分配到部门,由部门根据员工日常工作表现进行二次分配。2700

B14409602400

C12608402100

D10807201800

部门经理级A9006001500

B8405601400

C7805201300

D7204801200

E6604401100

主 管级A7204801200

B6604401100

C6004001000

D540360900

E480320800

领班级A528352880

B492328820

C456304760

D420280700

384256640

员工级A420280700

B390260650

C360240600

D330220550

E300200500

临时工实习生清洁工A300200500

B240160400

C180120300

备注:

1.一线部门:营销部、餐饮部、房务部

二线部门:办公室、财务部、采购部、工程部

2.职务说明:

1)主管级包括各部门主管、经理助理、大堂副理、销售经理、餐厅经理、主办会计。

2)领班级包括各部门领班、销售代表、美工摄影、成控会计、总出纳、收入审计、明细帐会计、信贷会计、电脑维护员、兼职文员。

3.新入店员工,试用期三个月,工资标准在500元/月以上的试用期工资按工资标准的80%执行,工资标准在500元/月以下的按照300元/月试用。

4.清洁工、杂工、临时工及在校实习生的工资按300元执行,试用期三个月,转正后按400元/月执行。

工 资 管 理 方 案

为进一步完善酒店薪酬体系,提高酒店内部竞争力,根据酒店的经营管理方针,现制定出东方瑞景国人大酒店《工资管理暂行办法》如下:

1.酒店实行岗位工资制,即根据不同岗位、不同职务、不同工种的差别和技能的高低及对酒店的贡献确定工资级别。

2.酒店对员工工资实行动态管理,以岗位要求制订工资标准,以工作绩效体现工资差别,即根据员工个人表现和贡献可升可降。

3.各级员工享受相应级别的工资,对成绩突出、有特殊贡献者经部门推荐,人力资源部考核,总经理批准后,可破格享受所担任职务的最上线工资。

4.工资构成:月工资总额=岗位工资+考核工资+相关补贴+绩效工资

1)岗位工资:是根据酒店各岗位的工作标准、岗位职责所设置,是员工的一项基本收入保障。岗位工资=工资总额×60%

2)考核工资: 根据酒店整体效益、部门绩效所设置,与员工的月度绩效、日常奖惩挂钩,发放额随各部门每月的绩效考核情况、人员岗位编制情况上下浮动。考核工资=工资总额×40%

3)相关补贴:

a)夜班津贴:根据部门排班情况,凡正常排班情况下在24:00以后下班的夜班人员(含实习生),享受每天2元的夜班津贴。

b)店龄补贴:自入职起每满一年,每月补贴20元,并依次类推。

c)英语补贴:凡经省市级旅游局考核认证,通过英语等级考核合格且取得相应级别证书者,按相应的英语等级,当年每月享受英语补贴——A级:10元,B级:8元,C级:5元。如再参加第二次考核不及格者则取消。

d)技术补贴:酒店将对持有有关技术证(经劳动部门鉴定认可的)且得到酒店认可其技术(经酒店考核)的技术工种(如工程人员、厨师等)增加相应的技术补贴。由部门每年对试用期已转正的技术人员进行技术等级考核,并按照考核情况按比例评定出各技术人员的技术等级报人力资源部。酒店根据其技术等级当年每月发放技术补贴——A级:80元,B级:50元,C级:30元。(技术等级每年考核一次,按每年技术等级考核情况发放技术补贴)e)医疗补贴:酒店每月为员工发放30元的医疗补贴。

f)交通补贴:酒店为非住店乘坐公交车上下班的员工提供交通补贴,单站往返的补贴50元,中转一站以上的补贴80元。

4)绩效工资:根据各部门经营指标的完成情况,将部门超额或未完成部分按比例分配到部门,由部门根据员工日常工作表现进行二次分配。

5.月实际工资计算方法:月工资总额÷30天×实际出勤天数(含有薪假)

6.试用期工资:

1)员工入店须经三个月试用,工资标准在500元/月以上的试用期工资为工资标准的80%,工资标准在500元/月以下的按照300元/月试用。

2)新招聘管理人员试用期工资享受所在职务最低工资标准的80%,试用期三个月。

3)内部晋升人员试用期工资增加增资额的50%,原则上逐级晋升,试用期一个月。

7.工资调整:

1)员工因试用期满、职务升降需调整工资时,经部门同意,人力资源部考核,总经理批准后方可执行。

2)员工试用期满转正,原则上从员工E级起逐级调资,调资间隔不少于三个月。计算公式:月工资总额= 调整前月工资总额÷26天×实际出勤天数+调整后月工资总额÷26天×实际出勤天数

3)各级员工均享受相应级别的工资待遇,对成绩突出、有特殊贡献者由部门以业绩报告形式进行推荐,人力资源部考核,总经理批准后,可破格提升一级工资并进行公开表彰;对出现重大失误,连续两次列为部门考核最差者,经部门申请,人力资源部考核,总经理批准后,给予降薪一级直至开除处分。对员工工资的上调和下浮,原则上一年不超过三次,一次不超过两级。

8.缺勤扣款:

1)事假不发薪。

2)病假期工资,五天内每天发日工资标准的40%,超过五天每天扣日工资额的100%。

3)婚假:男女双方达到结婚年龄并按规定办理结婚登记手续,依法领取结婚证明,除按规定的3天婚假外,晚婚者(男25周岁、女23周岁)增加婚假7天(含周六周日),期间当日工资每天按12元发放,超过10天者按事假处理,未办理续假手续者,按旷工处理。

4)工伤期间工资:凡符合工伤条件的,假期均以市级以上医院开具的休假证明为准,按照岗位工资的100%标准发放当日工资。

5)产假工资:按照国家有关规定执行。

6)年假、公休假均不影响工资。

7)慰唁假工资:如员工之直系亲属(指配偶、子女、父母、兄弟、姐妹、配偶之父母、祖父母和外祖父母)不幸逝世,可申请三天有薪慰唁假,假期内(三天)按工资标准的100%支付工资,超假部分按事假处理。

8)迟到/早退:扣款办法按《处罚细则》有关规定执行。

9)凡属旷工性质,以旷工时间的总工资三倍予以扣款。

6.加班工资:根据行业性质,酒店实行综合工时制,员工可在季度内跨月调休/补休,但不允许跨季度调休/补休,各部门必须根据经营管理情况做好每月排班并认真审核,季度内可调休/补休的,一律调休/补休。如确因工作需要不能调休的,由部门总监/经理批准,人力资源部审核、总经理批准后方可按规定发放加班工资。(原则上日常加班以补休形式进行安排,如确因工作需要,当日部门需安排加班的,应事先填写《加班申请单》,经部门总监、总经理批准后方可安排加班)

1)月工资合计在1500元以上的人员无加班工资(节假日除外),由部门根据情况安排补休。

2)其他员工在法定节假日加班,工作一天补休一天,或按有关规定计发加班费。非法定节假日加班原则上安排补休。

7.工资结算:酒店每月15日将上月工资总额存入个人银行帐户,遇节假日提前发放。

8.离店工资结算:

1)正式员工:月工资总额÷26天×离店前出勤天数

2)新员工入职未满一周离职者不享受工资待遇。

9.备注:

1)此方案自下发之日起执行,原下发的规定与此方案不一致的,以此方案有关规定为准,方案中未涉及到原有内容的,仍按原有规定执行。

4.线性表的链式存储结构实验报告 篇四

课程名称:数据结构与算法分析 实验名称:链表的实现与应用

实验日期:2015.01.30 班级: 数媒1401 姓名: 范业嘉 学号 1030514108

一、实验目的

掌握线性表的链式存储结构设计与基本操作的实现。

二、实验内容与要求

⑴定义线性表的链式存储表示;

⑵基于所设计的存储结构实现线性表的基本操作;

⑶编写一个主程序对所实现的线性表进行测试;

⑷线性表的应用:①设线性表L1和L2分别代表集合A和B,试设计算法求A和B的并集C,并用

线性表L3代表集合C;②(选做)设线性表L1和L2中的数据元素为整数,且均已按值非递减有序排列,试设计算法对L1和L2进行合并,用线性表L3保存合并结果,要求L3中的数据元素也按值非递减有序排列。

⑸设计一个一元多项式计算器,要求能够:①输入并建立多项式;②输出多项式;③执行两个多项式相加;④执行两个多项式相减;⑤(选做)执行两个多项式相乘。

三、数据结构设计

1.按所用指针的类型、个数、方法等的不同,又可分为:

线性链表(单链表)

静态链表

循环链表

双向链表

双向循环链表

2.用一组任意的存储单元存储线性表中数据元素,用指针来表示数据元素间的逻辑关系。

四、算法设计

1.定义一个链表

void creatlist(Linklist &L,int n){ int i;Linklist p,s;L=(Linklist)malloc(sizeof(Lnode));p=L;L->next=NULL;for(i=0;i

s=(Linklist)malloc(sizeof(Lnode));

scanf(“%d”,&s->data);

s->next=NULL;

p->next=s;

p=s;

/ 8

} } 2.(1)两个链表的合并

void Mergelist(Linklist &La,Linklist &Lb,Linklist &Lc){ Linklist pa,pb,pc;pa=La->next;pb=Lb->next;Lc=pc=La;while(pa&&pb){

if(pa->data<=pb->data)

{pc->next=pa;pc=pa;pa=pa->next;}

else {pc->next=pb;pc=pb;pb=pb->next;} } pc->next=pa?pa:pb;free(Lb);}(2)两个链表的并集

Linklist unionlist(Linklist &La,Linklist &Lb){ Linklist p1,p2,head,q,s;int flag;head=q=(Linklist)malloc(sizeof(Lnode));p1=La->next;while(p1){

flag=0;

p2=Lb->next;

while(p2)

{

if(p1->data==p2->data)

{

flag=1;

break;

}

p2=p2->next;

}

if(flag==0)

{

s=(Linklist)malloc(sizeof(Lnode));

s->data=p1->data;

q->next=s;

q=s;

}

p1=p1->next;/ 8

}

q->next=Lb->next;return head;

}

3.(1)一元多项式的加法

List addpoly(List pa,List pb)

//一元多项式的加法 { int n;List pc,s,p;pa=pa->next;pb=pb->next;pc=(List)malloc(sizeof(struct Linklist));pc->next=NULL;p=pc;while(pa!=NULL&&pb!=NULL){

if(pa->expn>pb->expn)

{

s=(List)malloc(sizeof(struct Linklist));

s->expn=pa->expn;

s->coef=pa->coef;

s->next=NULL;

p->next=s;

p=s;

pa=pa->next;

}

else if(pa->expn

expn)

{

s=(List)malloc(sizeof(struct Linklist));

s->expn=pb->expn;

s->coef=pb->coef;

s->next=NULL;

p->next=s;

p=s;

pb=pb->next;

}

else

{

n=pa->coef+pb->coef;

if(n!=0)

{

s=(List)malloc(sizeof(struct Linklist));

s->expn=pa->expn;/ 8

s->coef=n;

s->next=NULL;

p->next=s;

p=s;

}

pb=pb->next;

pa=pa->next;

} } while(pa!=NULL){

s=(List)malloc(sizeof(struct Linklist));

s->expn=pa->expn;

s->coef=pa->coef;

s->next=NULL;

p->next=s;

p=s;

pa=pa->next;} while(pb!=NULL){

s=(List)malloc(sizeof(struct Linklist));

s->expn=pb->expn;

s->coef=pb->coef;

s->next=NULL;

p->next=s;

p=s;

pb=pb->next;} return pc;}

(2)一元多项式的减法

List subpoly(List pa,List pb)

//一元多项式的减法 { int n;List pc,s,p;pa=pa->next;pb=pb->next;pc=(List)malloc(sizeof(struct Linklist));pc->next=NULL;p=pc;while(pa!=NULL&&pb!=NULL){

if(pa->expn>pb->expn)

/ 8

{

s=(List)malloc(sizeof(struct Linklist));

s->expn=pa->expn;

s->coef=pa->coef;

s->next=NULL;

p->next=s;

p=s;

pa=pa->next;} else if(pa->expn

expn){

s=(List)malloc(sizeof(struct Linklist));

s->expn=pb->expn;

s->coef=-pb->coef;

s->next=NULL;

p->next=s;

p=s;

pb=pb->next;} else {

n=pa->coef-pb->coef;

if(n!=0)

{

s=(List)malloc(sizeof(struct Linklist));

s->expn=pa->expn;

s->coef=n;

s->next=NULL;

p->next=s;

p=s;

}

pb=pb->next;

pa=pa->next;} } while(pa!=NULL){ s=(List)malloc(sizeof(struct Linklist));s->expn=pa->expn;s->coef=pa->coef;s->next=NULL;p->next=s;p=s;pa=pa->next;} / 8

while(pb!=NULL){

s=(List)malloc(sizeof(struct Linklist));

s->expn=pb->expn;

s->coef=-pb->coef;

s->next=NULL;

p->next=s;

p=s;

pb=pb->next;} return pc;}(3)一元多项式的乘法

void mulpolyn(polynomail pa,polynomail pb,polynomail &pc){

LNode *p,*q,*s,*hc;p=pa->next;q=pb->next;hc=pc;while(p!=NULL){

while(q!=NULL)

{

s=(polynomail)malloc(sizeof(LNode));

hc->next=s;

hc=hc->next;

hc->coef=q->coef*p->coef;

hc->expn=q->expn+p->expn;

q=q->next;

}

p=p->next;

q=pb->next;} hc->next=NULL;}

/ 8

五、测试结果

2.3.7 / 8

六、心得体会(包括对于本次实验的小结,实验过程中碰到的问题等)

1.首先书上给的链表输入是倒序的,写的时候想都没想就抄上去了,结果运行时发现问题,可是上网百度依然没有把问题解决,导致最后输出链表倒序的,并且链表的合并并集依旧是倒序的。

2.当写一元多项式的加减时,前提是弄清楚各种情况,系数相同时就相加减,系数不同就保留原有多项式;当系数相加减为0时,就free这个节点。在做减法时,我考虑到了减数与被减数之间的关系。

3.在做多项式时,我准备按照书上的算法一个一个写小函数,结果到最后发现写不下去了,就去问问同学和上网看看,结果感觉写这个数据结构的程序其实不必想麻烦了,只是指针,数组的高级运用。

5.C实现通用数据结构单链表 篇五

1、list_init

void list_init(List *list, void (*destroy)(void *data));

返回值void

描述初始化由参数list指定的链表,该函数必须在链表做其他操作之前调用,当调用list_destroy时,destroy参数提供了一种释放动态分配数据的方法,如果链表采用malloc动态分配的数据,destroy应该设置为free来释放这些数据

复杂度O(1)

2、list_destroy

void list_destroy(List *list);

返回值void

描述销毁由参数list指定的链表,调用该函数以后任何函数都不能再执行,除非重新执行list_init函数。list_destroy将list中的所有元素都移除,每移除一个元素都会调用此函数

复杂度O(n)n为链表元素的个数

3、list_ins_next

int list_ins_next(List *list, ListElmt *element, const void *data);

返回值如果插入元素成功返回0,否则返回-1

描述在指定的list的element元素后面插入一个元素,如果element为NULL,则在链表的头部插入新的元素,该元素包含一个指向data的指针

复杂度O(1)

4、list_rem_next

int list_rem_next(List *list, ListElmt *element, void **data);

返回值如果移除元素成功返回0,否则返回-1

描述移除在指定的list的element后面的那个元素,如果element为NULL,则移除链表的头元素,调用返回后,data指向已经移除元素的数据

复杂度O(1)

5、list_size

int list_size(const List *list);

返回值如果list中元素的个数

描述这是一个宏,用来计算指定list中元素的个数

复杂度O(1)

6、list_head

ListElmt *list_head(const List *list);

返回值指向链表头元素的指针

描述这是一个宏,返回由参数list指定的链表头元素的指针

复杂度O(1)

7、list_tail

ListElmt *list_tail(const List *list) ((list)->tail);

返回值指向链表尾元素的指针

描述这是一个宏,返回由参数list指定的链表尾元素的指针

复杂度O(1)

8、list_is_head

int list_is_head(const ListElmt *element);

返回值如果element元素是链表头元素返回0,否则返回-1

描述这是一个宏,用来判断element元素是否是list的头元素

复杂度O(1)

9、list_is_tail

int list_is_tail(const ListElmt *element);

返回值如果element元素是链表尾元素返回0,否则返回-1

描述这是一个宏,用来判断element元素是否是list的尾元素

复杂度O(1)

10、list_data

void *list_data(const ListElmt *element);

返回值结点中保存的数据

描述这是一个宏,返回由element元素中保存的数据

复杂度O(1)

11、list_next

ListElmt *list_next(const ListElmt *element) ;

返回值返回element所指定结点的下一个结点

描述这是一个宏,返回链表中element所指定结点的下一个结点

复杂度O(1)

单链表的实现和分析

抽象数据类型的头文件(list.h):

#ifndef LIST_H

#define LIST_H

#include

//为单链表的结点定义一个结构体.

typedef struct ListElmt_ {

void*data;//数据域

struct ListElmt_*next;//指针域

} ListElmt;

//为单链表定义一个结构体.

typedef struct List_ {

intsize;//容量

int(*match)(const void *key1, const void *key2);//匹配函数

void(*destroy)(void *data);//撤销操作

ListElmt*head;//头指针

ListElmt*tail;//尾指针

} List;

//公共接口

void list_init(List *list, void (*destroy)(void *data));

void list_destroy(List *list);

int list_ins_next(List *list, ListElmt *element, const void *data);

int list_rem_next(List *list, ListElmt *element, void **data);

#define list_size(list) ((list)->size)

#define list_head(list) ((list)->head)

#define list_tail(list) ((list)->tail)

#define list_is_head(list, element) ((element) == (list)->head ? 1 : 0)

#define list_is_tail(element) ((element)->next == NULL ? 1 : 0)

#define list_data(element) ((element)->data)

#define list_next(element) ((element)->next)

#endif

初始化单链表:

void list_init(List *list, void (*destroy)(void *data)) {//初始化list

list->size = 0;

list->destroy = destroy;//设置为定义的析构函数

list->head = NULL;

list->tail = NULL;

return;

}

回收单链表:

void list_destroy(List *list) {

//移除每一个元素

while (list_size(list) >0) {

if (list_rem_next(list, NULL, (void **)&data) == 0 && list->destroy != NULL) {//不断地移除链表的头结点

list->destroy(data);//调用一个用户定义的函数来释放动态分配的数据.

}

}

//现在没有操作了,释放结构体作为预防措施

memset(list, 0, sizeof(List));

return;

}

插入新节点作为指定结点的直接后继结点:

int list_ins_next(List *list, ListElmt *element, const void *data) {

ListElmt *new_element;//为结点动态分配存储空间

if ((new_element = (ListElmt *)malloc(sizeof(ListElmt))) == NULL)//假如分配失败

return -1;

// 将元素插入链表

new_element->data = (void *)data;

if (element == NULL) {

//插入到链表的头部

if (list_size(list) == 0)

list->tail = new_element;

new_element->next = list->head;

list->head = new_element;

} else {

//插入到除了链表头部以外指定的其他地方

if (element->next == NULL)

list->tail = new_element;

new_element->next = element->next;

element->next = new_element;

}

list->size++; //表长增加

return 0;

}

删除指定结点的直接后继结点:

int list_rem_next(List *list, ListElmt *element, void **data) {

ListElmt *old_element;

//不允许从一个空的list中移除元素.

if (list_size(list) == 0)

return -1;

// 从list中移除元素.

if (element == NULL) {

// 移除表头的结点.

*data = list->head->data;

old_element = list->head;

list->head = list->head->next;

if (list_size(list) == 1)//如果list只有一个元素,则直接删除尾结点

list->tail = NULL;

} else {

// 移除非头结点.

if (element->next == NULL)

return -1;

*data = element->next->data;

old_element = element->next;

element->next = element->next->next;

if (element->next == NULL)//移除指定结点后,后继为NULL,则用尾结点指向

list->tail = element;

}

//释放分配的抽象数据类型.

free(old_element);

//调整list的长度.*

list->size--;

return 0;

}

注意:list_size、list_head、list_tail、list_is_head、list_is_tail、list_data、list_next 这些宏实现了链表中的一些简单操作,它们提供了快速访问和检测结构体成员的能力,

这些操作的时间复杂度都是O(1)

完整的测试代码如下:

// Completed on .10.22 21:00

// Language: C99

//

// 版权所有(C)codingwu(mail: oskernel@126.com)

// 博客地址:www.cnblogs.com/archimedes/

#include

#include

#include “list.h”

static void print_list(const List *list) {

ListElmt *element;

int *data, i;

fprintf(stdout, “List size is %d ”, list_size(list));

i = 0;

element = list_head(list);

while (1) {

data = list_data(element);

fprintf(stdout, “list[%03d]=%03d ”, i, *data);

i++;

if (list_is_tail(element))

break;

else

element = list_next(element);

}

return;

}

int main(int argc, char **argv) {

List list;

ListElmt *element;

int *data, i;

//初始化list

list_init(&list, free);

element = list_head(&list);

for (i = 10; i >0; i--) {

if ((data = (int *)malloc(sizeof(int))) == NULL)

return 1;

*data = i;

if (list_ins_next(&list, NULL, data) != 0)//逐个插入元素

return 1;

}

print_list(&list);//打印初始list

element = list_head(&list);//指向头结点

for (i = 0; i < 7; i++)

element = list_next(element);

data = list_data(element);

fprintf(stdout, “Removing an element after the one containing %03d ”, *data);

if (list_rem_next(&list, element, (void **)&data) != 0)//删除指定结点

return 1;

print_list(&list);

fprintf(stdout, “Inserting 011 at the tail of the list ”);

*data = 11;

if (list_ins_next(&list, list_tail(&list), data) != 0)//插入指定结点

return 1;

print_list(&list);

fprintf(stdout, “Removing an element after the first element ”);

element = list_head(&list);

if (list_rem_next(&list, element, (void **)&data) != 0)

return 1;

print_list(&list);

fprintf(stdout, “Inserting 012 at the head of the list ”);

*data = 12;

if (list_ins_next(&list, NULL, data) != 0)

return 1;

print_list(&list);

fprintf(stdout, “Iterating and removing the fourth element ”);

element = list_head(&list);

element = list_next(element);

element = list_next(element);

if (list_rem_next(&list, element, (void **)&data) != 0)

return 1;

print_list(&list);

fprintf(stdout, “Inserting 013 after the first element ”);

*data = 13;

if (list_ins_next(&list, list_head(&list), data) != 0)

return 1;

print_list(&list);

i = list_is_head(&list, list_head(&list));

fprintf(stdout, “Testing list_is_head...Value=%d (1=OK) ”, i);

i = list_is_head(&list, list_tail(&list));

fprintf(stdout, “Testing list_is_head...Value=%d (0=OK) ”, i);

i = list_is_tail(list_tail(&list));

fprintf(stdout, “Testing list_is_tail...Value=%d (1=OK) ”, i);

i = list_is_tail(list_head(&list));

fprintf(stdout, “Testing list_is_tail...Value=%d (0=OK) ”, i);

fprintf(stdout, “Destroying the list ”);

list_destroy(&list);

return 0;

6.线性表的动态分配存储结构分析 篇六

1 引入线性表动态分配的源由

在数据结构中, 数据的逻辑结构分为线性结构和非线性结构, 非线性结构中又以线性表为典型代表, 线性表的逻辑结构是通过元素之间的相邻关系体现的。因此利用数组实现线性表的顺序存储, 结构简单, 其算法也容易理解。但是, 由于存储分配只能预先定义, 如果插入的数据量超出预先分配的存储空间, 那么临时扩大就会存在很大的困难;如果按最大的可能空间进行分配, 则势必降低了存储空间的利用率。为解决此问题, 可以利用C语言动态分配内存的机制, 实现线性表的顺序存储。

2 动态分配顺序存储结构的基本操作

2.1 动态分配的顺序存储结构的描述

线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。线性表是一个相当灵活的数据结构, 它的长度可根据需要增长或缩短, 即对线性表的数据元素不仅可以进行访问, 还可以进行插入和删除等。由于高级程序设计语言中的数据类型也有随机存取的特性, 因此, 通常都用数组来描述数据结构中的顺序存储结构。在此, 由于线性表的长度可变, 且所需最大存储空间随问题的不同而不同, 则在C语言中可用动态分配的一维数组, 如下描述。

在上述定义中, 顺序表的初始化操作就是为顺序表分配一个预定义大小的数组空间, 并将线性表的当前长度设为“0”。Listsize指示顺序表当前分配的存储空间大小, 一旦因插入元素而空间不足时, 可进行再分配, 即为顺序表增加一个大小为LISTINCRE-MENT个数据元素的空间。

2.2 线性表的初始化

根据线性表结构的基本描述, 为完成对一组数据的处理, 用户根据需要定义线性表供程序使用, 则为线性表的初始化。初始化线性表是为线性表分配一个预定义的存储空间, 并将线性表的当前长度定义为零。分配一个预定的存储空间可以通过调用C语言的动态分配库函数malloc来实现。具体算法如下:

2.3 线性表某个元素的插入

从线性表的特点中我们得到一个结论, 在一个表中有且仅有唯一的根结点和终端结点, 除了根结点和终端结点, 其余结点都有唯一的前驱和唯一的后继, 只有满足这样的条件才称为线性表, 故此线性表是一个连续的有限的存储空间。我们要在一个线性表的某个元素前、后插入一个元素, 其数据元素在存储空间中的位置有所变化, 为了不破坏线性表的特征, 我们就要采取一定的措施进行位置的变化, 这就是线性表元素的插入。例如, 某一长度为n的线性表, 为了在线性表的第i个和第i+1个元素之间插入一个值为x的数据元素, 则需要从第i个至第n个数据元素依次往后移动一个位置。一般情况下, 所需要移动的元素次数为n-i+1。在具体的移动过程中为移出一个元素, 则从尾部向前部依次向后移动至第i-1的位置处。具体算法如下:

2.4 线性表中删除某个元素

线性表的删除操作是使长度为n的线性表变成长度为n-1的线性表, 数据元素之间的逻辑关系发生了变化, 为了在存储结构上反映这个变化, 同样需要移动元素。在移动过程中, 必须将从第i+1个元素至n个元素依次前移一位, 一般情况下, 删除第i个元素时需从第i+1至第n个元素依次向前移动一个位置。具体算法如下:

3 动态分配顺序存储结构的应用

在日常生活中, 我们只要注意观察, 留意我们的生活, 我们就不难发现, 其实很多时候我们都会用到线性表的顺序存储结构, 例如在学校对学生信息的管理、病人在医院挂号、数学集合的合并, 其中两个线性表的合并操作是线性表处理的典型例子。今天我们以其作为综合应用。具体算法如下:

4 动态分配顺序存储结构的主函数

线性表动态分配顺序存储结构的基本操作共四个, 包括线性表的初始化、插入、删除、合并。要将这些算法融合为一体成为一个完整的程序, 我们必须从程序的入口点开始执行, 即主函数main () 。下面就在主函数中调入以上的四个子程序, 使程序结构化、合理化、正确化、实用化。程序如下:

5 动态分配顺序存储结构的优缺点

在数据结构中, 我们通过时间复杂度和空间复杂度来评价一个算法的好坏, 既要考虑程序所占的空间又要考虑程序执行的次数, 所占空间越小, 执行次数越少, 又能得出正确答案, 这是每个程序员所希望的, 所以当我们在使用线性表的时候, 我们不需要为表中元素之间的逻辑关系而增加额外的存储空间, 而且可以快速的存取表中任意位置的元素。但是, 如果我们要插入或者删除的元素是在第一个位置, 那么无疑的, 我们需要移动大量的元素来完成这样的操作, 而且限于线性表长度必须小于数组长度, 如果我们需要插入大量数据, 那么很难保证空间是否充足, 而如果我们要删除大量数据的时候, 无疑又会造成空间的浪费。故顺序存储结构的优点为:具有简单、运算方便等优点, 特别是对于小线性表或长度固定的线性表, 采用顺序存储结构的优越性更为突出;缺点为:顺序存储插入与删除一个元素, 必须移动大了的数据元素, 以此对大的线性表, 特别是在元素的插入和删除很频繁的情况下, 采取顺序存储很是不方便, 效率低;顺序存储空间容易满, 出现上溢, 程序访问容易出问题, 顺序存储结构下, 存储空间不便扩充;顺序存储空间的分配问题, 分多了浪费, 分少了空间不足上溢。

摘要:线性表是由数据类型相同的若干个数据元素组成的有限序列, 其特点和算法容易理解, 是学习其它数据结构的基础。该文主要介绍了线性表、线性表的应用、线性表的常用算法和线性表的优缺点。

关键词:线性表,动态分配,插入,删除

参考文献

[1]秦玉平, 马靖善.数据结构 (C语言版) [M].北京:清华大学出版社, 2005.

[2]谭浩强.C程序设计[M].3版.北京:清华大学出版社, 2005.

上一篇:中国移动企业文化理念下一篇:房产策划代理合同