锦标赛排序
2015-07-20 17:06
190 查看
锦标赛排序的算法思想与体育比赛类似。
首先将n个数据元素两两分组,分别按关键字进行比较,得到n/2个比较的优胜者(关键字小者),作为第一步比较的结果保留下来,
然后对这n/2个数据元素再两两分组,分别按关键字进行比较,…,如此重复,直到选出一个关键字最小的数据元素为止。
首先将n个数据元素两两分组,分别按关键字进行比较,得到n/2个比较的优胜者(关键字小者),作为第一步比较的结果保留下来,
然后对这n/2个数据元素再两两分组,分别按关键字进行比较,…,如此重复,直到选出一个关键字最小的数据元素为止。
#include #include #include #include #define SIZE 100000 #define MAX 1000000 struct node { long num;//关键字 char str[10]; int lastwin;//最后胜的对手 int killer;//被击败的对手 long times;//比赛次数 }data[SIZE]; long CompareNum=0; long ExchangeNum=0; long Read(char name[])//读取文件a.txt中的数据,并存放在数组data[]中;最后返回数据的个数 { FILE *fp; long i=1; fp=fopen(name,"rw"); fscanf(fp,"%d%s",&data[i].num,data[i].str); while(!feof(fp)) { i++; fscanf(fp,"%d%s",&data[i].num,data[i].str); } return (i-1); } long Create(long num)//创建胜者树,返回冠军(最小数)在数组data[]中的下标 { int i,j1,j2,max,time=1; long min;//记录当前冠军的下标 for(i=1;pow(2,i-1) ; max=pow(2,i-1);//求叶子结点数目 for(i=1;i<=max;i++)//初始化叶子结点 { data[i].killer=0; data[i].lastwin=0; data[i].times=0; if(i>num) data[i].num=MAX; } for(i=1;i<=max;i+=2)//第一轮比赛 { ++CompareNum; if(data[i].num <= data[i+1].num) { data[i].lastwin = i+1; data[i+1].killer=i; ++data[i].times; ++data[i+1].times; min=i; } else { data[i+1].lastwin=i; data[i].killer=i+1; ++data[i].times; ++data[i+1].times; min=i+1; } } j1=j2=0;//记录连续的两个未被淘汰的选手的下标 while(time <= (log(max)/log(2)))//进行淘汰赛 { for(i=1;i<=max;i++) { if(data[i].times==time && data[i].killer==0)//找到一名选手 { j2=i;//默认其为两选手中的后来的 if(j1==0)//如果第一位置是空的,则刚来的选手先来的 j1=j2; else//否则刚来的选手是后来的,那么选手都已到场比赛开始 { ++CompareNum; if(data[j1].num <= data[j2].num)//先来的选手获胜 { data[j1].lastwin = j2;//最后赢的是j2 data[j2].killer=j1;//j2是被j1淘汰的 ++data[j1].times; ++data[j2].times;//两选手场次均加1 min=j1;//最小数下标为j1 j1=j2=0;//将j1,j2置0 } else//同理 { data[j2].lastwin=j1; data[j1].killer=j2; ++data[j1].times; ++data[j2].times; min=j2; j1=j2=0; } } } } time++;//轮数加1 } return min;//返回冠军的下标 } void TournamentSort(long num)//锦标赛排序 { long tag=Create(num);//返回最小数下标 FILE *fp1; fp1=fopen("sort.txt","w+");//为写入创建并打开文件sort.txt while(data[tag].num != MAX)//当最小值不是无穷大时 { printf("%d %s\n",data[tag].num,data[tag].str);//输出数据 fprintf(fp1,"%d %s\n",data[tag].num,data[tag].str);//写入数据 data[tag].num=MAX;//将当前冠军用无穷大替换 tag=Create(num);//返回下一个冠军的下标 } } int main() { int num; char name[10]; printf("Input name of the file:"); gets(name); num=Read(name);//读文件 TournamentSort(num);//锦标赛排序 printf("CompareNum=%d\nExchangeNum=%d\n",CompareNum,ExchangeNum); return 0; }
相关文章推荐
- NYOJ 84 阶乘的0的个数
- 多线程中的ReadWriteLock锁问题
- hdu3722Card Game 概率dp水题
- ajax调用期间添加蒙层blockUI
- 提高效率—编程中的技巧
- 学习ios的网站
- 基础总结篇之一:Activity生命周期
- Matlab函数bwmorph
- oracle实例名,服务名等概念区别与联系
- 关于UIBarButtonItem的一点札记
- Javascript 多浏览器兼容性问题及解决方案
- PyYAML使用
- K-means学习笔记
- 在MVC的WebApi中默认是没有开启Session会话支持的。需要在Global中重写Init方法来指定会话需要支持的类型
- XCode无法打开
- js 动画1
- [基本实验] 探测Web目录结构和隐藏的敏感文件
- 杭电 2005 第几天?
- java处理日期
- Java关键字this、super使用总结