数据结构是计算机课程的一门重要的基础课.docx
- 文档编号:24953794
- 上传时间:2023-06-03
- 格式:DOCX
- 页数:57
- 大小:318.81KB
数据结构是计算机课程的一门重要的基础课.docx
《数据结构是计算机课程的一门重要的基础课.docx》由会员分享,可在线阅读,更多相关《数据结构是计算机课程的一门重要的基础课.docx(57页珍藏版)》请在冰豆网上搜索。
数据结构是计算机课程的一门重要的基础课
数据结构是计算机课程的一门重要的基础课
前言
数据结构是计算机课程的一门重要的基础课,它的教学要求大致有三个重要方面:
其一就是让学生学会分析研究计算机加工的数据对象的特性,以便为数据选择适当的物理结构和逻辑结构;其二,根据结构,选择适当的算法,并初步掌握算法的时间分析和空间分析;其三,学习复杂的程序设计。
基于以上的三点要求,我在编写这本实验指导书时,也在整本书中贯穿这样的中心思想:
让读者通过数据结构的实验课,理论结合实践,达到这三点要求。
读者在使用这本书时,要以这三点要求为出发点,力求理解结构、掌握算法、读懂程序。
依据理论课的讲授情况,本书的实验安排以表(包括有序表、链表等),树,图三个主要的数据结构为重点。
文件的相关实验,此次成书未予编入。
本书的前三个实验是表的实验,有序表、
实验一、有序表的建立、插入和删除………………………………(1-8)
实验二、链表及其多项式相加……………………………………(9-16)
实验三、稀疏矩阵的建立和转置……………………………………(17-21)
实验四、二叉树及其先序遍历……………………………………(22-26)
实验五、中序线索二叉树……………………………………(27-31)
实验六、哈夫曼树的建立……………………………………(32-35)
实验七、图的邻接表的建立……………………………………(36-40)
实验八、图的拓扑排序……………………………………(41-45)
实验九、快速排序……………………………………(46-51)
实验十、归并排序……………………………………(52-55)
实验一、有序表的建立、插入与删除
一、实验目的
1、了解有序表的顺序存贮结构。
2、掌握有序表元素在内存中是怎样存贮的。
3、在有序表中实现如下操作:
(1)插入一个新元素到第i个位置。
使原来标号为增1。
(2)删除第i个位置的元素。
(3)存一个新元素到第i个位置。
(4)读表
(5)检索表中第i个元素。
(6)寻表的长度
二、实验原理
(一)线性表是最常用的而且也是最简单的一种数据结构,线性表是N个数据元素的有限序列。
例如26个英文元素的字母表:
(A,B,C,D,···)。
其数据结构的描述为:
Linear_list=(D,R)其中:
D={ai|ai属于D0,i=1,2,3,···}R={N},N={
本实验是以数组的形式把有序表存放在计算机内存的一个连续的区域内,这样便有:
LOC(ai+1)=LOC(ai)+m。
其中m是存放每个元素所占的内存字数。
LOC(ai)=LO+m·(i-1)。
其中LO是ai的地址,即首地址。
(二)实验程序说明
插入一个新元素到第i个位置,既把元素ai向后移一个位置,成为元素ai+1,把新元素放入到第i个位置,其他元素依次后移。
存一新元素到第i个位置是把元素ai冲掉后存上新值。
删除第i个元素就是把余后的元素依次向前移一个位置。
即:
以元素ai+1,ai+2,···,依次取代ai,ai+1,···。
删除后的表长是n-1(n是原表长)。
三、程序流程图
四、参考程序
/*有序表的建立、插入与删除*/
staticintarray[100];
intj,i,n,p;
intch;
voiddu()
{
printf("pleasetellmewhichnumbersdoyouoperate:
");
scanf("%d",&i);
while(i>n)
{
printf("ERROR,pleaseenternewelement");
scanf("%d",&i);
}
}
voidda()
{
printf("thelistis:
");
for(j=0;j printf("%3d",array[j]); printf("\n"); } voidshow() { printf("-----------------------------------\n"); printf("thefunctionofthelist\n"); printf("1: insert\n"); printf("2: delete\n"); printf("3: savenewelement\n"); printf("4: readlist\n"); printf("5: check\n"); printf("6: thelengthofthelist\n"); printf("0: end\n"); printf("-----------------------------------\n"); } main() { printf("pleaseinputthelengthoflist: "); scanf("%d",&n); printf("\n"); printf("pleaseenternumber: "); for(i=0;i scanf("%d",&array[i]); p=1; while(p! =0) { show(); printf("enterp: "); scanf("%d",&p); if(p>=0&&p<=6) {switch(p) { case1: printf("theinsertednumberplacesthefrontoftheoperation\n"); du(); for(j=n-1;j>=i-1;j--) array[j+1]=array[j]; printf("pleaseenternumber: \n"); scanf("%d",&ch); array[i-1]=ch; n+=1; da(); break; case2: du(); for(j=i-1;j<=n;j++) array[j]=array[j+1]; n-=1; da(); break; case3: du(); printf("pleaseenternewnumber: \n"); scanf("%d",&ch); printf("\n"); array[i-1]=ch; da(); break; case4: da(); break; case5: du(); printf("whatisthe%dnumber: ",i); printf("%3d\n",array[i-1]); break; case6: printf("thelengthofthelistis: "); printf("%3d\n",n); break; case0: p=0;break; } } } printf("ERROR,pleaseenternewnumber\n"); } 五、实验步骤 1.参考实验程序自己编出程序,上机调试。 2.对调试好的程序进行以下实验: 当机器显示表长=,可以键入一个小于100的整数,然后根据功能表做: 1: 表示有序表的插入; 2: 表示有序表的删除; 3: 表示存新值; 4: 表示检索i个元素; 5: 表示读有序表; 6: 表示查表长; 0: 表示结束。 六、思考题 1.有序表,有哪些显著的特点和优点? 2.分析实验指导书上的程序,以《数据结构》上的对有序表的类型定义来改写程序。 实验二、链表及其多项式相加 一、实验目的 1.了解线性表的链式存储结构,熟练掌握链表。 2.了解作为链表的多项式存贮方式。 3.熟悉掌握多项式加法的算法。 二、实验原理 顺序存储的线性表有一些弱点,其一,插入与删除元素需要大量移动元素;其二,预先分配存储空间时必须按最大的空间来分配。 其三,表长难以扩充。 所以,必须引入链式存储结构。 链式存储结构的特点是用一组任意的存储单元存储线性链表的数据元素,与顺序表的区别在于链式存储的存储单元可以是连续的,也可以是不连续的。 为了实现这种结构,链表采取由两部分信息组成数据元素ai的存储映像,称为结点。 结点包括两个域,其中存储数据信息的域称为数据域,存储直接后继信息的称为指针域。 指针域中存储的信息叫做指针或链。 这样,n个结点链接成一个链表,即为线性表(a1,a2,a3,···,an)。 符号多项式的操作,已经成为表处理的典型用例,在数学上,一个一元多项式pn(x)可以按升幂写成: pn(x)=p0+p1·x+p2·(x的2次幂)+···+pn·(x的n次幂)。 它由n+1个系数唯一确定。 因此,在计算机里,它可用一个线性表P来表示: P=(p0,p1,p2,···,pn),显然,此种表示仅适于顺序存储结构,在通常的应用中,多项式的次数变化很高且很大,将造成内存的很大浪费。 三、实验要求 1.参照书上的原理说明分析程序,深入理解链表的物理存储模式和逻辑模式。 2.看懂书上算法,参考实验程序编出程序上机调试。 3.参考书上的程序,编写出链表的主程序。 四、程序流程图 1.主过程2.建立多项式链表流程 N Y N Y 五、参考程序 /*链表及其多项式相加*/ typedefstructlinkline { intcoef; intexp; structlinkline*next; } line; line*creat() {/*建立多项式列表*/ intn; line*head; line*p1,*p2; n=0; printf("(输入的数必须是整数,指数须从小到大依次输入,系数为零表示多项式结束)\n"); p1=p2=(line*)malloc(sizeof(line));/*开辟一个新单元*/ scanf("%d%d",&p1->coef,&p1->exp);/*录入多项式*/ if(p1->coef==0)head=0; else { while(p1->coef! =0) {n++; if(n==1)head=p1; elsep2->next=p1; p2=p1; p1=(line*)malloc(sizeof(line)); scanf("%d%d",&p1->coef,&p1->exp); } p2->next=0; } return(head); } /*以下是输出多项式的函数*/ voidprint(line*p) { line*p0; p0=p; printf(""); if(p0! =0) do { printf("%dx的%d次幂",p0->coef,p0->exp); p0=p0->next; if(p0! =0)printf("+"); } while(p0! =0); elseprintf("空多项式! ! "); printf("\n"); } intcompare(intm,intn)/*比较两个整数的大小的函数*/ { intj; if(m if(m==n)j=0; if(m>n)j=1; return(j); } voidfreeNode(line*w1)/*释放一个表中的所有结点*/ { line*w2; w2=w1->next; while(w1) { free(w1); w1=w2; w2=w2->next; } } line*AddLine(line*ha,line*hb)/*两个非空多项式相加*/ { line*la,*lb,*lc; inta,b,sum; lc=ha; la=ha; lb=hb; if((ha==0)&&(hb! =0))return(hb); while((la! =0)&&(lb! =0)) { a=la->exp;b=lb->exp; switch(compare(a,b))/*比较当前结点指数的大小*/ { case-1: {ha=la;/*只修改la的指针*/ la=la->next; break; } case0: {sum=la->coef+lb->coef; if(sum! =0) {/*将其不为零的系数和保存*/ la->coef=sum; ha=la;la=la->next; }/*endif*/ else {/*分别删除系数和为零的对应的两个结点*/ if(lc==la){lc=lc->next;ha=lc;la=ha;}/*刚开始时特殊处理头结点*/ else{ ha->next=la->next; la=ha->next; } }/*endelse*/ hb=lb; lb=lb->next; break; } case1: {/*将指数小的项插入到la的前部*/ hb=lb->next; if(ha==la){lc=lb;lb->next=ha;la=la->next;} else { ha->next=lb; lb->next=la; ha=la; la=la->next; } lb=hb->next; break; } }/*endswtich*/ }/*endwhile*/ if(lb! =0)ha->next=lb; return(lc); }/*endAddLine*/ /*************以下为主程序**************/ main() { line*la,*lb,*lc; printf("请输入多项式La: "); la=creat(); printf("请输入多项式Lb: "); lb=creat(); printf("多项式La: \n"); print(la); printf("多项式Lb: \n"); print(lb); printf("多项式La与Lb的和是: \n"); lc=AddLine(la,lb); print(lc); freeNode(lb); } 六、思考问题 1、链表的特性和优点是什么? 2、修改实验程序将系数域改写为实数域,并且修改相应的程序语句。 3、试将多项式输出按升幂排序。 实验三、稀疏矩阵的建立与转置 一、实验目的: 1、了解稀疏矩阵的三元组存储形式。 2、熟悉掌握三元表存储矩阵的转置算法。 二、实验内容: 矩阵是很多的科学与工程计算中研究的数学对象。 在此,我们感兴趣的是,从数学结构这门学科着眼,如何存储矩阵的元从而使矩阵的各种运算有效的进行。 本来,用二维数组存储矩阵,在逻辑上意义是很明确的,也很容易理解,操作也很容易和方便。 但是在数值分析中经常出现一些阶数很高的矩阵,同时,在矩阵中又有很多值相同或者都为零的元素,可以对这种矩阵进行压缩存储: 对多个值相同的元素只分配一个存储空间;对零元素不分配空间。 稀疏矩阵的定义是一个模糊的定义: 即非零元个数较零元个数较少的矩阵。 例如下图所示的矩阵: 11290000 1000000 30000140 10240000 11800000 1500-7000 为一个稀疏矩阵。 为了实现稀疏矩阵的这种存储结构,引入三元组这种数据结构。 三元组的线性表顺序存储形式如下图: MU NU TU I I V I J V …… I J V A,B: ARRAY[1。 。 。 MAXNUM]OFTUPLE3TP 三、 实验步骤 看懂书上的算法,参考书上的程序编写程序上机调试、输入数据、检验结果。 四、程序流程图 Y N Y NCOL+1 YP+1 四、参考程序 structtuple3tp/*稀疏矩阵的建立和转置*/ { inti,j; intv; }; structsparmattp{ intmu,nu,tu; structtuple3tpdata[31]; }; structsparmattpa,b; voidcrt_sparmat() { inti; printf("输入稀疏矩阵行值,列值,最大非零元个数: "); scanf("%d%d%d",&a.mu,&a.nu,&a.tu); for(i=1;i<=a.tu;i++){ printf("输入行坐标,列坐标,非零元"); scanf("%d%d%d",&a.data[i].i,&a.data[i].j,&a.data[i].v); } } voidtrans_sparmat() { intcol,p,q; b.mu=a.nu; b.nu=a.mu; b.tu=a.tu; if(b.tu! =0){ q=1; for(col=1;col<=a.nu;col++) for(p=1;p<=a.tu;p++)if(a.data[p].j==col){ b.data[q].i=a.data[p].j; b.data[q].j=a.data[p].i; b.data[q].v=a.data[p].v; q++; } } } out(structsparmattpx) { inti,j,k,flag; for(i=1;i<=x.mu;i++){ for(j=1;j<=x.nu;j++){ flag=0; for(k=1;k<=x.tu;k++){ if(((x.data[k].i)==i)&&((x.data[k].j)==j)){ flag=1; printf("%5d",x.data[k].v); } } if(flag==0)printf("0"); } printf("\n"); } } main() { printf("稀疏矩阵的建立与转置\n"); crt_sparmat(); trans_sparmat(); printf("原矩阵为: \n"); out(a); printf("转置矩阵为: \n"); out(b); } 五、思考问题 1.稀疏矩阵是怎样储存的? 2.为什么引入稀疏矩阵这种数据结构? 3.稀疏矩阵的数据结构属于哪一种? 实验四、二叉树及其先序遍历 一、实验目的: 1.明确了解二叉树的链表存储结构。 2.熟练掌握二叉树的先序遍历算法。 二、实验内容: 1.树型结构是一种非常重要的非线性结构。 树在客观世界是广泛存在的,在计算 机领域里也得到了广泛的应用。 在编译程序里,也可用树来表示源程序的语法结构,在数据库系统中,数形结构也是信息的重要组织形式。 2.节点的有限集合(N大于等于0)。 在一棵非空数里: (1)、有且仅有 一个特定的根节点; (2)、当N大于1时,其余结点可分为M(M大于0)个互不相交的子集,其中每一个集合又是一棵树,并且称为根的子树。 树的定义是以递归形式给出的。 3.二叉树是另一种树形结构。 它的特点是每个结点最多有两棵子树,并且,二叉 树的子树有左右之分,其次序不能颠倒。 4.二叉树的结点存储结果示意图如下: 左指针域 数据域 右指针域 二叉树的存储(以五个结点为例): A B NIL C NIL NIL D NIL NIL E NIL 三、实验步骤 1.理解实验原理,读懂实验参考程序。 2. (1)在纸上画出一棵二叉树。 A BE CDGF (2)输入各个结点的数据。 (3)验证结果的正确性。 四、程序流程图 先序遍历 五、参考程序 #definebitreptrstructtype1/*二叉树及其先序边历*/ #definenull0 #definelensizeof(bitreptr) bitreptr*bt; intf,g; bitreptr/*二叉树结点类型说明*/ { chardata; bitreptr*lchild,*rchild; }; preorder(bitreptr*bt)/*先序遍历二叉树*/ { if(g==1)printf("先序遍历序列为: \n"); g=g+1; if(bt) { printf("%6c",bt->data); preorder(bt->lchild); preorder(bt->rchild); } elseif(g==2)printf("空树\n"); } bitreptr*crt_bt()/*建立二叉树*/ { bitreptr*bt; charch; if(f==1)printf("输入根结点,#表示结束\n"); elseprintf("输入结点,#表示结束\n"); scanf("\n%c",&ch); f=f+1; if(ch=='#')bt=null; else { bt=(bitreptr*)malloc(len); bt->data=ch; printf("%c左孩子",bt->data); bt->lchild=crt_bt(); printf("%c右孩子",bt->data); bt->rchild=crt_bt(); } return(bt); } main() { f=1; g=1; bt=crt_bt(); preorder(bt); } 六、思考问题 1.画出给出的各类型的数据示意图,理解为不同目的而建立的不同数据结构意义。 2.改写程序完成中、后序遍历。 3.考虑用非递归算法完成二叉树遍历。 实验五、中序线索二叉树 一、实验目的: 1.理解线索的含义,掌握线索二叉树的算法。 2.了解中序线索及其遍历的实现过程。 二、实验内容: 从实验四可知,遍历二叉树是以一定的规则,将二叉树中的结点排列成一个线性序列,得到二叉树的先序序列、中序序列、或者后序序列
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 计算机 课程 重要 基础课