数据结构课程设计报告学院:计算机科学与工程专业:计算机科学与技术班级:09级班学号:姓名:指导老师:时间: 2010年12月一、课程设计题目:1、哈夫曼编码的实现2、城市辖区地铁线路设计3、综合排序算法的比较二、小组成员:三、题目要求:1.哈夫曼编码的实现(1)打开若干篇英文文章,统计该文章中每个字符出现的次数,进一步统一各字符出现的概率。
(2)针对上述统计结果,对各字符实现哈夫曼编码(3)对任意文章,用哈夫曼编码对其进行编码(4)对任意文章,对收到的电文进行解码2.某城市要在其各个辖区之间修建地铁来加快经济发展,但由于建设地铁的费用昂贵,因此需要合理安排地铁的建设路线。
(1)从包含各辖区的地图文件中读取辖区的名称和各辖区的直接距离(2)根据上述读入的信息,给出一种铺设地铁线路的解决方案。
使乘客可以沿地铁到达各个辖区,并使总的建设费用最小。
(3)输出应该建设的地铁路线及所需要建设的总里程信息。
3.综合排序算法的比较各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概的执行时间。
试通过随机的数据比较各算法的关键字比较次数和关键字移动的次数。
(1)对以下各种常用的内部排序算法进行比较:直接插入排序,折半插入排序,二路归并排序,希尔排序,冒泡排序,快速排序,简单选择排序,堆排序,归并排序,基数排序。
(2)待排序的表长不少于100,要求采用随机数。
(3)至少要用5组不同的输入数据做比较:比较的次数为有关键字参加的比较次数和关键字移动的次数(4)改变数据量的大小,观察统计数据的变化情况。
(5)对试验统计数据进行分析。
对各类排序算法进行综合评价。
四、项目安排:1、小组内分工合作分工:负责哈夫曼编码的实现,负责城市辖区地铁线路设计,负责综合排序算法的比较。
合作:组内,组外进行交流,组长帮助解决组员的在项目过程中的困难,并控制进度。
五、完成自己的任务:任务:综合排序算法比较1.思想实现流程图2.代码的实现#include<time.h>#include<stdio.h>#include<stdlib.h>#define MAXSIZE 1000 int L[MAXSIZE+1];int num=100;开始初始数据直接排序折半排序希尔排序冒泡排序快速排序选择排序……统计排序效率排序结果排序优劣intcount1=0,count2=0,count3=0,count4=0,count5=0,count6=0,count7=0,count8=0,count9=0,count10 =0;int creatdata() //产生随机数{FILE *f;int row;row=num/10;f = fopen("O_data.txt", "wt"); //创建并写入产生的随机数if(f){for(int i=0; i<10; i++) //控制列{for(int j=0; j<row; j++){fprintf(f, "%2d\t", rand()%100); //调用rand()函数控制为两位数}fprintf(f, "\n");}f close(f);}return 0;}void zjpx(int L[MAXSIZE]) //直接插入排序{creatdata();int i,j;for(i=2;i<=num;i++) // 从第二个开始插入{i f(L[i]<=L[i-1]){L[0]=L[i]; //设置哨兵并记录要插入的值L[i]=L[i-1];count2=count2+2; //如果if 成立则此处关键字移动for(j=i-2;(L[0]<L[j]);j--) //开始向前寻找{L[j+1]=L[j];count1++; //此处关键字比较count2++; //如果两次if成立则此处关键字移动} //记录后移L[j+1]=L[0]; //插入到正确位置count2++;}c ount1++;}printf("直接排序后的结果是:\n关键字比较了%d次\n关键字移动了%d次\n",count1,count2);for(i=2;i<=num;i++){p rintf("%2d ",L[i]);i f(i%10==0)printf("\n");}}void zbpx(int L[MAXSIZE]) //折半插入排序{creatdata();int i,j,m,low,high; //定义标志for(i=2;i<=num;++i) // 从第二个开始插入{L[0]=L[i];c ount4++; //此处关键字移动l ow=1,high=i-1;while(low<=high) //寻找插入位置{m=(low+high)/2; //折半找到位置if(L[0]<L[m]){high=m-1;} //判断是否需要移动位置并将折半区间进一步缩小else low=m+1;count3++; //在上次判断的时候已经做了关键字的比较所以比较次数自加}for(j=i-1;j>=high+1;j--){L[j+1]=L[j]; //记录后移count4++; //此处关键字移动}L[high+1]=L[0]; //插入记录count4++; //此处关键字移动}printf("折半插入排序后的结果是:\n关键字比较了%d次\n关键字移动了%d次\n ",count3,count4);for(i=2;i<=num;i++){p rintf("%2d ",L[i]);i f(i%10==0)printf("\n ");}}void xepx(int L[MAXSIZE],int num) //希尔排序{creatdata();int temp;int i,j,d;d=num/2; //确定第一次分组while(d>=1) //在第一组内进行向后的比较{f or(i=d+1;i<=num;i++) //对各组进行排序{temp=L[i];j=i-d;count6++; //如果while(d>=1)成立则此处有关键字的移动while((j>0)&&(temp<L[j])) //对组内进行排序{L[j+d]=L[j];j=j-d;count6++; //如果while 成立则此处有关键字的移动}count5++; //由于组内比较所以此处有关键字的比较L[j+d]=temp;count6++; //此处有关键字的移动}d=d/2;}printf("\n希尔排序后的结果是:\n关键字比较了%d次\n关键字移动了%d次\n ",count5,count6);for(i=2;i<=num;i++){p rintf("%2d ",L[i]);i f(i%10==0)printf("\n ");}}void mppx(int L[MAXSIZE]) //冒泡排序{creatdata();int flag=1;int temp;for(int i=1;i<=num && flag!=0;i++) //第一层循环排序{flag=0;for(int j=1;j<=(num-i);j++) //第二层循环排序{if(L[j]<L[j+1]){temp = L[j];L[j] = L[j+1];L[j+1] = temp; //进行排序flag=1;count8=count8+2; //如果if成立则此处有关键字的移动}count7++; //由于内部排序上面的if语句此处有关键字的比较}}printf("\n冒泡排序后的结果是:\n关键字比较了%d次\n关键字移动了%d次\n",count7,count8);for(i=1;i<num;i++){p rintf("%2d ",L[num-i]);i f(i%10==0)printf("\n ");}}void xzpx(int L[MAXSIZE]) //选择排序{creatdata();int i,j,k,temp;for(i=1;i<num;i++) //第一趟循环寻找最小记录{k=i;f or(j=i+1;j<=num;j++) //查找关键字最小的记录{if(L[k]<L[j]){k=j;} //查到最小记录的关键字然后与第一个数互换位置count9++; //此处有关键字的比较if(i!=k){temp=L[i];L[i]=L[k];L[k]=temp; //将关键字最小记录与还未排序的第一个数交换count10+=2; //如果if 成立则关键字有移动(!!!此处有问题显然if肯定有成立的时候所以count10会有值但是测试结果一直是0 搞不清原因)}}}printf("\n选择排序后的结果是:\n关键字比较了%d次\n关键字移动了%d次\n ",count9,count10);for(i=1;i<num;i++){p rintf("%2d ",L[num-i]);i f(i%10==0)printf("\n ");}}/*int partition(int L[MAXSIZE],int low,int high){int temp,t;int i,j,pos,flag;int change1,change2;temp=L[1]; //保存该元素的值pos=low; //记录当前位置change1=change2=0; //记录每次比较的起始元素,距离区间头或尾的偏移量do{f lag=1; //没有元素交换f or(i=high-change1;i>=pos+1;i--) //在左区间进行比较{if(L[i]<temp){t=L[pos];L[pos]=L[i];L[i]=t;pos=i; flag=0; change1++; //记录新的位置pos,偏移量增加break;}}i f(flag==0) //如果左区间有元素发生移动,则对右区间进行比较{flag=1;for(j=low+change2;j<=pos-1;j++) //从右区间的起始位置开始,一直到基准元素所处的位置{if(L[j]>temp){t=L[j];L[j]=L[pos];L[pos]=t;pos=j; flag=0; change2++;break; //如果有元素交换,flag置0,记录新的位置,偏移量增加}}}}while(flag==0);for(i=0;i<=7;i++)p rintf("%d ",*(a+i));printf("\n\n");return pos;}void kspx(int L[MAXSIZE],int b,int t){creatdata();int i;if(b<t){i=partition(L,b,t); //对区间(b,t)进行第一次划分k spx(L,b,i-1); //左区间进行划分k spx(L,i+1,t); //右区间进行划分}}*/void compare(int L[MAXSIZE]){printf("排序方式直接折半希尔冒泡选择\n");printf("比较次数%4d %4d %4d %4d %4d \n",count1,count3,count5,count7,count9);printf("移动次数%4d %4d %4d %4d %4d \n",count2,count4,count6,count8,count10); }void menu(int L[MAXSIZE]){int x;printf(" \n1 直接排序 4 冒泡排序7比较数据统计\n");printf(" ");printf(" \n2 折半排序 5 快速排序(未完成) 0 退出\n");printf(" ");printf(" \n3 希尔排序6选择排序\n");printf(" ");printf("\n请输入对应的序号查看结果\n");scanf("%d",&x);if(x>=0&&x<=7){s witch(x){c ase 0:exit(0);c ase 1:zjpx(L);menu(L);break;c ase 2:zbpx(L);menu(L);break;c ase 3:xepx(L,num);menu(L);break;c ase 4:mppx(L);menu(L);break;// case 5:kspx(L,0,10);menu(L);break;c ase 6:xzpx(L);menu(L);break;c ase 7:compare(L);menu(L);break;}}else{p rintf("输入有误!");m enu(L);}}void main(){creatdata();FILE* fp;int i=0;fp=fopen("O_data.txt","r"); //只读if(fp==NULL) //失败{p rintf("错误!");e xit(1); //中止程序}while(!feof(fp)) //从文件读出数据f scanf(fp,"%d",&(L[i++]));fclose(fp);printf("随机生成的数为:\n");for(i=0;i<num;i++){i f(i%10==0)p rintf("\n");p rintf("%2d ",L[i]);}printf("\n");menu(L);}3.实验数据分析:本实验共成功测试了5个排序方法,除了选择排序的关键字比较出现问题外实验结果全部合理正确,在统计关键字比较以及移动的问题上,与预想的结果相差不大,可以认为测试基本成功。