锦标赛排序

来源:互联网 发布:ubuntu共享文件夹路径 编辑:程序博客网 时间:2024/04/28 04:05

锦标赛排序的算法思想与体育比赛类似。
首先将n个数据元素两两分组,分别按关键字进行比较,得到n/2个比较的优胜者(关键字小者),作为第一步比较的结果保留下来,
然后对这n/2个数据元素再两两分组,分别按关键字进行比较,…,如此重复,直到选出一个关键字最小的数据元素为止。

 #include#include#include#include#define SIZE 100000#define MAX 1000000struct 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;//最后赢的是j2data[j2].killer=j1;//j2是被j1淘汰的++data[j1].times;++data[j2].times;//两选手场次均加1min=j1;//最小数下标为j1j1=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.txtwhile(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;}
0 0
原创粉丝点击