兰州大学数据结构课程设计4.docx
《兰州大学数据结构课程设计4.docx》由会员分享,可在线阅读,更多相关《兰州大学数据结构课程设计4.docx(18页珍藏版)》请在冰豆网上搜索。
![兰州大学数据结构课程设计4.docx](https://file1.bdocx.com/fileroot1/2022-11/29/8b2d2f6e-2481-4e88-8dda-2c0047dbae40/8b2d2f6e-2481-4e88-8dda-2c0047dbae401.gif)
兰州大学数据结构课程设计4
《数据结构》课程设计题目
(程序实现采用C语言)
题目1:
猴子选王(学时:
3)
一堆猴子都有编号,编号是1,2,3...m,这群猴子(m个)按照1-m的顺序围坐一圈,从第1开始数,每数到第n个,该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子,则该猴子为大王。
要求:
m及n要求从键盘输入,存储方式采用向量及链表两种方式实现该问题求解。
题目2:
字符逆转(学时:
3)
从键盘读入一个字符串,把它存入一个链表(每个结点存储1个字符),并按相反的次序将字符串输出到显示屏。
题目3:
工资核算(学时:
3)
设有一个单位的人员工资有如下信息:
name、department、basepay、allowance、total。
现从键盘输入一组人员工资数据并将它们存储到名为paydata的文件中;再从paydata取出工资数据并给每个人的basepay增加100元,增加后将工资数据显示于屏幕(每行1人)。
题目4:
满足条件的有序表生成(学时:
3)
已知三个有序表A、B、C,它们皆由同一类元素构成,现要求对于表A作以下运算而获得有序表D:
排出A中所有的既在B中又在C中出现的元素。
另外该任务要求具有建立有序表功能以及输出有序表到屏幕的功能。
题目5:
一元多项式的减法(学时:
6)
设有两个一元多项式A(x),B(x),请完成运算A(x)+B(x)、A(x)-B(x),要求多项式采用链表进行存储。
另外该任务要求具有建立多项式链表以及输出多项式到屏幕的功能。
题目6:
床位分配(学时:
6)
某客店有N个等级的房间,第k级客房有A(k)个,每个房间有B(k)个单人床,以菜单调用方式设计为单身旅客分配床位以及离店时收回床位的程序。
要求分配成功时,印出旅客姓名、年龄、性别、到达日期、客房等级、房间号及床位号;分配不成功时,允许更改房间等级,若不更改等级,印出“满客”提示。
题目7:
文本文件单词的检索及计数(学时:
6)
要求编程建立一个文本文件,每个单词不包括空格及跨行,单词由字符序列构成且区分大小写,完成以下功能:
统计给定单词在文本文件中出现的总次数、检索输出某单词在文本文件中首次出现的行号及位置。
题目8:
二叉树的遍历(学时:
6)
二叉树以lson-rson链接方式存储,以菜单方式设计并完成功能任务:
建立并存储树、输出前序遍历结果、输出中序遍历结果、输出后序遍历结果、交换左右子树、统计高度,其中对于中序、后序的遍历运算要求采用非递归方式。
题目9:
创建二叉排序树(学时:
3)
二叉排序树以lson-rson链接方式存储,编写能够通过键盘输入建立二叉排序树,并在建立完立即在屏幕显示中序遍历结果的程序。
题目10:
霍夫曼编码应用(学时:
3)
假设一串由大写字母构成的电文,采用霍夫曼规则对其进行编码,以菜单方式设计并完成功能任务:
建立霍夫曼树、霍夫曼编码生成、编码文件译码。
#include
#include
#include
#definen100
#definem2*n-1
typedefstruct//码结点的存储结构
{
charch;
charbits[9];
intlen;
}CodeNode;
typedefCodeNodeHuffmanCode[n+1];
typedefstruct//树结点的存储结构
{
intweight;
intlchild,rchild,parent;
}HTNode;
typedefHTNodeHuffmanTree[m+1];
intnum;
voidselect(HuffmanTreeHT,intk,int&s1,int&s2)//挑选权值最小的两个结点
{
inti,j;
intminl=32767;
for(i=1;i<=k;i++)
if(HT[i].weight{
j=i;
minl=HT[i].weight;
}
s1=j;
minl=32767;
for(i=1;i<=k;i++)
if(HT[i].weight=s1)
{
j=i;
minl=HT[i].weight;
}
s2=j;
}
intjsq(char*s,intcnt[],charstr[])//统计输入字符和串
{
char*p;
inti,j,k=0;
inttemp[257];
for(i=0;i<257;i++)
temp[i]=0;
for(p=s;*p!
='\0';p++)
temp[*p]++;
for(i=0,j=0;i<=256;i++)
if(temp[i]!
=0)
{
j++;
str[j]=i;
cnt[j]=temp[i];
}
num=j;
returnj;
}
//建立霍夫曼树
voidchuffmanTree(HuffmanTree&HT,HuffmanCode&HC,intcnt[],charstr[])
{
inti,s1,s2;
for(i=1;i<=2*num-1;i++)
{
HT[i].lchild=0;
HT[i].rchild=0;
HT[i].parent=0;
HT[i].weight=0;
}
for(i=1;i<=num;i++)
HT[i].weight=cnt[i];
for(i=num+1;i<=2*num-1;i++)
{
select(HT,i-1,s1,s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
for(i=1;i<=num;i++)
HC[i].ch=str[i];
}
//给霍夫曼树的每个叶子节点分配二进制代码
voidHuffmanEncoding(HuffmanTreeHT,HuffmanCodeHC)
{
intc,p,i;
charcd[n];
intstart;
cd[num]='\0';
for(i=1;i<=num;i++)//1到num为叶子节点,每个节点都有二进制编码串
{
start=num;
c=i;
while((p=HT[c].parent)>0)
{
start--;
cd[start]=(HT[p].lchild==c)?
'0':
'1';
c=p;
}
strcpy(HC[i].bits,&cd[start]);
HC[i].len=num-start;
}
}
voiddecode(HuffmanCodeHC,charreceive[],chars[])//译码
{
charstr[268];
charcd[9];
inti,j,k=0,p=0,cjs;
while(receive[p]!
='\0')
{
cjs=0;
for(i=0;i='\0';i++)
{
cd[i]='';
cd[i+1]='\0';
cd[i]=receive[p++];
for(j=1;j<=num;j++)
if(strcmp(HC[j].bits,cd)==0)
{
str[k]=HC[j].ch;
k++;
cjs=1;
break;
}
}
}
str[k]='\0';
strcpy(s,str);
}
voidcoding(HuffmanCodeHC,charstr[],charget[])//输出字符串的二进制编码
{
inti,j=0;
while(str[j]!
='\0')
{
for(i=1;i<=num;i++)
if(HC[i].ch==str[j])
{
strcat(get,HC[i].bits);
break;
}
j++;
}
strcat(get,"\0");
}
voidmain()
{
charstr[257];//str用于在统计输入序列中的字母时用,存放是什么字符,1到256
charst[10000],s[10000];//st用来接收输入的字符串,s用来接收解压的字符串
intcn[257];//cn用于接收统计后的每个字符的频率,1到256
HuffmanTreeHT;
HuffmanCodeHC;
charch='y';intd,i;
printf("-------------------霍夫曼树------------------------\n\n");
printf("1.建立霍夫曼树.\n");
printf("2.生成霍夫曼编码.\n");
printf("3.编码文件译码.\n");
while(ch=='y')
{
printf("请选择:
");
scanf("%d",&d);
switch(d)
{
case1:
printf("输入要编码的字符串:
");
scanf("%s",&st);
num=jsq(st,cn,str);//统计文件中的字符
str[num+1]='\0';
chuffmanTree(HT,HC,cn,str);
printf("霍夫曼树建立成功!
\n");//建立霍夫曼树
break;
case2:
HuffmanEncoding(HT,HC);//根据霍夫曼树建立霍夫曼编码
printf("建立霍夫曼编码如下\n共有%d种字符\n",num);
for(i=1;i<=num;i++)
printf("字符%c次数为%d,编码为%s\n",HC[i].ch,cn[i],HC[i].bits);
charget[10000];
get[0]='\0';
coding(HC,st,get);
printf("\n上述字符串的霍夫曼码为%s\n",get);
//printf("编码效率为%f%%\n",code_ratio(st,cn,HC));
break;
case3:
printf("输入二进制码开始译码:
");
charreceive[10000];
scanf("%s",&receive);
decode(HC,receive,s);//译码
printf("译码为:
%s\n",s);
break;
}
printf("\n是否继续?
(y/n):
");
scanf("%c",&ch);
scanf("%c",&ch);
}
}
题目11:
关键路径寻找(学时:
6)
对于给定的一个工程施工图,该图以边为单位从键盘输入,编写能够找出该图的关键路径的程序。
#include"stdio.h"
#include"stdlib.h"
#defineLENsizeof(structEnode)
typedefstructVexnode//顶点表
{
intadjvex;//邻接域
intdut;//记录权值
structVexnode*next;
}vexnode;
typedefstructEnode
{
intindegree;//记录入度
intvertex;//顶点
intee,el;//记录最迟开始时间和最早结束时间
structVexnode*link;
}enode;
voidprint(enodedig[],intfirst,intlen)
{
inti,j;
staticinttop=0,list[50];
vexnode*q;
i=first;
q=dig[i].link;
list[top]=dig[i].vertex;
top++;//进栈
if(q==NULL)
{
printf("%d",list[len]);
for(i=1+len;i%d",list[i]);
printf("\n");
}
while(q!
=NULL)
{
j=q->adjvex;
if(dig[j].ee==dig[j].el)
{
list[top]=dig[j].vertex;
print(dig,j,len);
////////
}
q=q->next;
}
top--;////////
}
inttoposort(enodedig[],inte_n,intstacktp[])
{
inttop=0,bottom=0,i,j,len=0;
vexnode*q;
for(i=1;i<=e_n;i++)
{
if(dig[i].indegree==0)//入度为0则进栈
{
stacktp[top]=i;
top++;
}
len=top;
}
while(top>bottom)//拓扑排序
{
i=stacktp[bottom];
q=dig[i].link;
bottom++;
while(q!
=NULL)
{
j=q->adjvex;
dig[j].indegree--;//入度--
if(dig[i].ee+q->dut>dig[j].ee)//求一下最早开始时间
dig[j].ee=dig[i].ee+q->dut;
if(dig[q->adjvex].indegree==0)//入度为0则进栈
{stacktp[top]=q->adjvex;top++;}
q=q->next;
}
}
if(top==e_n)//表示没有环存在,则求出最迟结束时间
{
for(i=1;i<=e_n;i++)
dig[i].el=dig[stacktp[top-1]].ee;//先初始化一下
bottom=0;
while(top>bottom)//栈非空
{
top--;//从最后的一个事件开始倒推
i=stacktp[top];
q=dig[i].link;
while(q!
=NULL)
{
j=q->adjvex;
if(dig[j].el-q->dutdig[i].el=dig[j].el-q->dut;
q=q->next;
}
}
for(i=0;iprint(dig,stacktp[i],i);
return0;
}
elsereturn1;
}
voidmain()
{
enodedig[20];//顶点表数组
vexnode*q;//邻接点链表
charch;
inte_n,v_n,m,i,j,u,v,stacktp[20];
printf("------------关键路径------------\n\n");
printf("请输入顶点个数和边的条数:
");
scanf("%d%d",&e_n,&v_n);
for(i=1;i<=e_n;i++)//初始化
{
dig[i].indegree=0;
dig[i].link=NULL;
dig[i].vertex=i;
dig[i].ee=dig[i].el=0;
}
printf("请输入%d条边以及该边的权:
\n",v_n);
for(i=0;i{
scanf("%d%d%d",&u,&v,&j);//读入各边以及边的权值
q=malloc(LEN);
dig[v].indegree++;
q->adjvex=v;
q->dut=j;
q->next=dig[u].link;//将q结点放入u邻接链表中
dig[u].link=q;//将q结点放入u邻接链表中
}
m=toposort(dig,e_n,stacktp);//拓扑排序
if(m)printf("图中存在环,不存在关键路径\n");
else
{
printf("需要各点明细查询吗[y/n]");
scanf("\n%c",&ch);;
if(ch=='y'||ch=='Y')
for(i=0;iprintf("%d(%d%d)\n",stacktp[i],dig[stacktp[i]].ee,dig[stacktp[i]].el);
}
}
题目12:
堆排序实现(学时:
3)
假设有一个数据类型为整型的一维数组A,A中的数据元素呈无序状态,编写一个采用堆排序法将A中的数据元素按由小到大进行排序的程序。
#include
#defineMAX255
intA[MAX];
voidcreatdui(intl,intm)/*建初始堆过程函数*/
{
inti,j,x;
i=l;
j=2*i;/*R[j]是R[i]的左孩子*/
x=A[i];
while(j<=m)
{
if(jif(x{
A[i]=A[j];/*将A[j]调到父亲的位置上*/
i=j;/*修改i和j的值,以便继续向下筛选*/
j=2*i;
}
elsej=m+1;/*起结束作用*/
}
A[i]=x;/*被筛结点的值存入最终的位置*/
}
voidsortdui(intn)
{
inti;
intm;
for(i=n/2;i>=1;i--)
creatdui(i,n);/*建立初始堆,遍布所有的根结点*/
for(i=n;i>=2;i--)
{/*进行n-1次循环完成堆排序*/
m=A[i];
A[i]=A[1];/*将第一个元素同当前区域的最后一个元素对换*/
A[1]=m;
creatdui(1,i-1);
}/*筛选A[1]结点,得到i-1个结点的堆,仅有A[1]可能违反堆性质*/
}
voidmain()
{
inti,n;
printf("---------------------堆排序---------------------\n\n");
printf("输入整型一维数组A中数字总数:
");
scanf("%d",&n);
if(n<=0||n>MAX)
{
printf("\n输入的数据有误!
!
!
");
return;
}
printf("\n请输入整型无序序列:
\n");
for(i=1;i<=n;i++)
{
scanf("%d",&A[i]);
}
printf("\n该序列为:
\n");
for(i=1;i<=n;i++)
{
printf("%4d",A[i]);
}
sortdui(n);
printf("\n堆排序后的序列为:
\n");
for(i=1;i<=n;i++)
{
printf("%4d",A[i]);
}
printf("\n");
}
题目13基数排序的实现(学时:
3)
A为每个关键字不超过3位的十进制整数关键字集合,试编写一个采用静态链表组织模式实现的基数排序程序将A进行由小到大的排序。
#include
#include
#defineN1024
intRadixCountSort(int*npIndex,intnMax,int*npData,intnLen)
{
int*pnCount=(int*)malloc(sizeof(int)*nMax);//保存计数的个数
inti=0;
for(i=0;i{
pnCount[i]=0;
}
for(i=0;i{
++pnCount[npIndex[i]];
}
for(i=1;i<10;++i)//确定不大于该位置的个数。
{
pnCount[i]+=pnCount[i-1];
}
int*pnSort=(int*)malloc(sizeof(int)*nLen);//存放零时的排序结果。
//注意:
这里i是从nLen-1到0的顺序排序的,是为了使排序稳定。
for(i=nLen-1;i>=0;--i)
{
--pnCount[npIndex[i]];
pnSort[pnCount[npIndex[i]]]=npData[i];
}
for(i=0;i{
npData[i]=pnSort[i];
}
free(pnSort);//释放
free(pnCount);
return1;
}
//基数排序
intRadixSort(int*nPData,intnLen)
{
//申请存放基数的空间
int*nDataRadix=(int*)malloc(sizeof(int)*nLen);
intnRadixBase=1;//初始化倍数基数为1
intnIsOk=0;//设置完成排序为false
inti;
//循环,知道排序完成
while(nIsOk==0)
{
nIsOk=1;
nRadixBase*=10;
for(i=0;i{
nDataRadix[i]=nPData[i]%nRadixBase;
nDataRadix[i]/=nRadixB