python实现k路归并排序,败者树

败者树叶子结点存放待比较的k个数,父结点中存放两个子节点中的败者,胜者继续往上比较。定义值小的胜,则根节点存放最小值。定义值大的胜,则根节点存放的最大值;

#多路外部归并排序,败者树

#b[i]<b[j],则i胜j败,ls[t]中存放j,i继续往上比较,ls[0]根结点放的是最小值;
Max=10000000
Num=100000
k=Max//Num
b=[0 for i in range(0,k)]
ls=[-1 for i in range(0,k)]
isend=[0 for i in range(0,k)]

def Adjust(s):
    t=(s+k)//2
    while t>0:
        if (b[s]>b[ls[t]] or ls[t]==-1) and s >=0:  #b[s]败,则更新父节点;
            tmp=s
            s=ls[t]
            ls[t]=tmp
        t=t//2

    ls[0]=s  #ls[0]中存放最小值


def CreateLoserTree():
    for i in range(k-1,-1,-1):
        Adjust(i)


#读取所有数据,把数据有序存储到k个文件中
def MemorySort():
    file_object=open(r'D:\Practice\testdata\testdata.txt')
    for j in range(0,k):
        file_data=[0 for i in range(0,Num)]
        for i in range(0,Num):
            file_data[i]=int(file_object.readline().replace('\n',''))


        #排序
        quickSort(file_data,0,Num-1)


        file_objectw=open(r'D:\Practice\testdata\testdata%s.txt'%j,'w')
        for i in range(0,Num):
            file_objectw.write('%s\n'%file_data[i])


    file_object.close()
    file_objectw.close()
            
def MergeSort():
    file_objects=[0 for i in range(0,k)]
    #初始化败者树叶子结点
    for i in range(0,k):
        file_objects[i]=open(r'D:\Practice\testdata\testdata%s.txt'%i)
        b[i]=int(file_objects[i].readline().replace('\n',''))
    CreateLoserTree()


    fileout_object=open(r'D:\Practice\testdata\testdataout.txt','w')
    while b[ls[0]]!=Max:
    #输出min
        fileout_object.write('%s\n'%b[ls[0]])
        tmp=file_objects[ls[0]].readline().replace('\n','')
        if tmp!='':
            b[ls[0]]=int(tmp)
            Adjust(ls[0])
        else:
            isend[ls[0]]=1
            b[ls[0]]=Max+1
            Adjust(ls[0])
    fileout_object.write('%s\n'%Max)


    for i in range(0,k):
        file_objects[i].close()
    fileout_object.close()


    
beginTime=time.clock()
MemorySort()
endTime=time.clock()
print("内存排序时间")
print(endTime-beginTime)


beginTime=time.clock()
MergeSort()
endTime=time.clock()
print("归并k路文件时间")
print(endTime-beginTime)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值