数据结构实验.docx
- 文档编号:9150659
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:119
- 大小:51.32KB
数据结构实验.docx
《数据结构实验.docx》由会员分享,可在线阅读,更多相关《数据结构实验.docx(119页珍藏版)》请在冰豆网上搜索。
数据结构实验
南阳理工学院
数据结构上机实验指导书
(2011版)
软件学院·软件工程教研室
2011.3
目录
实验1线性表应用2
实验2栈和队列的应用14
实验3线性表应用27
实验4图论及其应用46
实验5查找59
实验6排序64
实验1线性表应用
1、实验目的
1、了解和掌握线性表顺序存储和链式存储在计算机中的表示,基本操做在计算机中的实
2、能够利用线性表结构对实际问题进行分析建模,利用计算机求解。
3、能够从时间和空间复杂度的角度综合比较线性表两种存储结构的不同特点及其适用场合。
二、实验内容及步骤
1、利用程序设计语言分别实现顺序表和链表的抽象数据类型。
2、掌握程序分文件(头文件和实现文件)书写的方式。
3、分别用顺序表和链表实现课本算法2.2:
合并两个非递减有序序列,并对其时间性能做出分析。
三、实验步骤与调试过程
以线性表来描述一元多项式,储存结构采用单链表,每个结点储存的多项式中某一项的系数和指数,建立单链表时指数高的结点列于指数低的结点之后,即线性表的元素按指数递增有序排列。
四、实验结果
五、疑难小结
线性表是软件设计中最基础的数据结构。
用顺序方法存储的线性表称为顺序表,当线性表中很少做插入和删除操作,线性表的长度变化不大,易于事先确定其大小时,可以采用顺序表作为存储结构。
用链接方法存储的线性表称为线性链表,当线性表的长度变化较大,难以估计其存储规模,另外对线性表频繁进行插入和删除操作时,则采用链表作为存储结构可能会更好一些。
在实际应用中应该考虑以下因素:
(1)应有利于运算的实现;
(2)应有利于数据的特性;(3)应有利于软件环境。
六、主要算法和程序清单
●顺序表的非递减数列合并
#include
#defineListSize100
typedefintDataType;
typedefstruct
{
DataTypelist[ListSize];
intlength;
}SeqList;
voidInitList(SeqList*L)
/*将线性表初始化为空的线性表只需要把线性表的长度length置为0*/
{
L->length=0;/*把线性表的长度置为0*/
}
intListEmpty(SeqListL)
/*判断线性表是否为空,线性表为空返回1,否则返回0*/
{
if(L.length==0)/*判断线性表的长度是否为9*/
return1;/*当线性表为空时,返回1;否则返回0*/
else
return0;
}
intGetElem(SeqListL,inti,DataType*e)
/*查找线性表中第i个元素。
查找成功将该值返回给e,并返回1表示成功;否则返回-1表示失败。
*/
{
if(i<1||i>L.length)/*在查找第i个元素之前,判断该序号是否合法*/
return-1;
*e=L.list[i-1];/*将第i个元素的值赋值给e*/
return1;
}
intLocateElem(SeqListL,DataTypee)
/*查找线性表中元素值为e的元素,查找成功将对应元素的序号返回,否则返回0表示失败。
*/
{
inti;
for(i=0;i if(L.list[i]==e) returni+1; return0; } intInsertList(SeqList*L,inti,DataTypee) /*在顺序表的第i个位置插入元素e,插入成功返回1,如果插入位置不合法返回-1,顺序表满返回0*/ { intj; if(i<1||i>L->length+1)/*在插入元素前,判断插入位置是否合法*/ { printf("插入位置i不合法! \n"); return-1; } elseif(L->length>=ListSize)/*在插入元素前,判断顺序表是否已经满,不能插入元素*/ { printf("顺序表已满,不能插入元素。 \n"); return0; } else { for(j=L->length;j>=i;j--)/*将第i个位置以后的元素依次后移*/ L->list[j]=L->list[j-1]; L->list[i-1]=e;/*插入元素到第i个位置*/ L->length=L->length+1;/*将顺序表长增1*/ return1; } } intDeleteList(SeqList*L,inti,DataType*e) { intj; if(L->length<=0) { printf("顺序表已空不能进行删除! \n"); return0; } elseif(i<1||i>L->length) { printf("删除位置不合适! \n"); return-1; } else { *e=L->list[i-1]; for(j=i;j<=L->length-1;j++) L->list[j-1]=L->list[j]; L->length=L->length-1; return1; } } intListLength(SeqListL) { returnL.length; } voidClearList(SeqList*L) { L->length=0; } voidMergeList(SeqListA,SeqListB,SeqList*C);/*合并顺序表A和B中元素的函数声明*/ voidmain() { inti,flag; DataTypea[]={6,11,11,23}; DataTypeb[]={2,10,12,12,21}; DataTypee; SeqListA,B,C;/*声明顺序表A,B和C*/ InitList(&A);/*初始化顺序表A*/ InitList(&B);/*初始化顺序表B*/ InitList(&C);/*初始化顺序表C*/ for(i=1;i<=sizeof(a)/sizeof(a[0]);i++)/*将数组a中的元素插入到顺序表A中*/ { if(InsertList(&A,i,a[i-1])==0) { printf("位置不合法"); return; } } for(i=1;i<=sizeof(b)/sizeof(b[0]);i++)/*将数组b中元素插入到顺序表B中*/ { if(InsertList(&B,i,b[i-1])==0) { printf("位置不合法"); return; } } printf("顺序表A中的元素: \n"); for(i=1;i<=A.length;i++)/*输出顺序表A中的每个元素*/ { flag=GetElem(A,i,&e);/*返回顺序表A中的每个元素到e中*/ if(flag==1) printf("%4d",e); } printf("\n"); printf("顺序表B中的元素: \n"); for(i=1;i<=B.length;i++)/*输出顺序表B中的每个元素*/ { flag=GetElem(B,i,&e);/*返回顺序表B中的每个元素到e中*/ if(flag==1) printf("%4d",e); } printf("\n"); printf("将在A中出现B的元素合并后C中的元素: \n"); MergeList(A,B,&C);/*将在顺序表A和B中的元素合并*/ for(i=1;i<=C.length;i++)/*显示输出合并后C中所有元素*/ { flag=GetElem(C,i,&e); if(flag==1) printf("%4d",e); } printf("\n"); getch(); } voidMergeList(SeqListA,SeqListB,SeqList*C) /*合并顺序表A和B的元素到C中,并保持元素非递减排序*/ { inti,j,k; DataTypee1,e2; i=1;j=1;k=1; while(i<=A.length&&j<=B.length) { GetElem(A,i,&e1);/*取出顺序表A中的元素*/ GetElem(B,j,&e2);/*取出顺序表B中的元素*/ if(e1<=e2)/*比较顺序表A和顺序表B中的元素*/ { InsertList(C,k,e1);/*将较小的一个插入到C中*/ i++;/*往后移动一个位置,准备比较下一个元素*/ k++; } else { InsertList(C,k,e2);/*将较小的一个插入到C中*/ j++;/*往后移动一个位置,准备比较下一个元素*/ k++; } } while(i<=A.length)/*如果A中元素还有剩余,这时B中已经没有元素*/ { GetElem(A,i,&e1); InsertList(C,k,e1);/*将A中剩余元素插入到C中*/ i++; k++; } while(j<=B.length)/*如果B中元素还有剩余,这时A中已经没有元素*/ { GetElem(B,j,&e2); InsertList(C,k,e2);/*将B中剩余元素插入到C中*/ j++; k++; } C->length=A.length+B.length;/*C的表长等于A和B的表长的和*/ } ●链式表的非递减数列合并 /*包含头文件*/ #include #include #include /*宏定义和单链表类型定义*/ #defineListSize100 typedefintDataType; typedefstructNode { DataTypedata; structNode*next; }ListNode,*LinkList; voidMergeList(LinkListA,LinkListB,LinkList*C);/*将单链表A和B的元素合并到C中的函数声明*/ voidInitList(LinkList*head) /*将单链表初始化为空。 动态生成一个头结点,并将头结点的指 针域置为空。 */ { if((*head=(LinkList)malloc(sizeof(ListNode))) ==NULL)/*为头结点分配一个存储空间*/ exit(-1); (*head)->next=NULL; /*将单链表的头结点指针域置为空*/ } intListEmpty(LinkListhead) /*判断单链表是否为空,就是通过判断头结点的指针域是否为空 */ { if(head->next==NULL)/*判断 单链表头结点的指针域是否为空*/ return1; /*当单链表为空时,返回1;否则返回0*/ else return0; } ListNode*Get(LinkListhead,inti) /*查找单链表中第i个结点。 查找成功返回该结点的指针表示成 功;否则返回NULL表示失败。 */ { ListNode*p; intj; if(ListEmpty(head))/*在查找第i个元素之前, 判断链表是否为空*/ returnNULL; if(i<1)/*在查找第i个元 素之前,判断该序号是否合法*/ returnNULL; j=0; p=head; while(p->next! =NULL&&j { p=p->next; j++; } if(j==i) returnp;/*找到第i个结点 ,返回指针p*/ else returnNULL;/*如果没有找到第i个元 素,返回NULL*/ } ListNode*LocateElem(LinkListhead,DataTypee) /*查找线性表中元素值为e的元素,查找成功将对应元素的结点 指针返回,否则返回NULL表示失败。 */ { ListNode*p; p=head->next;/*指针p指向第一个结点*/ while(p) { if(p->data! =e)/*找到与e相等的元素,返 回该序号*/ p=p->next; else break; } returnp; } intLocatePos(LinkListhead,DataTypee) /*查找线性表中元素值为e的元素,查找成功将对应元素的序号 返回,否则返回0表示失败。 */ { ListNode*p; inti; if(ListEmpty(head))/*在查找第i个元 素之前,判断链表是否为空*/ return0; p=head->next;/*指针p指向第一 个结点*/ i=1; while(p) { if(p->data==e)/*找到与e相等的 元素,返回该序号*/ returni; else { p=p->next; i++; } } if(! p)/*如果 没有找到与e相等的元素,返回0,表示失败*/ return0; } intInsertList(LinkListhead,inti,DataTypee) /*在单链表中第i个位置插入一个结点,结点的元素值为e。 插入 成功返回1,失败返回0*/ { ListNode*p,*pre;/*定义指向第i个元素的前 驱结点指针pre,指针p指向新生成的结点*/ intj; pre=head;/*指针p指向头结 点*/ j=0; while(pre->next! =NULL&&j ,即第i个结点的前驱结点*/ { pre=pre->next; j++; } if(! pre) /*如果没找到,说明插入位置错误*/ { printf("插入位置错"); return0; } /*新生成一个结点,并将e赋值给该结点的数据域*/ if((p=(ListNode*)malloc(sizeof(ListNode)))==NULL) exit(-1); p->data=e; /*插入结点操作*/ p->next=pre->next; pre->next=p; return1; } intDeleteList(LinkListhead,inti,DataType*e) /*删除单链表中的第i个位置的结点。 删除成功返回1,失败返回 0*/ { ListNode*pre,*p; intj; pre=head; j=0; while(pre->next! =NULL&&pre->next->next! =NULL&&j { pre=pre->next; j++; } if(j! =i-1)/*如果没找到要 删除的结点位置,说明删除位置错误*/ { printf("删除位置错误"); return0; } /*指针p指向单链表中的第i个结点,并将该结点的数据 域值赋值给e*/ p=pre->next; *e=p->data; /*将前驱结点的指针域指向要删除结点的下一个结点, 也就是将p指向的结点与单链表断开*/ pre->next=p->next; free(p);/*释放p指向的结 点*/ return1; } intListLength(LinkListhead) { ListNode*p; intcount=0; p=head; while(p->next! =NULL) { p=p->next; count++; } returncount; } voidDestroyList(LinkListhead) { ListNode*p,*q; p=head; while(p! =NULL) { q=p; p=p->next; free(q); } } voidmain() { inti; DataTypea[]={6,7,9,14,37,45,65,67}; DataTypeb[]={3,7,11,34,45,89}; LinkListA,B,C;/*声明单链表A和B*/ ListNode*p; InitList(&A);/*初始化单链表A*/ InitList(&B);/*初始化单链表B*/ for(i=1;i<=sizeof(a)/sizeof(a[0]);i++)/*将数组a中元素插入到单链表A中*/ { if(InsertList(A,i,a[i-1])==0) { printf("位置不合法"); return; } } for(i=1;i<=sizeof(b)/sizeof(b[0]);i++)/*将数组b中元素插入单链表B中*/ { if(InsertList(B,i,b[i-1])==0) { printf("位置不合法"); return; } } printf("单链表A中的元素有%d个: \n",ListLength(A)); for(i=1;i<=ListLength(A);i++)/*输出单链表A中的每个元素*/ { p=Get(A,i);/*返回单链表A中的每个结点的指针*/ if(p) printf("%4d",p->data);/*输出单链表A中的每个元素*/ } printf("\n"); printf("单链表B中的元素有%d个: \n",ListLength(B)); for(i=1;i<=ListLength(B);i++) { p=Get(B,i);/*返回单链表B中的每个每个结点的指针*/ if(p) printf("%4d",p->data);/*输出单链表B中的每个元素*/ } printf("\n"); MergeList(A,B,&C);/*将单链表A和B中的元素合并到C中*/ printf("将单链表A和B的元素合并到C中后,C中的元素有%d个: \n",ListLength(C)); for(i=1;i<=ListLength(C);i++) { p=Get(C,i);/*返回单链表C中每个结点的指针*/ if(p) printf("%4d",p->data);/*显示输出C中所有元素*/ } printf("\n"); getch(); } voidMergeList(LinkListA,LinkListB,LinkList*C) /*单链表A和B中的元素非递减排列,将单链表A和B中的元素合并到C中,C中的元素仍按照非递减排列*/ { ListNode*pa,*pb,*pc;/*定义指向单链表A,B,C的指针*/ pa=A->next; pb=B->next; *C=A;/*将单链表A的头结点作为C的头结点*/ (*C)->next=NULL; pc=*C; /*依次将链表A和B中较小的元素存入链表C中*/ while(pa&&pb) { if(pa->data<=pb->data) { pc->next=pa;/*如果A中的元素小于或等于B中的元素,将A中的元素的结点作为C的结点*/ pc=pa; pa=pa->next; } else { pc->next=pb;/*如果A中的元素大于B中的元素,将B中的元素的结点作为C的结点*/ pc=pb; pb=pb->next; } } pc->next=pa? pa: pb;/*将剩余的结点插入C中*/ free(B);/*释放B的头结点*/ } 实验2栈和队列的应用 一、实验目的 1、掌握栈和队列这两种抽象数据类型的特点,并能在相应的应用问题中正确选用它们。 2、熟练掌握栈类型的两种实现方法。 3、熟练掌握循环队列和链队列的基本操作实现算法。 二、实验内容及步骤 1、用程序设计语言实现栈和队列的抽象数据类型。 2、在第一题的基础上完成以下选择: 选择一: 1)设计并实现括号匹配算法。 2)用队列实现在屏幕上打印杨辉三角。 选择二: 分别用栈和队列实现迷宫问题求解。 选择三: 分别用栈和队列实现一个列车调度系统。 三、实验步骤与调试过程 首先只只置操作数栈为空,表达式起始符“#”为运算符栈的栈底元素,依次读入表达式中每个字符,直至整个表达式求值完毕。 四、实验结果 五、疑难小结 对栈的顺序存储结构用了更深刻的了解,同时也对程序设计能力有了提高,加深了对栈先进后出性质的理解,对数组的应用也十分熟练。 六、主要算法: ●括号匹配算法。 #include #include #include #include"string.h" /*宏定义和链栈类型定义*/ typedefcharDataType; intMatch(DataTypee,DataTypech); typedefstructnode { DataTypedata; structnode*next;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验