数据结构实验c语言版

2025-04-10 版权声明 我要投稿

数据结构实验c语言版

数据结构实验c语言版 篇1

课程名称:

数据结构 授课教师:

学习对象:

任课时间:

一、学生情况分析

数据结构是计算机专业的一门核心专业课程。学生在前期的学习中已经学习了C语言程序设计课程。通过本课程学习使学生对提高编写程序的能力以及解决实际问题的能力。

二、课程教学目标

《数据结构》是计算机学科中一门核心专业基础课。主要介绍如何合理地组织数据、有效地存储和处理数据,正确地设计算法以及对算法的分析和评价。通过本课程的学习,使学生深透地理解数据结构的逻辑结构和物理结构的基本概念以及有关算法,培养基本的、良好的程序设计技能,编制高效可靠的程序,为学习操作系统、编译原理和数据库等课程奠定基础。

三、课程教学内容

第一章 绪论

教学内容:

1)什么是数据结构

2)抽象数据类型概念;数据类型;数据抽象与抽象数据类型;用于描述数据结构的语言

3)数据结构的抽象层次 4)算法定义

5)性能分析与度量;算法的性能标准;算法的后期测试;算法的事前估计;空间复杂度度量;时间复杂度度量;时间复杂度的渐进表示法; 教学要求:

了解:数据结构基本概念及数据结构的抽象层次

了解:抽象数据类型概念

了解:算法的定义及算法特性

掌握:算法的性能分析与度量方法 第二章 线性表

教学内容:

1)线性表的定义和特点

2)线性表的顺序存储及查找、插入和删除操作 3)线性表的链式存储及查找、插入和删除操作 4)使用线性表的实例 教学要求:

了解:线性表的定义和特点

熟练掌握:线性表的顺序存储结构的查找、插入和删除等基本操作 熟练掌握:单链表、循环链表及双向链表的定义及实现 掌握:熟练掌握单链表的应用方法 第三章 栈和队列

教学内容:

1)栈:栈的抽象数据类型;栈的顺序存储表示;栈的链式存储表示

2)队列:队列的抽象数据类型;队列的顺序存储表示;队列的链式存储表示 3)队列的应用举例 教学要求:

熟练掌握:栈的定义及实现 熟练掌握:队列的定义及实现

掌握:能运用栈和队列解决简单实际问题 第四章 串

教学:内容:

1)字符串的抽象数据类型 2)字符串操作的实现 3)字符串的模式匹配 教学要求:

熟练掌握:字符串的定义方式

熟练掌握:字符串的各种操作的实现 了解:字符串的模式匹配算法 第五章 数组和广义表

教学:内容:

1)数组的定义和初始化

2)作为抽象数据类型的数组的顺序存储方式 教学要求:

了解:作为抽象数据类型的数组的定义 熟练掌握:顺序表的数组定义方式及实现 第六章 树和二叉树

教学内容:

1)树和森林的概念:树的定义;树的术语;树的抽象数据类型;森林的概念 2)二叉树:二叉树的定义;二叉树的性质;二叉树的抽象数据类型 3)二叉树的表示:数组表示;链表存储表示

4)二叉树的遍历:中序遍历;前序遍历;后序遍历;应用二叉树遍历的实例;二叉树的中序非递归算法

5)线索化二叉树:线索;中序线索化二叉树;前序与后序的线索化

6)树与森林:树的存储表示;森林与二叉树的转换;树的遍历;森林的遍历 7)二叉树的计数

8)霍夫曼树:路径长度;霍夫曼树;霍夫曼树编码 教学要求:

了解:树和森林的概念

掌握:二叉树的概念、性质及二叉树的表示 熟练掌握:二叉树的遍历方法

掌握:线索化二叉树的特性及寻找某结点的前驱和后继的方法 掌握:树和森林的实现及遍历方法

掌握:二叉树的计数方法及从二叉树遍历结果得到二叉树的方法 掌握:霍夫曼树的实现方法及霍夫曼编码的概念 第七章 图

教学内容:

1)图的基本概念:图的基本概念;图的抽象数据类型 2)图的存储表示:邻接矩阵;邻接表;邻接多重表

3)图的遍历与连通性;深度优先搜索;广度优先搜索;连通分量 4)最小生成树:克鲁斯卡尔算法;普里姆算法 教学要求:

掌握:图的基本概念和图的存储表示

熟练掌握:图的两种遍历方法与求解连通性问题的方法 掌握:构造最小生成树的Prim和Kruskal方法 第九章 查找

教学内容:

1)静态查找表:顺序表的查找;有序表的查找;索引顺序表的查找 2)二叉排序树:二叉排序树上的搜索、插入和删除 教学要求:

熟练掌握:静态搜索表的顺序搜索和折半搜索方法

熟练掌握:二叉搜索树的表示、搜索、插入、删除算法及其性能分析方法 第十章 内部排序

教学内容:

1)概述

2)插入排序:直接插入排序;对分插入排序;链表插入排序;希尔排序 3)选择排序:直接选择排序;堆排序 教学要求:

掌握:排序的基本概念和性能分析方法

掌握:插入排序、选择排序、等内排序的方法及性能分析方法

单元名称:第 一 讲:绪论

一、教学目标

1.了解《数据结构》课程的体系结构 2.掌握本章介绍的各种基本概念和术语 3.了解数据结构的二元组表示

4.掌握逻辑结构与物理结构之间的映像关系。

二、重点与难点

重点:数据结构的基本概念;逻辑结构与物理结构之间的映像关系。难点:逻辑结构与物理结构之间的映像关系。

三、教学内容与教学过程

介绍本学期课程的内容及安排

本课程是计算机专业的重要专业课之一,主要介绍常用的数据结构以及相关算法。本课程主要讲授线性表、栈和队列、串、数组、树和二叉树、图、查找、排序等内容。

成绩考核方式为:期末成绩+平时成绩,其中期末成绩占70%,平时成绩占 30%,平时成绩为:作业成绩+出勤率+上机成绩。

讲授新课

1.1 什么是数据结构

讲解:(数据结构课程的研究背景)

从计算机最初以数值计算为主到大量非数值计算出现引出数据结构。

讲解:(数据结构课程的研究对象)

例1-1图书馆的书目检索系统自动化问题。1-2计算机和人机对奕问题

1-3多叉路口交通灯的管理问题 总结:

从以上三个例子可以看出,描述这类非数值计算问题的数学模型不再是数学方程,而 是诸如线性表、树和图等之类的数据结构,这些都是数据结构课程的研究对象。因此,简单地说,数据结构是一门研究非数值计算的程序设计问题中计算机的操作对象以及它们之间的关系和操作等等的学科。

介绍数据结构课程的发展以及与其他课程之间的关系。

1.2基本概念和术语

基本概念:数据、数据元素、数据项、数据对象、数据结构、结构

(1)常见基本结构(逻辑结构):集合、线性结构、树形结构、图状结构或网状结构 数据结构的形式定义:

数据结构一般用一个二元组来表示: Data_Structure=(D,S)其中:D是数据元素的有限集,S是D上的关系的有限集

DS表示一种数据结构,它由数据元素集合K和在K上定义的一种二元关系的集合R所组成。其中:

K{Ki|0in,n0}是数据元素的有限集合,n为DS中数据元素的个数。

R{Rj|0jm,m0}的取值为1。

是K上关系的有限集合,m为K上关系的个数,通常情况下mK上任何一个二元关系Rj是序偶的集合。对于Rj中的任一序偶(x,yK),称x为第一个元素(或y的前驱),y为第二个元素(或x的后继)。

数据结构中的数据元素和数据元素之间的关系还可以用图形直观地表示出来。图形中的每个结点对应一个数据元素,两结点之间带箭头的连线对应二元关系中的一个序偶,其中序偶的第一个元素称为弧尾,第二个元素称为弧头。举例讲解:

数据结构line={K,R},其中K={01,02,03,04,05,06,07,08,09,10},R={r},r={<01,02>,<02,03>,<03,04>,<04,05>,<05,06>,<06,07>,<07,08>,<08,09>,<09,10>}。

例数据结构tree={K,R},其中K={01,02,03,04,05,06,07,08,09,10},R={r},r={<01,02>,<01,03>,<01,04>,<02,05>,<02,06>,<04,07>,<04,08>,<06,09>,<06,10>}。

例 数据结构graph={K,R},其中K={01,02,03,04,05},R={r},r={<01,02>,<02,01>,<01,04>,<04,01>,<01,03>,<03,01>,<02,04>,<04,02>,<03,05>,<05,03>}。

介绍常见数据结构(集合、线性结构、树型结构、图型结构)具体表示方式(2)逻辑结构

上述数据结构的定义是对操作对象的一种数学描述,是从操作对象抽象出来的数学模型。结构定义中的“关系”描述的是数据元素之间的逻辑关系,因此又称为数据的逻辑结构。根据这种逻辑关系通常将数据结构划分为线性结构和非线性结构,其中非线性结构又分为树型结构和图型结构。

(3)物理结构

数据结构在计算机中的表示(存储映象)称为数据的物理结构或存储结构,它涉及到数据元素及其相互关系在计算机内部的表示形式。数据元素之间的关系在计算机中有两种不同的表示方法:顺序映像和非顺序映像。根据数据元素相互之间的关系在计算机中的表示形式将数据的物理结构划分为顺序结构和链式结构。

顺序映像的特点是借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系。非顺序映像的特点是借助指示元素存储地址的指针表示数据元素之间的逻辑关系。

注意:数据的逻辑结构和物理结构是密切相关的两个方面,任何一个算法的设计取决于选定的数据的逻辑结构,而算法的实现依赖于采用的存储结构。

(4)数据结构一般包括三方面内容:

数据的逻辑结构、数据的存储结构、数据的运算

(举例讲解)小结: 总结本讲的主要内容

四、作业布置

见习题集

单元名称:第 二 讲:线性表的类型定义,线性表的顺序存储

一、教学目标

掌握线性表的顺序表示和实现

二、重点与难点

线性表的顺序表示和实现。

三、教学过程的具体安排

讲授新课

2.1线性表的类型定义

线性表的定义:一个线性表是n 个数据元素的有限序列。其中每个数据元素的具体含义,在不同的情况下各不相同,但是同一线性表中的元素必定具有相同特性,即属于同一数据对象。例如:26个英文字母表;学生健康情况登记表(图2.1)等。

