C++代码,数据结构-外部排序-置换-选择排序

置换选择排序实在树形选择排序的基础上的来的,她产生的归并段的长度是不同,。

置换选择排序的操作过程,可以查看书,这里只给出C++可运行成功代码,

注:这里也需要建立败者树,但这里建立败者树的过程和上一个败者树建立过程是不一样的,,也可以自己画图进行建立过程的推导

#include<iostream>
#include<vector>
using namespace std;
#define w 6

typedef  int Losertree[w];

struct rcdnode{
int key;
int rnum;
};

typedef rcdnode Workarea[w];

void Select_mini(Losertree &ls,Workarea &wa,int q){//调整败者树,和上一个败者树的调整类似,但是这里加入了段号,先比较段号,
for(int t=(w+q)/2, p=ls[t];t>0;t=t/2,p=ls[t]){
    if(wa[p].rnum<wa[q].rnum||wa[p].rnum==wa[q].rnum&&wa[p].key<wa[q].key){
        int tem=q;
        q=ls[t];
        ls[t]=tem;
    }
}
ls[0]=q;

}


void Construct_loser(Losertree &ls,Workarea &wa,int fi[]){
for(int i=0;i!=w;++i){
    wa[i].key=wa[i].rnum=ls[i]=0;//工作区初始化
}

for(int i=w-1;i>=0;--i){//输入一个关键字
    wa[i].key=fi[i];
    wa[i].rnum=1;//段号为1
  Select_mini(ls,wa,i);//调整败者树

}
}


void get_run(Losertree &ls,Workarea &wa,int fi[],vector<int> &vec,int &counts,int rc,int &rmax){

while(wa[ls[0]].rnum==rc){//同属于一个段,不需要切换到下一个段
    int q=ls[0];
    int minimax=wa[q].key;
    vec.push_back(minimax);//涮选出一个关键字
    ++counts;
    if(counts>=24){wa[q].rnum=rmax+1;wa[q].key=1000;}//我的记录一共24个,全部读取完之后,则只需要消化败者树中剩余未输出的元素
    else{
        wa[q].key=fi[counts]; //提取下一个关键字
        if(wa[q].key<minimax){  //如果小于上一个涮选出的关键字,则它属于下一段
          rmax=rc+1;
            wa[q].rnum=rmax;
        }
        else{
            wa[q].rnum=rc;//否则属于当前段
        }
    }

    Select_mini(ls,wa,q);
}
}


void  Replace_selection(Losertree &ls,Workarea &wa,int fi[],vector <int>&vec){
Construct_loser(ls,wa,fi);//初建败者树
int rc=1;//当前生成的初始化段的段号,
int rmax=1;//败者树中最大的段号
int counts=5;//我的记录直接放在数组中,所以需要一个指针来指示读取的位置

while(rc<=rmax){//rc=rmax+1的时候标志输入文件的置换排序已经完成
    get_run(ls,wa,fi,vec,counts,rc,rmax);//求得一个初始化段
    vec.push_back(-1);//-1作为一个段的结束,标志作用,
    rc=wa[ls[0]].rnum;//设置下一个段的段号
}


}


int main()
{

int fi[24]={51,49,39,46,38,29,14,61,15,30,1,48,52,3,63,27,4,13,89,24,46,58,33,76};//待排输入文件
vector<int>vec;
Workarea wa;
Losertree ls;
Replace_selection(ls,wa,fi,vec);
for(vector<int>::iterator it=vec.begin();it!=vec.end();++it){//输出置换选择排序后得到的归并段
    if(*it==-1){
        cout<<endl;
    }
    else
    cout<<*it<<"  ";


}
return 0;
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值