大学《数据结构》C语言版课程实验题目及参考代码鲁东大学byZYC.docx
《大学《数据结构》C语言版课程实验题目及参考代码鲁东大学byZYC.docx》由会员分享,可在线阅读,更多相关《大学《数据结构》C语言版课程实验题目及参考代码鲁东大学byZYC.docx(29页珍藏版)》请在冰豆网上搜索。
大学《数据结构》C语言版课程实验题目及参考代码鲁东大学byZYC
数据结构实验
实验一线性表的基本操作
实验二栈和队列
实验三二叉树的操作
实验四图的遍历
实验五查找
实验六排序
实验一线性表的基本操作
(1)实验要求:
分别采用线性表的两种存储结构(顺序存储结构、链式存储结构)来实现以上基本操作。
(2)实验目的:
了解线性表的基本概念,掌握线性表的两种存储结构——顺序存储和链式存储,掌握在两种存储结构上实现线性表的基本操作,掌握用C上机调试线性表操作的基本方法。
(3)实验内容:
a.输入一组整型元素序列,建立线性表。
b.实现该线性表的遍历。
c.在该线性表中查找某一元素,查找成功显示查找元素,否则显示查找失败。
d.在该线性表中删除或插入指定元素。
(4)参考代码:
#include
#include
#defineSIZE20
#defineMORE10
typedefstruct{
int*base;//存储空间基址
intlength;//当前长度
intlistsize;//当前存储容量
}SqList;
voidInitList(SqList&L){
//构造线性表
L.base=(int*)malloc(SIZE*sizeof(int));
if(!
L.base)
exit(0);
L.listsize=SIZE;
scanf("%d",&L.length);
printf("输入表中元素:
\n");
for(inti=0;iscanf("%d",&L.base[i]);
}
voidOutput(SqListL){
//遍历
for(inti=0;iprintf("%5d",L.base[i]);
printf("\n");
}
voidLocate(SqListL,int&e){
//查找
inti;
for(i=0;i<=L.length;i++){
if(L.base[i]==e){
printf("查找成功\n");
break;
}
}
if(i>L.length)
printf("查找失败\n");
}
voidDelete(SqList&L,inti,int&e){
//删除第i个元素
intj;
if(i<1||i>L.length) exit(0);
e=L.base[i-1];
for(j=i-1;jL.base[j]=L.base[j+1];
}
L.length--;
}
voidInsert(SqList&L,inti,inte){
//插入
SqListq,p;
intj;
if(i<1||i>L.length+1)
exit(0);
if(L.length>=L.listsize){
int *newbase=(int*)realloc(L.base,(L.listsize+MORE)*sizeof(int));
if(!
newbase) exit(0);
L.base=newbase;
L.listsize+=MORE;
}
for(j=L.length-1;j>=i-1;j--){
L.base[j+1]=L.base[j];
}
L.base[i-1]=e;
L.length++;
}
voidmain(){
SqListLa,Lb,Lc;
intd,k,e;
printf("输入表的长度:
\n");
InitList(La);
printf("输入要查找的数:
\n");
scanf("%d",&d);
Locate(La,d);
printf("要删除第几个数?
\n");
scanf("%d",&k);
Delete(La,k,e);
printf("删除的数为:
%d\n",e);
printf("删除后的表为:
\n");
Output(La);
inta,b;
printf("输入要插入的位置和数:
\n");
scanf("%d%d",&a,&b);
Insert(La,a,b);
printf("插入后的表为:
\n");
Output(La);
}
实验二栈和队列
(1)实验要求:
掌握栈和队列的类型定义方法;掌握栈在两种不同的存储结构上实现的五种基本操作;掌握在循环队列上实现队列的基本操作,并能灵活运用以上栈和队列知识对现实生活中的实际问题提出解决方案。
(2)实验内容:
实验
(一):
假设一个算术表达式中可以包含三种括号:
圆括号“(”和“)”、方括号“[”和“]”和花括号“{”和“}”,且这三种括号可按任意的次序嵌套使用,利用栈的基本运算,设计程序,判断给定的表达式中所含括号是否正确匹配。
要求:
首先在主调函数中将算术表达式存放在一个字符数组中,然后利用栈(可以是顺序栈,也可以是链栈)的基本操作设计一个括号匹配的函数,在主调函数中调用此函数。
实验
(二):
利用循环队列模拟舞伴配对问题:
在舞会上,男、女各自排成一队。
舞会开始时。
依次从男队和女队的队头各出一人配成舞伴。
如果两队初始人数不等,则较长的那一队中未配对者等待下一轮舞曲。
假设初始男、女人数及性别已经固定,舞会的轮数从键盘输入。
试模拟解决上述舞伴配对问题。
要求:
从屏幕输出每一轮舞伴配对名单,如果在该轮有未配对的,能够从屏幕显示下一轮第一个出场的未配对者的姓名。
(3)参考代码:
实验
(一)
#include
#include
#defineSTACK_INIT_SIZE 100
#defineSTACKINCREHENT 10
//栈类型定义
typedefstruct
{
char *base;
char *top;
int stacksize;
}Sqlist;
//初始化栈
voidInitStack(Sqlist&S)
{
S.base=(char*)malloc(sizeof(char)*STACK_INIT_SIZE);
if(!
S.base)exit(0);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
}
//判断栈是否为空
intStackEmpty(SqlistS)
{
if(S.top=S.base)return1;
elsereturn0;
}
//进栈操作
voidPush(Sqlist&S,chare)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(char*)realloc(S.base,sizeof(char)*(STACKINCREHENT+S.stacksize));
if(!
S.base)exit(0);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREHENT;
}
*S.top=e;
S.top++;
}
//出栈操作
voidPop(Sqlist&S,char&e)
{
if(S.top==S.base)return;
--S.top;
e=*S.top;
}
//括号配对检查
intpeidui(char*str)
{
char*p,*c;
SqlistS;
InitStack(S);
for(p=str;*p;p++)
{
if(*p=='('||*p=='[')
Push(S,*p);
elseif(*p==')'||*p=='}'||*p==']'){
if(StackEmpty(S))return0;
Pop(S,*c);
if(*p==')'&&*c!
='(')return0;
if(*p==']'&&*c!
='[')return0;
if(*p=='{'&&*c!
='}')return0;
}
}
if(!
StackEmpty(S))return0;
return1;
}
intmain()
{
char*str;
inttmp;
str="(a+b)*c";
tmp=peidui(str);
if(tmp==1)
printf("配对成功");
elseprintf("配对不成功");
return0;
}
实验
(二)
#include
#include
#include
typedefstructQNode{
charname[10];
structQNode*next;
}QNode,*QueuePtr;
typedefstruct{
QueuePtrfront;
QueuePtrrear;
}LinkQueue;
voidInitQueue(LinkQueue&Q){ //构建一个空队列
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!
Q.front)
exit(0);
Q.front->next=Q.front;
} //InitQueue
voidEnQueue(LinkQueue&Q,char*str){ //将字符串入队
QueuePtrp;
p=(QueuePtr)malloc(sizeof(QNode));
if(!
p)exit(0);
strcpy(p->name,str);
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
}
voidDeQueue(LinkQueue&Q,char*str){ //将结点删除后连接到队列的后方
QueuePtrp;
p=Q.front->next;
strcpy(str,p->name);
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front;
free(p);
}
voidGetHead(LinkQueueQ,char*str){ //若队列非空,取队头元素
QueuePtrp;
if(Q.front!
=Q.rear){
p=Q.front->next;
strcpy(str,p->name);
}
}
voidDancer(LinkQueue&Q1,LinkQueue&Q2){ //实现配对,输出配对人名单,打印下一轮等的人
charstr[15],boy[15],girl[15],ch;
intb,g,i,k,ls,j;
printf("请输入男舞伴的人数:
\n");
scanf("%d",&b);
ch=getchar();
printf("请输入男舞伴的名字:
\n");
for(i=0;i
gets(str);
EnQueue(Q1,str);
}
printf("请输入女舞伴的人数:
\n");
scanf("%d",&g);
ch=getchar();
printf("请输入女舞伴的名字:
\n");
for(i=0;igets(str);
EnQueue(Q2,str);
}
printf("请输入舞会的轮数:
\n");
scanf("%d",&ls);
if(bk=b;
else k=g;
for(i=0;iprintf("第%d轮数配对如下:
\n",i+1);
for(j=0;jDeQueue(Q1,boy);DeQueue(Q2,girl);
printf("%s<---->%s\n",boy,girl);
EnQueue(Q1,boy);EnQueue(Q2,girl);
}
if(bGetHead(Q2,str);
printf("%s在等待\n",str);
}
else{
GetHead(Q1,str);
printf("%s在等待\n",str);
}
}
}
intmain(){
LinkQueueQ1,Q2;
InitQueue(Q1);
InitQueue(Q2);
Dancer(Q1,Q2);
}
实验三二叉树的操作
(1)实验要求:
掌握二叉树的二叉链表的存储结构;掌握二叉树的遍历思想;掌握二叉树的基本操作算法的程序实现。
(2)实验内容:
a.输入根据用户的输入信息,建立二叉树的二叉链表。
b.利用递归和非递归实现二叉树的先序、中序、后序遍历,利用队列实现二叉树的层次遍历。
c.求所有叶子结点及其总数。
(3)参考代码:
#include
#include
typedefstructBiTNode
{
intdata;
structBiTNode*lchild,*rchild;
}BiTNode,*BiTree;
voidCreateBiTree(BiTree&bt)//按先序遍历创建一个二叉树
{
inttmp;
scanf("%d",&tmp);
if(tmp==-1)
bt=NULL;
else
{
bt=(BiTree)malloc(sizeof(BiTNode));
if(!
bt)return;
bt->data=tmp;
CreateBiTree(bt->lchild);
CreateBiTree(bt->rchild);
}
}
voidInOrderTraverse(BiTreebt)//中序递归遍历
{
if(bt==NULL)return;
else
{
InOrderTraverse(bt->lchild);
printf("%d",bt->data);
InOrderTraverse(bt->rchild);
}
}
voidPreOrderTraverse(BiTreebt) //先序遍历二叉树
{
if(bt)
{ printf("%4d",bt->data);
PreOrderTraverse(bt->lchild);
PreOrderTraverse(bt->rchild);
}
}
voidPostOrderTraverse(BiTreebt) //后序遍历二叉树
{
if(bt)
{
PostOrderTraverse(bt->lchild);
PostOrderTraverse(bt->rchild);
printf("%4d",bt->data);
}
}
#defineMAXSTACK 15
typedefstruct{ //定义栈的存储结构
BiTree*base;
int top;
}SqStack;
//栈操作的相关函数
voidInitStack(SqStack&S)
{ S.base=(BiTree*)malloc(sizeof(BiTNode));
if(!
S.base) exit(0);
S.top=0;
}
voidPush(SqStack&S,BiTreee)
{
if(S.top==MAXSTACK)
exit(0);
S.base[S.top]=e;
S.top++;
}
voidPop(SqStack&S,BiTree&e)
{
if(S.top==0)
exit(0);
S.top--;
e=S.base[S.top];
}
intGetTop(SqStackS,BiTree&e)
{
if(S.top==0)
return0;
e=S.base[S.top-1];
return1;
}
intStackEmpty(SqStackS)
{
if(S.top==0)
return1;
elsereturn0;
}
voidInOrderTraverse1(BiTreebt)//中序非递归遍历----用到栈
{
SqStackS;
BiTreep;
if(bt)
{ InitStack(S); Push(S,bt);
while(!
StackEmpty(S))
{
while(GetTop(S,p)&&p)
Push(S,p->lchild);
Pop(S,p);
if(!
StackEmpty(S))
{
Pop(S,p); printf("%d",p->data);
Push(S,p->rchild);
}
}
}//if
}
voidPreOrderTraverse1(BiTreebt) //先序遍历二叉树的非递归算法
{
SqStackS;
BiTreep;
if(bt)
{ InitStack(S); Push(S,bt);
while(!
StackEmpty(S))
{
while(GetTop(S,p)&&p)
{ printf("%4d",p->data); Push(S,p->lchild); }
Pop(S,p);
if(!
StackEmpty(S))
{ Pop(S,p); Push(S,p->rchild); }
}
}//if
}
voidPostOrderTraverse1(BiTreebt) //后序遍历二叉树的非递归算法
{
SqStackS;
BiTreep,q;
if(bt)
{ InitStack(S); Push(S,bt);
while(!
StackEmpty(S))
{
while(GetTop(S,p)&& p)
Push(S,p->lchild);
Pop(S,p);
if(!
StackEmpty(S))
{
GetTop(S,p);
Push(S,p->rchild);
if(GetTop(S,p)&&!
p)
{ Pop(S,p); //空结点出栈
Pop(S,p);
printf("%4d",p->data);
while(!
StackEmpty(S)&&GetTop(S,q)&&q->rchild==p)
{ Pop(S,p); printf("%4d",p->data); }
if(!
StackEmpty(S))
{ GetTop(S,p); Push(S,p->rchild); }
}//if(!
p)
}//if(!
StackEmpty(S))
}//whie
}//if
}
#defineMAXQSIZE100 //最大队列长度
typedefstruct{
BiTree *base; //初始化动态分配空间
int front;
int rear;
}SqQueue;
intInitQueue(SqQueue&Q){
//构造一个空队列
Q.base=(BiTree*)malloc(MAXQSIZE*sizeof(BiTNode));
if(!
Q.base) return0;
Q.front=Q.rear=0;
return1;
}//InitQueue
intEnQueue(SqQueue&Q,BiTreee){
//插入元素e为Q的新的队尾元素
if((Q.rear+1)%MAXQSIZE==Q.front)
return0;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return1;
}
intDeQueue(SqQueue&Q,BiTree&e){//删除Q的队头元素,并用e返回其值
if(Q.front==Q.rear)return0;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return1;
}
intEmptyQueue(SqQueueQ)//判队空
{
if(Q.front==Q.rear)
return1;
elsereturn0;
}
voidLevelOrderTraverse(BiTreebt){ //按层次遍历二叉树算法——用到队列这种数据结构
SqQueueQ;
BiTreep;
if(!
bt) return; //空树
InitQueue(Q);//初始化空队列Q
//p=bt;
EnQueue(Q,bt); //根入队
while(!
EmptyQueue(Q))
{
DeQueue(Q,p); //队头p出队
printf("%d",p->data); //访问p
if(p->lchild)EnQueue(Q,p->lchild);//p的左孩子入队
if(p->rchild)EnQueue(Q,p->rchild);//p的右孩子入队
}
}
voidLeavesCount(BiTreebt,int&count)//求二叉树的叶子结点数
{
SqQueueQ;
BiTreep;
//p=bt;
if(!
bt)count=0;
else
{
InitQueue(Q);
EnQueue(Q,bt);
while(!
EmptyQueue(Q))
{
DeQueue(Q,p);
if(!
p->lchild&&!
p->rchild)count++;
if(p->lchild)EnQueue(Q,p->lchild);//p的左孩子入队
if(p->rchild)EnQueue(Q,p->rchild);//p的右孩子入队
}
}
}
voidmain()
{
BiTreebt;
printf("建立二叉树:
\n");
CreateBiTree(bt);
printf("中序递归遍历二叉树:
\n");
InOrderTraverse(bt);
printf("\n");
printf("中序非递归遍历二叉树:
\n");
InOrderTraverse1(bt);
printf("\n");
printf("层次遍历二叉树:
\n");
LevelOrderTraverse(bt);
printf("\n");
intcount=0;
LeavesCount(bt,count);
printf("叶子结点数为:
%d\n",count);
}
实验四图的遍历
(1)实验要求:
了解有向图和无向图的概念;掌握利用邻接矩阵和邻接链表建立图的存储结构;掌握DFS、BFS的基本思想及对图的遍历操作;了解图结构在日常生活中的广泛应用。
(2)实验内容:
设计