例如线性表(a1,…,ai-1,ai,ai+1,…,an),称ai-1是ai的直接前驱元素,ai+1是 ai的直接后继。引导学生自己总结线性结构的特点。

线性表的长度:线性表中元素的个数(n≥0),n=0为空表。线性表中数据元素的位序(如数据元素ai在线性表中的位序为i)。

抽象数据类型线性表的定义:

讲解定义中的数据对象,数据关系以及基本操作(教材P19),重点讲解常用的基本操作含义。

通过示例2-1,2-2讲解更复杂的基本操作,并分析时间复杂度。2.2 线性表的顺序表示和实现

(1)线性表的顺序表示:用一组地址连续的存储单元依次存储线性表的数据元素。

(2)顺序储存的地址关系:假设线性表的每个元素需占用l个存储单元,并以所占的第一个单元的存储地址作为数据元素的存储位置。则线性表中第i+1个数据元素的存储位置LOC(a i+1)和第i个数据元素的存储位置LOC(a i)之间满足下列关系:

LOC(a i+1)=LOC(a i)+l

线性表的第i个数据元素ai的存储位置为:

LOC(ai)=LOC(a1)+(i-1)*l,其中LOC(a1)为线性表的基地址。

(3)顺序表及其特点, 顺序储存结构是一种随机存取的存储结构。(4)线性表的动态分配顺序存储结构。

#define LIST_INIT_SIZE

#define LISTINCREMENT 10 Typedef struct { ElemType *elem;int

length;int

listsize;}SqList;(1)基于顺序存储结构的基本操作的实现

主要介绍下面的基本操作并且分析时间复杂度。

InitList_Sq(SqList &L);ListInsert_Sq(SqList &L, int i, ElemType e);

ListDelete_Sq(SqList &L, int i, ElemType &e);LocateElem_Sq(SqList L, ElemType e, Status(*compare)(ElemType, ElemType));MergeList_Sq(SqList La,SqList Lb, SqList &Lc);重点讲解:

顺序存储结构上实现线性表的插入操作

12i1ii1n,为了保证线性表的有序性,当在位设线性表置i1in1之前插入一个新的数据元素x时,需要将第i个到第n个数据元Aa,a,,a,a,a,,a素均向后移动一个位置,然后将数据元素x存储到第i个位置上并改变线性表的长度。

Status ListInsert_Sq(SqList &L, int i, ElemType e){ // 在顺序线性表L的第i个元素之前插入新的元素e,// i的合法值为1≤i≤Listlength_Sq(L)+1

if(i < 1 || i > L.length+1)return ERROR;// 插入位置不合法 if(L.length >= L.listsize){// 当前存储空间已满,增加分配

newbase =(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));if(!newbase)exit(OVERFLOW);// 存储分配失败 L.elem = newbase;// 新基址

L.listsize += LISTINCREMENT;// 增加存储容量 } q = &(L.elem[i-1]);// q指示插入位置

for(p = &(L.elem[L.length-1]);p >= q;--p)*(p+1)= *p;// 插入位置及之后的元素右移 *q = e;// 插入e ++L.length;// 表长增1 return OK;} // ListInsert_Sq

平均时间复杂度分析:f(n)(012n)/(n1)n/2O(n)

顺序存储结构上实现线性表的删除操作

12i1ii1n,设线性表为了保证线性表的有序性,当删除第i(1in)个位置上的元素后,需要将第i+1个到第n个数据元素均向前移动Aa,a,,a,a,a,,a一个位置并改变线性表的长度。

Status ListDelete_Sq(SqList &L, int i, ElemType &e){ // 在顺序线性表L中删除第i个元素,并用e返回其值。// i的合法值为1≤i≤ListLength_Sq(L)

if((i < 1)||(i > L.length))return ERROR;// 删除位置不合法 p = &(L.elem[i-1]);

// p为被删除元素的位置 e = *p;

// 被删除元素的值赋给e q = L.elem+L.length-1;// 表尾元素的位置

for(++p;p <= q;++p)*(p-1)= *p;// 被删除元素之后的元素左移--L.length;// 表长减1 return OK;} // ListDelete_Sq

平均时间复杂度分析:f(n)(012(n1))/nn1/2O(n)总结: 顺序存储结构的优缺点 顺序结构的优点是结构简单,对数据元素既可以实现顺序访问,又可以实现随机访问;缺点是插入和删除操作需要移动大量的数据元素。

小结:本讲主要介绍了线性表的逻辑结构定义和基本运算,线性表的插入和删除操作在顺序存储结构上的实现。

小结:总结本讲的主要内容

四、作业布置

见习题集

实验作业见实验指导

单元名称:第 三 讲:线性表链式存储

一、教学目标

掌握单链表的表示和实现

二、重点与难点

单链表的存储结构和基本操作实现。

三、教学内容与教学过程

复习线性表的顺序存储结构的特点引入另一种表示方法链式存储结构。

讲授新课

2.3.1线性链表(1)线性链表

线性链表:用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。

线性链表的存储结构:

以元素(数据元素的映象)+指针(指示后继元素存储位置)=结点(表示数据元素

数据元素的映象),其中指针域只有一个。

举例讲解:教材图2.5 线性表中第一个数据元素的存储地址作为线性表的地址,称作线性表的头指针。

有时为了操作方便,在第一个结点之前虚加一个“头结点”,以指向头结点的指针为链表的头指针。线性表为空时,头结点的指针域为空。举例如图2.7.线性表的单链表存储结构的C语言描述: typedef struc LNode{ // 定义单链表结点

ElemType

data;

struct LNode

*next;

// 指向后继的指针域 }LNode, *LinkList; 单链表操作的实现:

GetElem(L, i, e)

// 取第i个数据元素 ListInsert(&L, i, e)

// 插入数据元素

ListDele CreateList(&L, n)// 生成含 n 个数据元素的链表 CreateList(&L, n)// 生成含 n 个数据元素的链表 MergeList(&La,&Lb,&Lc)//合并两个有序链表

(1)建立单链表(要求从头部插入)void CreateList_L(LinkList &L, int n){

// 逆位序输入n个元素的值,建立带表头结点的单链线性表L。L =(LinkList)malloc(sizeof(LNode));L->next = NULL;// 先建立一个带头结点的单链表 for(i = n;i > 0;--i){

p =(LinkList)malloc(sizeof(LNode));// 生成新结点 scanf(&p->data);// 输入元素值

p->next = L->next;L->next = p;// 插入到表头 } } // CreateList_L 注:从头部插入元素建立单向链表得到的线性序列为输入序列的逆序列。(2)建立单链表(要求从尾部插入)void CreateList_L(LinkList &L, int n){

//正位序输入n个元素的值,建立带表头结点的单链线性表L。L =(LinkList)malloc(sizeof(LNode));r = L;L->next = NULL;// 先建立一个带头结点的单链表 for(i = n;i > 0;--i){

p =(LinkList)malloc(sizeof(LNode));// 生成新结点 scanf(&p->data);// 输入元素值

p->next=r->next;r->next=p;r = p;// 插入到表尾 } } // CreateList_L(3)在带头结点的单链表中插入结点

分析:设在结点a和结点b之间插入数据为x的结点,通过图来分析则插入前和插入后的情况。

Status ListInsert_L(LinkList L, int i, ElemType e){ // 在带头结头的单链表L中第i位置之前插入元素e p = L;j = 0;while(p && j < i-1){ p = p->next;++j;} // 寻找第i-1个结点 if(!p || j > i-1)return ERROR;// i小于1或者大于表长 s =(LinkList)malloc(sizeof(LNode));// 生成新结点 s->data = e;s->next = p->next;// 插入L中 p->next = s;return OK;} // LinstInsert_L(4)在带头结点的单链表中删除结点

Status ListDelete_L(LinkList L, int i, ElemType &e){ p = L;j = 0;while(p->next && j < i-1){ p = p->next;++j;} //寻找第i个结点并令p指向其前趋

if(!(p->next)|| j > i-1)return ERROR;// 删除位置不合理 q = p->next;p->next = q->next;// 删除并释放结点 e = q->data;free(q);return OK;} // ListDelete_L 注:上述两个算法的时间复杂度均为O(n)。单链表的优点:

它是一种动态结构,整个存储空间为多个链表共用

不需预先分配空间

插入、删除操作方便 单链表的缺点:

指针占用额外存储空间

不能随机存取,查找速度慢 小结:本讲主要介绍了单链表的存储结构,以及的基本操作(建立、插入和删除)的实现。

四、作业布置

见习题集

实验作业见实验指导。

第四讲 循环链表,双向链表,链表应用

一、教学目标

1.了解循环链表和的基本概念;

2.掌握双向链表的插入和删除操作;

3.掌握一元多项式的表示及加法在链式存储结构上的实现。

二、重点与难点

双向链表的存储结构和基本操作实现。

三、教学内容与教学过程

讲授新课 单向循环链表 设指针p指向单向链表中最后一个结点,则p->next的值是0,表示该结点是单向链表的最后一个结点。如果将单向链表中的最后一个结点的指针域改为存放单向链表中第一个结点的地址值,使得整个线性链表构成一个环,则称这种线性链表为单向循环链表。设p指向单向循环链表中的最后一个结点,则p->next的值不是0而是等于指向循环链表中的第一个结点head的值。双向链表

如果链表中的每个结点都有两个指针域,分别指向其前驱结点和后继结点,则称这种链表为双向链表。双向链表中的结点类型描述如下:

typedef struct DuLNode {

ElemType data;

// 数据域

struct DuLNode *prior;// 指向前驱的指针域 struct DuLNode *next;// 指向后继的指针域 } DuLNode, *DuLinkList;设指针p指向双向链表中的某个结点,则显然有以下的结论: p->prior->next==p==p->next->prior(1)双向链表的插入操作

设指针变量p指向双向链表中的结点A,指针变量q指向被插入的新结点B,则在结点A的后面插入结点B的操作序列为:

(1)q->next=p->next;

(2)p->next->prior=q;(3)p->next=q;

(4)q->prior=p;

(2)双向链表的删除操作

设指针变量p指向双向链表中被删除的结点X,则删除结点X的操作序列为:(1)p->prior->next=p->next;

(2)p->next->prior=p->prior;

(3)free(p);

注:在双向链表或双向循环链表中进行插入和删除操作时,尤其要注意修改有关结点指针域的操作次序,以免丢失链域信息而造成链表中断的错误。链式存储结构的应用:一元多项式的表示及相加

一元多项式Pn(x)可按升幂写成:

2n

Pn(x)P0Px1P2xPnx它由n+1个系数唯一确定。在计算机中,可用一个线性表P来表示:

P(P0,P1,P2,,Pn)

每项系数i隐含在系数Pi的序号里。

若Qm(x)为一个一元多项式,同样用线性表Q表示:

Q(Q0,Q1,Q2,,Qm)

这两个多项式可以相加,结果为Rn(x)Pn(x)Qm(x),其中设nm,则用线性表表示R为: R(P0Q0,P1Q1,P2Q2,,PmQm,Pm1,,Pn)

我们可以采用顺序存储结构存放P、Q和R,使得多项式相加算法定义十分简介。然而,在通常的应用中,多项式的次数很高且变化很大,使得顺序存储结构的最大长度很难确定,特别是在处理形如S(x)=1+3x10001+2x20000的多项式时,要用长度为20001的线性表来表示。如果对每个元素使用两个数据项,一个为系数项,另一个为指数项,则这样构成的线性表可表示成:

P((P0,e0),(P1,e1),(P2,e2),,(Pn,en))

因此上式S(x)可表示成((1, 0),(3, 1001),(2, 20000))。显然这样的线性表应采用链式存储结构。课本 P41 图2.17中两个线性链表分别表示一元多项式A(x)=7+3x+9x8+5x11和一元多项式B(x)=8x+22x7-9x8,由这两个多项式得到的和多项式如图课本 P412.18所示。

用链表表示多项式时,链表中的数据类型描述成: typedef struct polynomial{ float coef;int expn;

struct polynomial *next;}ElemType;根据一元多项式相加的运算规则:对于两个一元多项式中所有指数相同的项,对应系数相加,若其和不为零,则构成和多项式中的一项;对于两个一元多项式中所有指数不相同的项则分别抄到和多项式中去。

第一步:分别从A表和B表的表头开始,根据比较pa->expn和pb->expn的比较结果分三种情况讨论,直到A表或B表全部处理完。

(1)pa->expn==pb->expn:则相加此两项的系数,如果相加后该项系数不等于0,则在C表中生成一个新结点存放该项,修改pa和pb使其指向各自的下一个结点。

(2)pa->expn > pb->expn:则复制A表中pa所指向的结点到C表中,修改pa使其指向下一个结点。

(3)pa->expn < pb->expn:则复制B表中pb所指向的结点到C表中,修改pb使其指向下一个结点。

第二步:若B表没有处理完,将B表中剩余结点复制到C表中;反之则将A表中剩余结点复制到C表中。

void create_item(LinkList &pc,float coef,int expn){ p=(LinkList)malloc(sizeof(LNode));p->coef=coef;p->expn=expn;pc->next=p;pc=p;} void ploy_add(LinkList pah,LinkList pbh,LinkList &pch){ pa = pah;pb = pbh;pc = pch=(LinkList *)malloc(sizeof(LNode));// 为c链表添加一个头结点 while(pa!=0 && pb!=0){ if(pa->expn==pb->expn){ x=pa->coef+pb->coef;if(x!=0)create_item(pc,x,pa->expn);pa=pa->next;pb=pb->next;} else if(pa->expn>pb->expn){ create_item(pc,pa->coef,pa->expn);pa=pa->next;} else {create_item(pc,pb->coef,pb->expn);pb=pb->next;} } while(pa!=0){create_item(pc,pa->coef,pa->expn);pa=pa->next;} while(pb!=0){create_item(pc,pb->coef,pb->expn);pb=pb->next;} pc->next=0;pc=pch;pch=pch->next;free(pc);/* 释放c链中的头结点 */ }

小结:本讲主要介绍了循环链表和双向链表的基本概念,双向链表的插入和删除操作,一元多项式的表示及相加在链式存储结构上的实现。

四、作业布置

见习题集

实验作业见实验指导。

单元名称:第 五 讲:栈

一、教学目标

1.了解栈的基本概念和基本操作;

2.掌握栈的基本操作在两种存储结构上的实现。

二、重点与难点

栈的基本操作在两种存储结构上实现。

三、教学内容与教学过程

首先复习线性表的知识,引入限定性的数据结构栈和队列。讲授新课 3.1 栈

3.1.1 抽象数据类型栈的定义

栈:限定仅在表尾进行插入或删除操作的线性表,表尾—栈顶,表头—栈底,不含元素的空表称空栈。

通过教材P44的图3.1讲解栈顶,栈底以及栈后进先出的特点。栈的抽象数据类型定义: ADT Stack { 数据对象:D={ ai | ai ∈ElemSet, i=1,2,...,n, n≥0 } 数据关系:R1={ | ai-1, ai∈D, i=2,...,n }约定an 端为栈顶,a1 端为栈底。

基本操作:

InitStack(&S)StackEmpty(S)Push(&S, e)

DestroyStack(&S)

StackLength(S)

ClearStack(&S)

GetTop(S, &e)

Pop(&S, &e)

} ADT Stack 3.1.2 栈的表示和实现 顺序栈

类似于线性表的顺序映象实现,指向表尾的指针可以作为栈顶指针。

栈的顺序存储表示:

#define STACK_INIT_SIZE 100;

#define STACKINCREMENT

10;

typedef struct {

SElemType *base;

SElemType *top;

int stacksize;

} SqStack;顺序栈的基本操作的算法描述:

初始化,返回栈顶元素,入栈,出栈。(a)栈空栈满条件 栈空条件:top=base 栈满条件:base-top=stacksize(b)入栈操作

Status Push(SqStack &S, SElemType e){ if(S.top-S.base>=S.stacksize){ S.base=(SElemType*)realloc

(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));if(!S.base)exit(OVERFLOW);S.top=S.base+S.stacksize;

S.stacksize+=STACKINCREMENT;} *S.top++ = e;return OK;}(c)出栈操作

Status Pop(SqStack &S, SElemType &e){ if(S.top==S.base)return ERROR;e=*--S.top;return OK;}

链栈:栈的链式存储结构。栈顶指针就是链表的头指针

栈的链式存储结构类似单链表的存储结构,链表中第一个结点表示栈顶,最后一个结点表示栈底。由于链表的长度可以动态增长,因此进行入栈操作时无需考虑栈的上溢,但进行出栈操作时,必需考虑栈的下溢,下溢的条件是top的值为0。

链式栈的入栈操作

Status Push(LinkList &top, ElemType x){ p=(LinkList *)malloc(sizeof(LNode));p->data=x;p->next=top;top=p;return OK;}(2)链式栈的出栈操作

Status Pop(LinkStack &top, ElemTye &y){ if(top==0)return ERROR;p=top;y=p->data;top=p->next;free(p);return OK;} 小结;本讲主要介绍了栈的基本概念,栈的基本运算,栈在顺序存储结构和链式存储结构上实现基本操作。

四、作业布置

见习题集

实验作业见实验指导。

单元名称:第 六 讲:队列

一、教学目标

1.了解栈的基本概念和基本操作;

2.掌握栈的基本操作在两种存储结构上的实现。

二、重点与难点

栈的基本操作在两种存储结构上实现。

三、教学内容与教学过程

讲授新课 队列的基本概念

队列是一种限制所有插入操作在线性表的一端进行,而所有的删除操作在线性表的另一端进行的特殊线性表。允许插入(入队)操作的一端称为队尾,允许删除(出队)操作的一端称为队头。

设队列为q(a1,a2,,an),则a1是队头元素,an是队尾元素。队列中的元素按照a1,a2,,an的顺序进入队列的,退出队列也只能按照这个次序依次退出,即只有在 a1,a2,,an1都退出队列后,an才能退出队列。因此队列也称为先进先出(FIFO)的线性表。

2、队列的基本操作

InitQueue(&Q)QueueEmpty(Q)

DestroyQueue(&Q)

ClearQueue(&Q)QueueLength(Q)GetHead(Q, &e)EnQueue(&Q, e)DeQueue(&Q, &e)

3、队列的顺序存储结构和循环队列

在队列的顺序存储结构中,除了用一组地址连续的存储单元依次存放从队头到队尾的元素之外,还需要附设两个指针front和rear。为了在C语言中描述方便起见,在此我们约定:初始化建立空队列时,令front=rear=0,每当插入新的队尾元素时,尾指针rear增1;每当删除队头元素时,头指针front增1。因此,在非空队列中,头指针始终指向队列头元素,尾指针始终指向队列尾元素的下一个位置。

讨论:将数据10,20,30,40,50,60按照入队列、入队列、入队列、出队列、出队列、入队列、入队列、入队列、出队列和出队列的顺序,观察队列中队头和队尾指针的变化状态。

假设当前为队列分配的最大空间为6,则不可再继续插入新的队尾元素,否则会因数组越界而导致程序代码被破环,然而,此时又不宜如顺序栈那样进行存储再分配扩大数组空间,因为队列的实际可用空间并末占满。解决这个问题的巧妙方法是将顺序队列的存储空间想象成一个逻辑上首尾相连的环状空间,这种存储结构称为循环队列。

分析课本P64图3.14可知,Q.front=Q.rear无法判断队列空间是“满”还是“空”。解决这个问题有两种方法:其一是另设一个标志位以区别队列是“空”还是“满”;其二是少用一个元素空间,约定以队头指针在队尾指针的下一个位置上作为队列“满”的标志。因此,判断队列空的条件为Q.front=Q.rear;判断队列满的条件为Q.front =(Q.rear+1)% MAXQSIZE。

(a)顺序循环队列的类型描述

typedef struct { QElemType *base;int front;int rear;} SqQueue;(b)顺序循环队列的入队列操作

status EnQueue(SqQueue&Q, QelemType e){ if((Q.rear+1)%MAXSIZE==Q.front)return ERROR;Q.base[Q.rear]=e;Q.rear=(Q.rear+1)%MAXSIZE;return OK;}(c)顺序循环队列的出队列操作

status DeQueue(SqQueue &Q, QelemType &e){ if(Q.rear==Q.front)return ERROR;e = Q.base[Q.front];Q.front =(Q.front+1)%MAXSIZE;return OK;}

4、队列的链式存储结构

队列的链式存储结构实际上是一个同时带有头指针和尾指针的单向链表,头指针指向队头元素,尾指针指向队尾元素。为了操作方便起见,给链式队列添加一个头结点。空的链式队列的判断条件为头指针和尾指针都指向头结点。

(a)链式循环队列的类型描述 typedef struct QNode { QElemType data;

struct QNode *next;} QNode, *QueuePtr;typedef struct {

QueuePtr front;// 队头指针 QueuePtr rear;// 队尾指针 } LinkQueue;(b)链式队列的入队列操作

stutus EnQueue(LinkQueue &Q, QelemType e){ p=(QueuePtr)malloc(sizeof(Qnode));if(!p)exit(OVERFLOW);p->data=e;p->next=NULL;Q.rear->next=p;Q.rear=p;return OK;}(c)链式队列的出队列操作。

status DeQueue(LinkQueue &Q, QelemType &e){ if(Q.front==Q.rear returnERROR;p=Q.front->next;e=p->data;Q.front->next=p->next;if(Q.rear==p)Q.rear=Q.front;free(p);return OK;} 注意:当队列中最后一个元素被删除后,队列尾指针也丢失了,因此需要对队尾指针重新赋值。

小结:主讲主要介绍了队列的基本概念和基本操作,以及队列的基本操作在顺序存储结构和链式存储结构上的实现。

四、作业布置

见习题集

实验作业见实验指导。

单元名称:第 七 讲:串

一、教学目标

1.熟悉串的定义以及基本操作的定义,并能利用这些基本操作来实现串的其它各种操作的方法。

2.熟练掌握在串的定长顺序存储结构上实现串的各种操作的方法。3.掌握串的堆分配存储结构以及在其上实现串操作的基本方法。4.了解串的块链存储结构

二、重点与难点 串的存储结构以及基本操作的实现。

三、教学内容与教学过程

讲授新课

4.1 串类型的定义(1)基本概念:

串(string):由零个或多个字符组成的有限序列,也称字符串。记为:

S = „a1a2a3……an‟(n≥0)如:A= „BEIJING‟,B= „JING‟

串的长度:串中字符的数目n。

空串:不含任何字符的串,串长度为0,空格串:仅由一个或多个空格组成的串,长度为串中空格字符的个数。

如: „

‟,C= „ BEI JING ‟

子串:由串中任意个连续的字符组成的子序列。

主串:包含子串的串。如:A= „ BEIJING ‟

B= „ JING ‟

字符在串中的位置:字符在序列中的序号。

子串在主串中的位置:以子串的第一个字符在主串中的位置来表示。

如:A= „ BEIJING ‟,B= „JING ‟,B在A中的位置为4。

串相等:当且仅当两个串的值相等。也就是说,只有两个串的长度相等

且各个对应位置的字符都相等时才相等。

(2)串的抽象数据类型定义: ADT String { 数据对象:D={ ai |ai∈CharacterSet, i=1,2,...,n, n≥0 } 数据关系:R1={ < ai-1, ai > | ai-1, ai ∈D, i=2,...,n } 基本操作:(见教材P71)} ADT String

通过基本操作可以实现更复杂的操作。如通过判等、求串长和求子串等操作可以实现定位函数Index。

4.2 串的表示和实现 4.2.1 定长顺序存储表示

用一组地址连续的存储单元存储串值的字符序列,类似于线性表的顺序存储结构。所谓定长顺序存储结构,是直接使用定长的字符数组来定义,数组的上界预先给出:

#define MAXSTRLEN 255

// 用户可在255以内定义最大串长

typedef unsigned char SString[MAXSTRLEN + 1];

// 0号单元存放串的长度

特点:

串的实际长度可在这个予定义长度的范围内随意设定,超过予定义长度的串值则被舍去,称之为“截断”。

按这种串的表示方法实现的串的运算时,其基本操作为 “字符序列的复制”(通过串联接和求子串来讲解)。

4.2.2 堆分配存储表示

以一组地址连续的存储单元存储串值的字符序列,存储空间在程序执行过程中动态分配。

C语言中提供的串类型就是以这种存储方式实现的。系统利用函数malloc()和free()进行串值空间的动态管理,为每一个新产生的串分配一个存储区,称串值共享的存储空间为“堆”。C语言中的串以一个空字符为结束符,串长是一个隐含值。串堆分配存储表示: typedef struct {

char *ch;

// 若是非空串,则按串长分配存储区,否则ch为NULL int length;// 串长度 } HString;这类串操作实现的算法为:先为新生成的串分配一个存储空间,然后进行串值的复制(以串的复制操作为例)。

讲解串堆分配的表示与实现(P76,77)4.2.3 块链存储表示

以链表存储串值,除头指针外还可以附设一个尾指针指示链表中的最后一个结点,并给出当前串的长度。称如此定义的传存储结构为块链结构。

#define CHUNKSIZE 80 // 可由用户定义的块大小

typedef struct Chunk { // 结点结构

char ch[CUNKSIZE];struct Chunk *next;

} Chunk;typedef struct { // 串的链表结构

Chunk *head, *tail;// 串的头和尾指针

int

curlen;

// 串的当前长度

} LString;讲解块链存储表示在串处理系统中的应用。小结:总结本讲的主要内容

四、作业布置

见习题集

实验作业见实验指导。

单元名称:第九讲 数 组

一、教学目标

1.熟悉数组的定义。

2.掌握数组的顺序表示和基本操作的实现。

3.掌握特殊矩阵的压缩存储和稀疏矩阵三元组顺序表存储。4.了解稀疏矩阵的行逻辑链接的顺序表和十字链表表示储存

二、重点与难点 数组的压缩存储。

三、教学内容与教学过程

讲授新课 5.1 数组的定义

数组的抽象数据类型定义: ADT Array {

数据对象:

数据关系:

基本操作: }ADT Array 数组是一种数据类型。从逻辑结构上看,数组可以看成是一般线性表的扩充。二维数组 可以看成是线性表的线性表。举例

对于数组的操作一般只有两类:(与线性表对比讲解)(1)获得特定位置的元素值;(2)修改特定位置的元素值。5.2 数组的顺序表示和实现

对于数组A,一旦给定其维数n及各维长度bi(1≤i≤n),则该数组中元素的个数是固

定的,不可以对数组做插入和删除操作,不涉及移动元素操作,因此对于数组而言,采用顺序存储法比较合适。

数组的顺序存储结构有两种:一种是按行序存储,如高级语言BASIC、COBOL和

PASCAL语言都是以行序为主。另一种是按列序存储,如高级语言中的FORTRAN语言就是以列序为主。

以二维数组为例,假设每个元素只占L个存储单元,“以行为主”存放数组,下标从

0开始,首元素a00的地址为Loc[0,0] 求任意元素aij的地址,可由如下计算公式得到:

Loc[i,j]=Loc[0,0]+b2×i+j 其中b2为第二维的长度。

对于n维数组我们只要把上式推广,就可以容易地得到n维数组中任意元素aj1j2…jn的存

储地址的计算公式。

Loc[j1,j2,…jn]=Loc[0,0,…,0]+

ci1niji

其中cn=L,ci-1=bi×ci,1

特殊矩阵压缩存储的压缩原则是:对有规律的元素和值相同的元素只分配一个存储单元,对于零元素不分配空间。

(1)对称矩阵 满足条件:aij=aji 1≤i,j≤n(2)三角矩阵(3)带状矩阵

使用一维数组存储以上特殊矩阵,通过示例讲解矩阵中元素与一维数组中元素的对应关系。

5.3 稀疏矩阵

稀疏矩阵:指矩阵中大多数元素为零的矩阵。一般地,当非零元素个数只占矩阵元素总

数的5或低于这个百分数时,我们称这样的矩阵为稀疏矩阵。(1)稀疏矩阵的三元组表表示法

对于稀疏矩阵的压缩存储要求在存储非零元素的同时,还必须存储该非零元素在矩阵中所处的行号和列号。我们将这种存储方法叫做稀疏矩阵的三元组表示法。

稀疏矩阵的三元组顺序存储表示 #define MAXSIZE 1000 typedef struct {int i, j;

ElementType e; }Triple;typedef struct {Triple data[MAXSIZE+1];

int mu, nu, tu;

}TSMatrix;

用三元组表实现稀疏矩阵的转置运算 矩阵转置:指变换元素的位置,把位于(row,col)位置上的元素换到(col,row)位置上,也就是说,把元素的行列互换。

用三元组实现稀疏矩阵转置运算的两种方式

重点掌握第一种方式:由转置后的矩阵中元素在三元组中的次序依次在转置前的矩阵中找到相应的三元组进行转置。通过程序结合矩阵进行讲解。

(2)矩阵的行逻辑链接的顺序表(了解)(3)十字链表表示

(了解)小结:总结本讲的主要内容

四、作业布置

见习题集

数据结构实验c语言版 篇2

1、知识逻辑结构

知识逻辑结构是通过知识逻辑结构图的形式给出相关知识系统的总体框架,表示了其中各知识子系统间的内在联系。在C语言程序设计的实验教学之初,将C语言的框架或结构进行阐述,把课本知识变“薄”,使得学生对所学知识全貌一目了然,有一个宏观的认识,并理清知识总体条理;然后在框架中填充知识,也就是把相关C语言知识充实起来。

2、C语言程序设计实验教学的重要性

C语言程序设计是一门实践性很强的学科,在教学过程中实验教学占有很重要的地位和作用,如果实验教学效果不佳,会使学生失去继续学习的兴趣,并进而影响到后续课程的学习。结合我校信息学院的计算机专业课程设置,C语言程序设计实验教学在整个教学过程中的比例很大 (实验54学时,理论54学时) 。通过实验教学才能让学生从朦胧到清晰地体会C语言程序的内涵和精髓。同时,实验也是不断认识事物及其发展变化规律的重要手段。C语言程序设计的实验教学是用理论指导实践,同时通过实践加深对理论的认识。学生的观察能力、思维能力、动手能力和创新能力都需要通过实验教学来培养。

3、“C语言程序设计”课程的知识逻辑结构

C语言程序设计的关键是掌握结构化程序设计的思路。C语言程序都可以归结4个步骤组成:数据声明定义、输入数据(input)、数据计算、数据输出(output)。在前几次次实验课的时候,给学生引导出如下程序进行讲解:

类似的程序对初学C语言的学生来说很难,因为该程序中的绝大部分语句是学生在初学C语言时无法触及的,但是该程序中包含了C语言程序中的四个步骤:

3.1 数据定义就是要定义数据存储的结构,以上程序中int i, j;语句即为数据定义,在C语言中有最初的基本数据类型 (int、float、double等) ,并可以借此提出数组和指针等更高一级的数据结构。

3.2 示例程序调用基本输入输出流scanf进行数据的输入,并在相应实验中从基本的直接赋值输入,到数组的输入方法特别是其中字符数组的输入,最后还有从文件中输入数据。

3.3 数据计算是关键、核心、难点。示例程序中的计算gcd函数就是为了实现合理的计算而设。在实验课上利用示例程序将计算的关键部分恰当地用结构控制如顺序、选择、循环等相关语句表示了出来,使学生对C语言程序设计中的计算大概有个了解。具体语句的书写,常用的由运算符和表达式组成的表达式语句,子程序 (函数) 的写法可以在后续课程中持续讲解。

3.4 输出数据方法与输入数据方法相对应,这里不再累述。

以上程序的讲解虽然内容很多很难,但它几乎囊括了C语言程序设计的整个知识逻辑结构(图一),同学可以通以相关的程序实验课内容作为引导,在吃透课上内容之余,利用课余时间通看教材,完成相应实验内容和报告,走到理论课程的前面,使自己在理论课中能更好地接受并吃透老师教授的知识。

4、利用“知识逻辑”框架实验教学的效果

在实验课开始之初就将C语言程序设计的整个知识逻辑结构教授于学生,可以培养学生利用课余时间自主学习。并对相应课程进行预习。由知识逻辑机构向外衍生,直至学习并掌握C语言这门课程。我校信息技术学院2013年级学生在入学之初即对C语言程序设计这门课程的大体内容进行学习,已部分学有余力的学生在同学当中脱颖而出,在刚刚结束的我校2013年程序设计竞赛的初赛中,共有13位同学(本部+二级学院)挤入比赛的前60名,而另外的同学也取得了相应不俗的成绩。

摘要:本文分析C语言程序设计实验的特点, 通过把握C程序设计语言课程知识逻辑结构及其规律, 提出C语言程序设计课程的实验教学机制, 将其知识内容按逻辑结构化传授给学生, 使学生可以更快速地融入C语言程序设计的学习中。

关键词:C语言程序设计,知识逻辑结构,实验

参考文献

[1]侯建花, 杨长青.“C语言程序设计”实验教学的改革与实践.计算机教育2010 (1) :114-115.

[2]傅川C语言教学的探索与实践.浙江中医药大学学报2007 (7) :516-517

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

C语言实验教学改革初探 篇3

关键词:C语言;实验;教学改革

作者简介:吕风杰(1973-),男,山东沾化人,滨州学院计算机科学技术系,讲师;马士明(1983-),男,山东滨州人,滨州学院计算机科学技术系,助教。(山东滨州256600)

基金项目:本文系滨州学院教学研究资助项目(项目编号:BZXYJYXM200737)的研究成果。

中图分类号:G642.423     文献标识码:A     文章编号:1007-0079(2012)10-0118-02

C语言以其结构化、灵活性好、可移植性强、效率高等优点被广大院校理工科专业选为程序设计的入门课程。[1]随着应用型人才培养改革的不断深入,学生培养目标和教育教学理念也不断更新,但自进入高校课堂20余年来,受传统应试教育的引导,大都将授课重点放在C语言的基本语法的理论讲授上,而实验教学大多用于C语言的语法规则的验证和说明,这种教学模式仅从语言的使用这个单一的角度进行教学而使得大多数学生在学完之后吃不透、用不活所学语言知识。面对这种形势,原先的实验教学计划已远不能满足要求,如何从培养学生能力的角度出发优化实验教学内容,使实验教学与理论教学形成一个目标明确、由浅入深、紧密联系的有机整体已成为当前C语言教学中的迫切性问题。本文从C语言的特点出发,对如何在当前课时、实验资源有限的情况下,通过实验教学促进、完善课堂教学效果,培养学生实践能力、创新能力和应用能力进行了深入的探讨与实践。

一、改革实验教学内容

在应用型人才培养模式下,实验教学的组织要兼顾实践性与创新性。我们在原有教学大纲的基础上,根据电子信息类专业的特点重新修订了实验大纲,教学内容中提高了设计性和综合性实验的比例。

1.改革实验内容组织结构

为了不影响专业教学计划,又能保证实验教学改革的顺利进行,我们结合理论教学进度,编写了相对开放的实验教学大纲和讲义,将实验分为基础性实验、设计性实验和综合性实验三个层次,又将每个层次的实验内容分为必做和选做两类,以供不同专业按要求进行灵活选择。根据理论教学进度安排基础性实验,让学生熟悉编程、调试环境,掌握基本指令并学会简单编程,加深对课堂理论教学内容的理解;在单元章节之后安排设计型实验,采用任务驱动教学法,验证性与应用性实验相结合,在完成基础性实验的基础上,逐步丰富功能要求,并要求学生在实验报告中加以总结归纳,培养学生的综合思维能力;综合型实验其实是一个开放性试验,安排于每个知识单元或模块(从知识的角度出发,独立于理论教材编排)完成之后,每一个项目只给出具体的功能及性能要求,对具体方法不作要求和指导,并将一个实验课题分为设计、调试、总结、改进等几个进程,先由学生根据题目要求完成功能设计并通过调试,再由教师根据学生的设计从功能及性能方面进行有针对性的分析讲解,进而提出设计建议,然后由学生完成设计改进并写出实验报告及分析总结,以达到实践性与创新性的同步提高。

2.创新实验内容

目前,高校教學过程中所用教材及参考书大都以普教为目标,极少有针对专业或行业的例题和习题出现,而各高校开设的C语言实验教学内容恰恰大多为所用教材或参考书的习题。这类经典习题专业针对性差,对学生来说缺乏趣味性,用以进行功能验证尚可,但对于能力提高或创新教育的确是勉为其难了。而且随着网络等学习资源的普及使得问题的解决极为简单,学生仅需上网搜索一下即可得到完整答案,于是实验课程就成了简单的验证,很难起到锻炼和提高的作用。

为此,我们专门针对电子信息类专业的特点精心设计了实验内容,基础性实验采用经典案例,针对性强,利于学生的入门学习;设计型和综合型实验尽量选择与学生专业相关的项目,如数字滤波的实现、数据分析与验证等。这样一方面能够贴近学生所学专业,使学生不但学会了C语言,而且使得C语言有了“用武之地”;另一方面,在实际学习过程中,能够将学过的其他专业知识融入进来,提高了学生的兴趣及学习积极性,对其他专业课程的学习以至学生的学习风貌与学习态度起到了积极的推动作用。

二、改革实验教学模式

随着各高校对高等教育应用型人才培养改革的不断深入,各专业的教学内容有了较大幅度的修改和增加,在实际教学安排中“C语言程序设计”的理论与实践课时都进行了一定程度的压缩,为保证实践教学效果,在组织教学时进行了一些改革。

1.推行任务推动教学

随着计算机技术的应用与发展,C语言作为各理工科专业的程序设计入门课程,其培养方向应该是掌握程序设计及调试的一般方法,所以在实验教学组织中应以程序设计为主线,有意识地淡化C语言本身语句、语法的介绍,并积极推行典型算法与案例教学相结合的方法,通过精心设计与编排,将复杂枯燥的语法知识分解到每个生动、有趣、实用的程序实例中,把软件工程学的思想贯穿于算法分析和程序设计的过程中。例如,在每个知识单元开始之前先提出一个典型问题,如“业绩提成计算”、“数据排序”等,从问题入手,然后循循善诱,通过任务的分解、解决、综合逐步加以解决,这样不但使学生在程序分析与解决中掌握了相关语法,而且程序设计和解决问题的能力也得到了极大的提高。[2-3]

2.突出结构化程序设计特点

结构化程序设计是C语言程序设计的一大特点,而在当前的教材中却极少涉及到相关的实例,从而使得结构化程序设计在C语言教学中成了一句实实在在的空话。有些学生平时学得很认真,对语法、语句等细节也很熟悉,但碰到稍微复杂一点的编程则无从下手。在教学中,教师应该将现代程序设计的相关理念传授给学生:一般来讲,一个较复杂的软件常可以按功能分割为若干个典型的小模块,每个小模块最终都成为功能单一、结构清晰、接口简单、容易理解和编写的小程序,而加工对象——“数据流”就是将这些模块串接起来的“主线”,只要让学生掌握了典型的算法就可将这些算法变成像搭积木一样组装成相应软件的算法。

如在学过数组部分后,教师给出一个由计时函数GetTickCount()、格式输出函数printf()函数、格式输入函数scanf()一起构成的能够测试人的反应时间的“反应计时器”函数。在此基础之上布置学生设计主函数和相关函数,通过调用“反应计时器”函数完成两个个体各一组样本的采集(如各采集并存储10个独立的反应时间),并计算各自平均值、标准差等指标;进而进行t检验,对个体差别进行分析验证。这样不但使学生学会了相应的算法实现,而且对结构化程序的灵活性和易于扩展等特点及工程应用中的程序设计方法有了较为深刻的理解,同时对工程数学中较为“死板”的统计与检验内容的实际应用有了一个感性的认识,达到了实践能力与创新能力共同提高的培养目标。

另外,在教学过程中,教师还应有意识地总结归纳一些典型算法,并作为验证型实验内容,要求学生熟练掌握,如累加、累乘、查找、排序等,在后续设计型和综合型实验中将相关内容加入,使得学生能够用会、用活,为以后的程序设计奠定基础。同时,典型算法的熟练掌握也可增加学生学习计算机语言的信心,并提高学习兴趣。[4]

3.充分利用多媒体及网络教学平台

多媒体课件具有演示直观、动态性强等特点,易于被学生所接受和理解,尤其对于实践教学,多媒体课件能够进行直观的演示与模拟,满足了实验教学的要求,把难以理解的内容或不容易观察到的事物用多媒体充分显示出来,调动学生的视觉直观功能,为突破难点创造出良好的氛围,有效地弥补传统教学的不足。

運用网络教学平台进行课后习题的布置与讨论,引导学生提出问题并找寻解决方案。一方面,充分节约了课堂教学时间,缓解了课时不足带来的影响;另一方面,能够将更多的学生吸引到问题的分析与讨论中,“讨论出真知”——相对课堂教学而言,网络讨论扩大了讨论的参与面,能够最大限度地穷尽并纠正学生在问题理解过程中可能出现的问题,极大地提高了学生的学习积极性与学习效果。

4.强化实验教学过程管理

C语言是一门实践性很强的课程,除了要把理论知识学好外,上机实践也是相当重要的一个关键环节。学习中存在的疑点或难点,学生可通过上机调试得到明确解答,同时也加深对学习内容的理解。对学生而言,在每一次的上机前应做好充分准备,编写好上机内容;对上机中出现的问题应能调试分析,编写实验报告,分析程序结果。学生只有反复上机操作才能对C语言有更深、更全面的认识和理解,逐步提高实际操作和学习的能力。对教师而言,应精心设计上机实验内容。设计上机内容时,尽量把所学的内容综合起来,达到知识的系统化。同时,也可布置一些趣味性较浓的内容,以提高学生的学习兴趣,变学生的被动学习为主动学习。另外,上机内容尽量结合学生专业,让学生觉得学有所用。

三、改革实验教学评价模式

注意综合素质的培养与评价,在“C语言程序设计”期末考核中采用实验与理论考核相结合、平时成绩与期终考核成绩相结合的综合考核评价方式,并采用实验教学成绩一票否决的形式,从而改变学生在以往课程学习中“重理论,轻实践”的思想,激发学生学习的积极性与自主性,尤其在创新性培养上。具体做法是摒弃原先那种以对错判分的一刀切的评价方式,在平时教学中对学生实验完成的成绩评判要采用个案分析的方法,在充分理解学生设计意图的基础上因势利导,对设计中的创新之处或闪光点要给予充分的肯定;对不足和错误之处要帮助学生仔细分析,然后由学生自己总结改正,以提高学生的自信心,保护其学习兴趣,最后根据学生的完成情况及钻研态度进行综合评判。

四、总结

任何一种程序设计语言都有其独有的语法特点,作为程序设计入门课程的“C语言程序设计”也不例外,但是,应该认识到在高校C语言教学中,学习语法不是学习程序设计语言的真正目的,而是应该在掌握语法的基础上,通过学习与实践,真正地学会使用C语言来解决各种实际问题,进而使学生掌握程序设计思想,真正成为学生进入程序设计领域的“敲门砖”、“导航灯”。通过对近两年的学生期终理论考试成绩对比分析发现,改革前后对于语法部分的得分率没有明显变化,而综合编程题的得分率比以前有了大约25%的提高,且学生学习的积极性比以前有较大的提高,课程结束后不少学生又通过计算机等级考试等各种形式进行了进一步的学习与提高,C语言实践教学改革取得了理想的效果。

参考文献:

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

[2]郑人杰,马素霞,殷人昆,等.软件工程概论[M].北京:机械工业出版社,2001.

[3]敖志广,吕振辽,高克宁.非计算机专业本科生C语言的教学实践[J].计算机教育,2007,(1):53-54.

[4]林向宝.C语言教学探讨[J].黑龙江交通科技,2007,(4):120-121.

(责任编辑:王祝萍)

数据结构实验c语言版 篇4

实验二 循环结构程序设计

班级 2012196 学号 201219628 姓名 李明月

一、实验目的

(1)掌握用while语句,do-while语句和for语句实现循环的方法;(2)掌握循环结构的嵌套;

(3)掌握break语句和continue语句的使用方法。

二、实验内容及步骤

1.相传国际象棋是古印度舍罕王的宰相达依尔发明的。舍罕王十分喜欢象棋,决定让宰相自己选择何种赏赐。这位聪明的宰相指着8×8共64格的象棋盘说:陛下,请您赏给我一些麦子吧,就在棋盘的第一个格子中放1粒,第2格中放2粒,第3格放4粒,以后每一格都比前一格增加一倍,依此放完棋盘上的64个格子,我就感恩不尽了。舍罕王让人扛来一袋麦子,他要兑现他的许诺。国王能兑现他的许诺吗?

程序1:试编程计算舍罕王共要多少粒麦子赏赐他的宰相,这些麦子合多少立方米?(已知1立方米麦子约1.42e8粒)总粒数为:sum=1+2+22+23+„+263 程序代码:

#include int main()//定义一个主函数 { int i;double t=1,sum=1,v;//定义变量

for(i=1;i<=63;i++)//用for循环语句实现循环运算 { t=t*2;sum+=t;//循环表达式 } printf(“总麦粒数为:%fn”,sum);v=sum/1.42e8;printf(“折合体积为: %f立方米n”,v);//对结果进行输出

return 0;} 运行结果:

2.求完数。

程序2:一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如6的因子为1,2,3,而6=1+2+3,因此6是“完数”。编程找出1000之内的所有完数,输出所有的完数(要求:一行显示6个数);

程序代码:

#include int main(){ int i,j,sum,n=0;printf(“ 1000以内的完数有:n”);for(i=1;i<=1000;i++){

sum=0;for(j=1;j

if(i%j==0)

{

sum=sum+j;

} } if(sum==i)

{ printf(“ %d”,i);

n=n+1;

if(n%2==0)

printf(“n”);

} } printf(“n”);return 0;} 运行结果:

3.打印九九乘法表

程序3:编程输出如下上三角形式的九九乘法表。2 3 4 5 6 7 8 9-------n“);for(i=1;i<10;i++)//i { for(j=1;j<=i;j++)// printf(” “);for(j=i;j<10;j++)//j printf(”%-2d “,i*j);// printf(”n“);}

代表行 输出空格达到来使得向右对齐代表列

输出行与列的乘积 3 1 2 3 4 5 6 7 8 9

运行结果:

三、问题讨论

break语句和continue语句在循环结构中使用时有何区别?举例说明。

break语句是跳出整个循环过程,不再判断执行循环的田间是否成立,并且break语句不能用于循环语句和switch语句之外的任何其他语句中。而continue语句则只是结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判定。

例子:

#include int main(){ int i;for(i=100;i<=200;i++){ if(i%3==0)continue;

printf(”%d“,i);} printf(”n");return 0;} 输出:

但是换成break之后:

四、实验心得

C语言数组实验报告 篇5

(2)#include

int main(void)

{

int i;

char ch;

char str[100];

printf(“请输入字符串:n”);

scanf(“%s”, str);

printf(“请输入查找字符:n”);

scanf(“ %c”, &ch);

for(i=0;str[i]!=';i++)

{

if(str[i] == ch)

{

printf(“位置为:%dn”, i+1);

return 0;

}

}

printf(“该字符不存在n”);

return 0;

}

(3)

(1)

#include

main()

{

long matrix[8][8],min,max,temp;

int i,j,m,n;

printf(“nPlease input n of Matrix:n”);

scanf(“%d”,&n);

m=n;

printf(“nPlease input elements of Matrix(%d*%d):n”,m,n);for(i=0;i

for(j=0;j

scanf(“%ld”,&matrix[i][j]);

for(i=0;i

{

for(j=0;j

printf(“%5ld”,matrix[i][j]);

printf(“n”);

}

}

(2)

#include

main()

{

long matrix[8][8],min,max,temp;

int i,j,m,n,nMax=0,nMin=0;

printf(“nPlease input n of Matrix:n”);

scanf(“%d”,&n);

m=n;

printf(“nPlease input elements of Matrix(%d*%d):n”,m,n);for(i=0;i

for(j=0;j

scanf(“%ld”,&matrix[i][j]);

min=max=matrix[0][0];

for(i=0;i

for(j=0;j

{

if(matrix[i][j]>max)

{

max=matrix[i][j];

nMax=i;

}

else if(matrix[i][j]

{

min=matrix[i][j];

nMin=i;

}

}

for(j=0;j

{

temp=matrix[nMax][j];

matrix[nMax][j]=matrix[nMin][j];

matrix[nMin][j]=temp;

}

printf(“nResult matrix:n”);

for(i=0;i

{

for(j=0;j

printf(“%5ld”,matrix[i][j]);

printf(“n”);

}

}

(3)

#include

main()

{

long matrix[8][8],min,max,temp;

int i,j,m,n,nMax=0,nMin=0;

printf(“nPlease input n of Matrix:n”);

scanf(“%d”,&n);

m=n;

printf(“nPlease input elements of Matrix(%d*%d):n”,m,n);for(i=0;i

for(j=0;j

scanf(“%ld”,&matrix[i][j]);

min=max=matrix[0][0];

for(i=0;i

for(j=0;j

{

if(matrix[i][j]>max)

{

max=matrix[i][j];

nMax=i;

}

else if(matrix[i][j]

{

min=matrix[i][j];

nMin=i;

}

}

for(j=0;j

{

temp=matrix[nMax][j];

matrix[nMax][j]=matrix[nMin][j];

matrix[nMin][j]=temp;

}

printf(“nResult matrix:n”);

if(nMax!=nMin)

for(i=0;i

{

for(j=0;j

printf(“%5ld”,matrix[i][j]);

printf(“n”);

}

Printf(“same line!n”)

(4)#include

void main()

{

int a[20];

int n,j,i,k,m=20;

printf(“给定的数组为:n”);

for(n=0;n<20;++n)

{

a[n]=2*n+3;

printf(“%d ”,a[n]);

}

printf(“n”);

printf(“输入要查找的数:”);

scanf(“%d”,&j);

for(n=0;n<=m;)

{

i=(m+n)/2;

if(a[i]

n=i+1;

else if(a[i]>j)

m=i-1;

else if(a[i]=j)

{

printf(“该数在数组的第%d位上n”,i+1);break;

}

if(n>m)

{

printf(“No Foundn”);

}

}

}

二、#include

void arr();

int sea(int j);

int a[20];

void main()

{

int n,j,i,h;

printf(“请输入20个数据:n”);

for(n=0;n<20;++n)

scanf(“%d”,&a[n]);

}

arr();

printf(“n请输入要查找的数:”);

scanf(“%d”,&j);

h=sea(j);

if(h==0)

{

printf(“No foundn”);

}

else

{

printf(“该数在已排序数组的第%d位n”,h)}

}

void arr()

{

int z,n,k;

for(n=0;n<20;++n)

{

for(k=0;k<19-n;k++)

if(a[k]>a[k+1])

{

z=a[k];

a[k]=a[k+1];

a[k+1]=z;

}

printf(”将数组排序,得:n“);

for(n=0;n<20;++n)

printf(”%d ",a[n]);

}

}

int sea(int j)

{

int n,i,h,m=20;

for(n=0;n<=m;)

{

i=(n+m)/2;

if(a[i]

n=i+1;

else if(a[i]>j)

m=i-1;

else if(a[i]=j)

{

数据结构实验c语言版 篇6

C语言是计算机及相关专业的一门非常重要的基础课, 是大学生学习程序设计的入门课程。学好C语言, 不仅可以为后续课程 (如:数据结构、操作系统等) 的学习打好基础, 也可以为工程软件开发打下良好的基础。然而, C语言是一门实践性非常强的课程, 因此, 要学好C语言, 必须注重上机实践。C语言实验是理论的实践环节, 其目的首先是印证对理论的理解, 然后熟悉、掌握所学技能, 最后综合利用所学知识, 启发学生的创造能力和创新精神。

1、现阶段C语言实验课存在的问题

由于大一学生本身对计算机就有一种神秘感, 并且对编程一无所知, 所以, 对计算机编程存在一种内在恐惧, 加之C语言本身比较抽象, 一般的C程序编程又很枯燥, 所以学生普遍反映C语言难学。这在很大程度上增加了学生对C语言课程的学习难度, 致使很多学生的学习积极性不高。因而, 上实验课之前没有做好充分的准备工作, 以至于在上实验课时, 有些学生坐在计算机前不知道输入什么程序, 有的同学将书本上现成的程序输入进去, 而根本不知道程序的功能和逻辑关系, 一旦程序出错或操作失误就束手无策了, 对于输出的错误信息看不懂, 相当一部分学生上机不是去编写、调试程序, 而是干其他事情, 最后实验报告也是草草了事只求应付。

2、提高C语言实验教学效果的思考

基于以上问题, 结合自己的教学研究与实践, 笔者认为提高实验教学效果, 培养学生的编程能力及调试程序的能力, 在实验教学过程中应采取以下措施:

(1) 、要求学生做好实验课之前的预习工作

为了避免学生在上实验课时出现盲目性, 提高实验课的教学效果, 教师应该在每次上实验课之后布置下次实验内容, 并要求学生在下次实验课之前对实验内容进行预习, 预习时要求学生对实验题目进行分析, 写出算法或程序, 并且设计几组实验数据, 针对实验数据分析出实验结果, 并在预习之后形成预习报告, 每次上课之前教师应对预习报告进行检查并打分。

(2) 、根据教学内容, 合理设计实验内容

为了激发学生的学习兴趣, 提高学生学习的主动性, 并且能让学生更好地掌握所学知识, 教师应该根据教学内容, 合理设计实验内容, 使实验内容既联系书本、接近实际需要又能够让学生感兴趣, 让学生能够运用所学知识解决问题。实验题目可分为必做题和选做题。必做题按教学顺序设计, 尽量避免涉及后续章节的知识, 对一些学生最容易忽视的细节多设置一些问题, 要求学生上机时进行实践以加深印象;选做题目应尽量引用前面的所学内容, 以便学生加深对前面所学知识的理解。

(3) 、实验课应加强容易被忽视细节的教学

C语言虽然说与自然语言和教学语言十分接近, 但在实际中却存在着许多"细小"的却又十分严格的差异。由于它的细小, 常常不能引起注意而被忽略。通过上机操作, 学生可以加强理解形成较深印象。例如:容易忽略"="与"=="的区别。在数学中, 可以用"5+3=8"表示恒等关系。但在C语言中, "="是赋值运算符, 是一种操作, 它完全不同于数学中表示恒等关系的"=";而"=="在C语言中是关系运算符, 用于进行"=="两边的操作数是否相等的判断。如:if (x==3) x=y;前者是进行比较, x是否和3相等, 后者表示如果x和3相等, 把y值赋给x。由于习惯问题, 初学者往往会犯这样的错误, 而通过反复大量的上机实习, 就可以加强类似这样的细节教学。

(4) 、引导学生自己解决上机实践过程中的问题

通过教学实践我们发现, C语言实验课还有一个非常突出的问题:学生在上机实践的过程中, 一旦遇到问题, 就觉得无从下手, 结果是要么放弃实验干其他事, 要么向实验教师请教.有时实验教师会因为帮助一部分学生解决问题, 而无暇顾及其他学生, 甚至使得有些学生的问题在实验课上不能得到的解答。因此, 为了使学生能更好地掌握所学知识, 提高其上机实践的效果, 也为了减轻实验教师的负担, 应引导学生自己解决上机实践过程中所遇到的问题, 其方法如下:一、在最初上实验课时, 教师可以与学生一起, 编制一些简单程序, 甚至教师可以有意地在程序里设置一些常见常犯的错误, 如少写一个分号, 少写一个函数参数, 错写一个变量名, 需要使用库函数如标准输入输出函数printf、scanf时少写文件包含语句等, 然后编译程序, 对编译后出现的错误, 应启发引导学生发现错误出现的原因及改正错误的方法, 这对于学生解决上机过程中所出现的语法错误有很好的指导提示作用;二是教师应该在上实验课的过程中, 使学生学会调试程序的方法, 如单步执行程序, 查看某些变量的当前值, 将程序执行到光标处等等, 并使学生养成自己调试程序的习惯。如学生经常会遇到这样的问题:在经过多次编译修改之后, 自己编写的程序终于可以编译链接通过, 原本以为大功告成, 可就是在最后执行阶段, 不管输入什么样的测试数据, 程序运行之后都得不到正确的结果, 此时, 学生通常都不知所措, 毫无解决之法, 只得求助于教师。其实, 此时, 如果学生已会自己调试程序, 可以选择单步运行或执行到光标处, 然后查看每一步当前变量的值, 就可以分析检查出出错的地方, 从而可以很轻易地将问题解决掉。实际调试程序的过程中, 几乎所有逻辑问题都可以通过此类似方法解决, 因此, 使学生学会自己调试程序, 并且使其养成自己调试程序的习惯, 不仅可以减轻教师的负担, 还可以使学生在解决问题的过程中获得成就感, 进而对程序设计甚至计算机科学产生浓厚的学习兴趣, 形成良性循环。

(5) 、严格规范实验报告格式, 实现书写实验报告的真正目的

做完实验后, 需要提交实验报告, 其目的一是, 为了教师更好的检查学生的实验效果, 并作为对学生实验考核的重要依据;目的二是给学生一个反思总结的机会。而现实情况并不理想, 通常, 有很大一部分学生提交实验报告仅仅是为了应付, 仅仅是为了获取平时分数, 达不到提交实验报告的真正目的。因此, 为了改变现状, 为了提高实验课的教学效率, 应严格规范实验报告的格式, 要求实验报告中除了一些实验内容、要求及实验代码和实验结果等基本项目之外, 还要求实验报告应该包括实验内容分析、关键算法、实验过程中所出现的问题以及解决方法、实验测试数据及结果、实验心得及小结, 小结部分应该包括通过这次上机学到了什么知识, 有哪些提高, 又有哪些不足。对于没有按照要求书写的实验报告, 应该发给学生要求重写。这样一来既可以整顿学风, 又可以锻炼学生的表达能力, 还给学生一个反思的过程, 会达到很好的实践教学效果。

(6) 、制定公平合理的实验课考核方式

C语言实验作为一门独立于C语言理论的实践性课程, 必须建立公平合理的考核方式。在传统考核方式中, 期末考试成绩在总评成绩中往往占有很大的比重, 一般都在70%以上。而平时成绩和实验成绩总共只有30%左右。为了强调课前预习的重要性, 为了避免学生将问题堆积、鼓励学生多提问题, 我们适当的降低了期末成绩在总评成绩中的比重, 增加了对课前预习报告的考察, 并且在平时成绩中加大了对学生平时好学程度的考察, 以期更公平合理地对学生的学习效果进行评价。

3、结束语

本文针对当前C语言实验教学中存在的问题, 提出了提高教学效果的教学措施, 其中大部分设想已应用于实际教学中, 如要求学生做好课前的预习工作, 加强容易被忽视细节的教学, 引导学生自己解决上机实践过程中的问题等等。实践结果表明, 上述教学措施的推行有效地提高了教学质量, 改善了教学效果。

参考文献

[1].谭浩强张基温C语言程序设计[M]北京:清华大学出版社, 2007, 5

[2].谭浩强C程序设计题解与上机指导[M]北京:清华大学出版社2006, 7

数据结构实验c语言版 篇7

关键词:数据同步;客户端;C语言

中图分类号:TP311.52文献标识码:A文章编号:1007-9599 (2010) 16-0000-02

The C-language Design Research of Data Synchronization System Client

Dai Xiuhong

(Liaoning Petrochemical College,Jinzhou121000,China)

Abstract:The research data synchronization system of the client's C language design,data synchronization system proposed by the client data synchronization process and data management and monitoring,this paper addresses generated in the process of enterprise information system database of multiple inter-related business data synchronization,data synchronization process in particular,face three major issues:how to accurately access the source system data,howto keep the data is safe,timely and correct sent to the target system and how to synchronize data and processes on a unified monitoring and management.

Keywords:Data synchronization;Client;C language

對于业务系统来说数据的正确性将直接影响到企业的正常工作和发展,因此对数据同步的过程和数据进行监控和管理就显得尤为重要。同步系统使用了独立的数据库来存放所有同步的数据,同步系统的客户端可以对同步的数据和过程进行管理。客户端登陆时需要设置同步系统服务器端的IP地址并输入正确的用户名、密码才能进入客户端系统进行操作。本文研究数据同步系统客户端的功能设计和异常信息日志表等数据表的设计。数据同步系统包括数据同步系统服务器端、数据同步系统客户端和数据同步系统转发器端。同步系统服务器端对源数据发送方进行身份验证并接收源系统发送的数据后保存在数据同步系统数据库的待发送表中,数据同步系统转发器端将数据从待发送表中取出发送给数据接收方,而通过数据同步系统客户端可以实现对数据同步过程中的同步数据和同步过程的监督和管理。

一、同步数据的查询、新增和修改模块

在成功登录同步系统客户端后可以对待发送数据表、已发送数据表和异常信息日志表的数据进行管理。其主要功能包括:

(一)待发送表数据的查询、修改功能。待发送表中保存了所有未发送到目标系统的正常状态消息和发送失败的异常状态消息,通过数据同步客户端可以查询到这些数据并进行修改操作,考虑为了保护数据的完整性和一致性,数据同步系统的客户端没有开放数据删除的功能。

(二)已发送表数据的查询。己发送表中保存了所有正确发送到目标系统的所有数据,可以通过数据同步系统客户端查询这些数据,但不允许修改和删除操作。

(三)异常信息日志表数据的查询。异常信息日志表记录了数据同步系统服务器本身在运行过程中发生的异常信息、源数据发送方调用同步系统服务器端接口时发生的异常信息和数据同步系统转发器端向数据接收系统发送数据时发生异常的信息,通过数据同步系统客户端可以查询所有的异常信息,为相关系统负责人进行故障排查提供了依据。

二、异常状态数据管理

在数据同步的过程中可能会出现各种的异常情况如:源系统组织的数据问题、数据接收系统服务器问题、身份验证问题等各种情况,在异常发生时需要将发生异常的数据暂停发送,并将待发送数据表中的一些相关数据的状态进行修改防止造成数据错误。若在数据同步系统转发器将正常状态的数据发送给某个数据接收方时发生了异常,则该条数据的状态将变为异常状态,所有待发送数据表中与该条数据相同转发类型和数据接收系统的所有数据的状态将同时更新为异常状态,此时数据同步系统转发器端将停止向该数据接收方发送数据,但不会对其它的数据接收方产生影响。通过数据同步客户端可以查询到异常发生时的时间和异常信息等,系统负责人可以根据异常信息快速的判断异常发生的可能原因并及时的进行处理,若是由于源系统方发送的数据问题产生异常,则可以在待发送查询页面中查询到该数据并进行修改保存操作。在系统负责人确认异常情况已经解决后可以查询待发送表中的异常状态数据并修改其状态为正常状态,此后数据同步系统转发器将自动将这些暂停发送的数据发送给数据接收方。通过数据同步系统客户端的异常状态数据管理可以有效的提高数据同步系统的可靠性和安全性。

三、转发类型管理

在同步系统服务器端发布以后将会有多个业务系统调用同步系统的服务器端接口,随着业务的发展可能会改变原先制定的数据同步对象,如原来A系统的数据需要同步给B系统,而现在则需要同时同步给C系统或者将B系统换成D系统。如果每次改变业务需求时都需要修改同步系统的代码并重新分布的话将会对其余的业务也产生影响,这应该是尽量避免的。

在同步系统服务器端接收源系统发送的数据时会根据传入的转发类型参数字段查找数据同步系统数据库转发类型表中相同转发类型的所有数据记录,然后根据每条记录中的目标系统字段生成相应的数据插入待发送数据表,例:在转发类型表中存在两条数据A和B,数据A的转发类型字段、目标系统字段、目标系统接口字段和是否可用字段分别为ES_CS_001,CA,GetDataFromA和True,数据B的转发类型字段、目标系统字段、目标系统接口字段和是否可用字段分别为ES_CS_001,CB,GetDataFromB和True,若源数据发送方传入的转发类型参数字段的值为ES_CS_001,则数据同步系统服务器端将根据A和B的值向待发送表中插入两条待发送数据,数据同步系统转发器在进行数据转发时将分别取出这两条记录并分别调用CA系统的GetDataFromA方法和CB系统的GetDataFromB方法发送数据。可以通过数据同步系统客户端将数据B记录的是否可用字段设置为false,此后在数据同步系统服务器端接收ES_CS_001转发类型的数据时将只会在待发送表中插入一条记录。因此在数据同步业务需求发生改变时只需修改转发类型表中的数据字段内容即可实现相应的数据同步业务功能的增、改而无需修改任何的代码,实现了代码的重用。

四、数据同步系统客户端实现

(一)服务器端初始化。数据同步系统主要为源数据发送系统提供了数据接收的接口,在对源数据发送方进行身份验证后将接收到的数据存储到数据库中等待转发器进行转发。本文首先数据同步的整个过程进行介绍,然后详细描述了数据同步系统客户端从初始化到运行以及接收源数据发送方的数据并存储到数据库的整个过程。在.NET中可以通过二步来实现Remoting服务器端初始化:

第一步:指定通道。在Remoting中通过通道(channel)来实现两个应用程序域之间对象的通信。为了实现跨越应用程序域进行通信,同步系统客户端必须先指定通信的通道。Remoting的通道主要有两种:Tcp类型通道和Http类型通道。在.Net的System.Runtime.Remoting.Channel命名空间里定义了IChannel接口,其中就包括了这两种通道类型。HttpChannel类型存在于命名空间System.Runtime.Remoting.Channel.Http中。通过使用Http协议,使其能在Internet上穿越防火墙传输序列化消息流。TcpChannel类型存在于命名空间System.Runtime.Remoting.Channel.Tcp中。Tcp类型通道使用了基于Socket的传输方式并通过Tcp协议来跨越Remoting边界传输序列化的消息流。TcpChannel类型默认使用二进制格式序列化消息对象,因此它具有更高的传输性能。指定通道代码如下:

public class Server

[STAThread]

static void Mai。(stringy[]args)

{

try{

//设置端口

IDictionary htPort=new Hashtable();

htPort[""port""]=9996;

//设置名称

htPort[""name""]=""channel";

//指定通道类型

BinaryServerFormatterSinkProvider serverProv=new

BinaryServerFormatterSinkProvider();

serverProv.TypeFilterLevel=

System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

BinaryClientFormatterSinkProvider clientProv=new

BinaryClientFormatterSinkProvider();

TcpChannel channel=new TcpChannel(htPort,clientProv,serverProv);

//注册通道

ChannelServices.RegisterChannel(channel);

}

第二步:设置远程对象的激活方式。在访问远程的一个对象实例时,必须在服务器端创建通道并对该对象进行初始化。这种客户端通过通道来创建远程对象的方式,称为对象的激活。在Remoting中,远程对象的激活分为两种:服务器端激活和客户端激活。服务器端激活,即WellKnow方式激活:在激活对象实例之前会在一个URI上来发布这个类型,并为此类型配置一个WellKnown对象,然后根据指定的地址或端口来发布对象.Net Remoting把服务器端激活又分为两种模式:SingleTon和SingleCall模式。SingleCall模式是一种无状态模式,客户端调用远程对象方法时,会为每一个客户端建立一个远程对象实例,而远程对象实例的销毁和资源回收则由.NET提供的垃圾回收机制自动管理。考虑到会有多个业务系统调用数据同步系统服务器端,需要为每个访问同步系统服务器端的对象建立一个远程对象实例,所以本系统采用了WellKnown模式中的SingleCall模式。

(二)接口實现。数据同步系统必须提供数据接收接口用于获得源数据发送方的数据,数据同步系统服务器端将接口函数封装在可串行化的类中并生成.dll文件然后发给源数据发送方,源数据发送方引用该dll文件并通过设置远程对象的工P地址、端口和激活方式来获取远程对象。远程处理框架需要提供必要的基础结构,以便隐藏远程对象调用方法和返回结果的复杂性。所有需要跨越应用程序域的本地对象都必须按数值来传递并且用Serializable属性标记,否则需要继承并实现ISerializable接口。在应用程序域内部,数据类型按数值传递,而所有的对象按引用传递。MarshalByRefObject是通过使用代理进行消息通讯从而跨越应用程序域边界的对象的基类。没有从MarshalByRefObject继承的对象会以隐式方式按值封送。在Remoting中能够传递的远程对象可以是各种类型,包括复杂的DataSet对象。通过继承MarshalByRefObject可以使任意对象变为远程对象。当客户端激活远程对象时,将接收到该远程对象的代理。对该代理的所有操作都将重新定向,使远程处理基础结构能够正确截取和转发调用。远程对象定义如下:

//允许运行库串行化一个对象

[Serializable]

//远程对象必须继承MarshalByRefObject

public class Message:MarshalByRefObject

{//为源系统提供的接口

public bool GetMsgFromOrigin(byte[]identify,string oriSystem,string operatorName,string transType,string xmlStr)

{

//实例化业务逻辑层对象

MSDS.BizFacade.Message message=new MSDS.BizFacade.Message();

//调用业务逻辑层函数

return message.GetMsgFromOrigin(identify,oriSystem,operatorName,transType,xmlStr);

catch(Exception ex)

//向接口调用方抛出异常信息

throw new Except.ion(ex.Message);

finally

//释放资源

ServicedComponent.Dispose0bject (message);}}

五、结论

在企业信息化发展过程中,建立了大量的信息管理系统,这些系统之间存在一定的关联关系,部分数据在多个系统内都需要被使用。但由于缺乏有关企业信息管理模型方面的标准和规范,造成这些信息系统之间存在兼容性差、数据信息资源难以交流共享等问题,当一个业务系统对其数据库中的某些信息进行更新时,将导致该系统与其它多个系统内数据的不一致性,从而对公司业务的正常运作造成了阻碍。通过对本人所在企业的需求调研,本文设计并实现了用于解决企业数据同步问题的数据同步系统。系统采用Visual Studio 2003的开发环境,使用C语言实现系统开发。实现了在企业范围内多个业务数据库之间的数据交换与同步。系统投入正式运行,并取得了较好的应用效果。

参考文献:

[1]杨柳,蔡英蔚.基于XML格式异构数据同步模型的研究[J].中国电力教育,2008,22

[2]沈敏,许华虎.基于XML的分布式异构数据库数据同步系统的研究[J].计算机工程与应用,2005,41,5:184-186

[3]梁利妓,吴国平.一种基于XML的异构数据源集成方案[J].现代计算机,2004,3:27-29

上一篇:财务人员入党申请书下一篇:幼儿园开学寄语版