Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 堆排序:如何排序?_Python_Sorting_Computer Science_Heapsort - Fatal编程技术网

Python 堆排序:如何排序?

Python 堆排序:如何排序?,python,sorting,computer-science,heapsort,Python,Sorting,Computer Science,Heapsort,我试图在Python中实现堆排序,但似乎做得不对。我已经尝试实现了这个,但是我的代码没有排序!它只是筛选到荒谬的效果。我倾向于认为问题在这方面: 将堆的根(最大值)与堆的最后一个元素交换 如何获得最大值 这就是我所拥有的: def my_heap_sort(sqc): def heapify(count): start = (count-2)/2 while s

我试图在Python中实现堆排序,但似乎做得不对。我已经尝试实现了这个,但是我的代码没有排序!它只是筛选到荒谬的效果。我倾向于认为问题在这方面:

将堆的根(最大值)与堆的最后一个元素交换

如何获得最大值

这就是我所拥有的:

def my_heap_sort(sqc):                    
    def heapify(count):                
        start = (count-2)/2            
        while start >= 0:              
            sift_down(start, count-1)  
            start -= 1                 

    def swap(i, j):                    
        sqc[i], sqc[j] = sqc[j], sqc[i]

    def sift_down(start, end):         
        root = start                   

        while (root * 2 + 1) <= end:   
            child = root * 2 + 1       
            temp = root                
            if sqc[temp] < sqc[child]: 
                temp = child+1         
            if temp != root:           
                swap(root, temp)       
                root = temp            
            else:                      
                return                 

    count = len(sqc)                   
    heapify(count)                     

    end = count-1                      

    while end > 0:                     
        swap(end, 0)                   
        end -= 1                       
        sift_down(0, end)              

选择排序是一种相对直接的排序算法: 遍历数组,提取前n个元素的最小值,然后提取下n-1个元素的最小值。。。。。。 这就是O(n^2)算法

由于您总是提取最小值,因此应该考虑使用最小堆。它在O(logn)时间内提取一分钟。提取min n次导致O(n*logn)时间

因此,对于堆排序,只需要构建一个堆(heapifyo(n)),然后遍历数组并提取min n次

您可以使用python构建堆或构建自己的堆

def heapsort(l):
    hp = make_heap(l)
    for i in range(len(l)):
       yield hp.extract_min() 

如何获取最大值?您不需要“获取”它。根正好是最大值,这是堆的一个已定义属性

如果您觉得难以理解堆排序,将非常有帮助


我重写了你的代码:

def swap(i, j):                    
    sqc[i], sqc[j] = sqc[j], sqc[i] 

def heapify(end,i):   
    l=2 * i + 1  
    r=2 * (i + 1)   
    max=i   
    if l < end and sqc[i] < sqc[l]:   
        max = l   
    if r < end and sqc[max] < sqc[r]:   
        max = r   
    if max != i:   
        swap(i, max)   
        heapify(end, max)   

def heap_sort():     
    end = len(sqc)   
    start = end // 2 - 1 # use // instead of /
    for i in range(start, -1, -1):   
        heapify(end, i)   
    for i in range(end-1, 0, -1):   
        swap(i, 0)   
        heapify(i, 0)   

sqc = [2, 7, 1, -2, 56, 5, 3]
heap_sort()
print(sqc)

我找到了它,几乎想知道它是如何工作的:

def heapsort(sqc):                                 
    def down_heap(sqc, k, n):                            
        parent = sqc[k]                                  

        while 2*k+1 < n:                                 
            child = 2*k+1                                
            if child+1 < n and sqc[child] < sqc[child+1]:
                child += 1                               
            if parent >= sqc[child]:                     
                break                                    
            sqc[k] = sqc[child]                          
            k = child                                    
        sqc[k] = parent                                  

    size = len(sqc)                                      

    for i in range(size/2-1, -1, -1):                    
        down_heap(sqc, i, size)                          

    for i in range(size-1, 0, -1):                       
        sqc[0], sqc[i] = sqc[i], sqc[0]                  
        down_heap(sqc, 0, i)                             
def heapsort(sqc):
def向下堆(sqc、k、n):
父项=sqc[k]
当2*k+1=sqc[子级]:
打破
sqc[k]=sqc[child]
k=儿童
sqc[k]=父级
尺寸=长度(sqc)
对于范围内的i(尺寸/2-1,-1,-1):
下堆(sqc、i、尺寸)
对于范围内的i(尺寸-1,0,-1):
sqc[0],sqc[i]=sqc[i],sqc[0]
向下堆(sqc,0,i)
编辑: 这个实现是基于我自己对算法的理解编写的。它更长,但对我来说,这个算法在这个实现中更清晰。当您需要理解算法时,长名称是有帮助的,所以我保留了所有长名称

def heapsort(sequence):                                                      
    sequence_length = len(sequence)                                          

    def swap_if_greater(parent_index, child_index):                          
        if sequence[parent_index] < sequence[child_index]:                   
            sequence[parent_index], sequence[child_index] =\                 
                    sequence[child_index], sequence[parent_index]            

    def sift(parent_index, unsorted_length):                                 
        index_of_greater = lambda a, b: a if sequence[a] > sequence[b] else b
        while parent_index*2+2 < unsorted_length:                            
            left_child_index = parent_index*2+1                              
            right_child_index = parent_index*2+2                             

            greater_child_index = index_of_greater(left_child_index,         
                    right_child_index)                                       

            swap_if_greater(parent_index, greater_child_index)               

            parent_index = greater_child_index                               

    def heapify():                                                           
        for i in range((sequence_length/2)-1, -1, -1):                       
            sift(i, sequence_length)                                         

    def sort():                                                              
        count = sequence_length                                              
        while count > 0:                                                     
            count -= 1                                                       
        swap_if_greater(count, 0)                                        
        sift(0, count)                                                   

    heapify()                                                                
    sort()                                                        
def heapsort(顺序):
序列长度=len(序列)
def交换如果大于(父索引、子索引):
如果序列[父索引]<序列[子索引]:
序列[父索引],序列[子索引]=\
序列[子索引],序列[父索引]
def sift(父索引,未排序的长度):
大于的索引=λa,b:a如果序列[a]>序列[b]否则b
而父索引*2+2<未排序的长度:
左\子\索引=父\索引*2+1
右\子\索引=父\索引*2+2
更大的子索引=更大的索引(左子索引,
右(子索引)
如果大于,则交换(父索引,子索引)
父索引=更大的子索引
def heapify():
对于范围内的i((序列长度/2)-1,-1,-1):
筛选(i,序列长度)
def sort():
计数=序列长度
当计数>0时:
计数-=1
如果_大于(计数,0),则交换_
筛选(0,计数)
希皮菲()
排序()
编辑: 和优化版本:

def opt_heapsort(s):                               
    sl = len(s)                                    

    def swap(pi, ci):                              
        if s[pi] < s[ci]:                          
            s[pi], s[ci] = s[ci], s[pi]            

    def sift(pi, unsorted):                        
        i_gt = lambda a, b: a if s[a] > s[b] else b
        while pi*2+2 < unsorted:                   
            gtci = i_gt(pi*2+1, pi*2+2)            
            swap(pi, gtci)                         
            pi = gtci                              
    # heapify                                      
    for i in range((sl/2)-1, -1, -1):              
        sift(i, sl)                                
    # sort                                         
    for i in range(sl-1, 0, -1):                   
        swap(i, 0)                                 
        sift(0, i)                                 
def opt_heapsort(s):
sl=透镜(s)
def交换(pi、ci):
如果s[pi]s[b]否则b
而pi*2+2<未排序:
gtci=i_gt(π*2+1,π*2+2)
交换(pi、gtci)
pi=gtci
#希皮菲
对于范围((sl/2)-1,-1,-1)内的i:
筛选(i,sl)
#分类
对于范围内的i(sl-1,0,-1):
互换(i,0)
筛选(0,i)

我发现heapify(堆排序的“核心”)的不同实现在internetz上并不清楚。下面是我谦虚的尝试,通过添加一个简单但清晰的“heapify”示例来帮助社区。我使用向量来避免数组操作带来的额外混乱

此方法对数组中的1个单元格进行重排序。 使整体健康
def heapsort(sqc):                                 
    def down_heap(sqc, k, n):                            
        parent = sqc[k]                                  

        while 2*k+1 < n:                                 
            child = 2*k+1                                
            if child+1 < n and sqc[child] < sqc[child+1]:
                child += 1                               
            if parent >= sqc[child]:                     
                break                                    
            sqc[k] = sqc[child]                          
            k = child                                    
        sqc[k] = parent                                  

    size = len(sqc)                                      

    for i in range(size/2-1, -1, -1):                    
        down_heap(sqc, i, size)                          

    for i in range(size-1, 0, -1):                       
        sqc[0], sqc[i] = sqc[i], sqc[0]                  
        down_heap(sqc, 0, i)                             
def heapsort(sequence):                                                      
    sequence_length = len(sequence)                                          

    def swap_if_greater(parent_index, child_index):                          
        if sequence[parent_index] < sequence[child_index]:                   
            sequence[parent_index], sequence[child_index] =\                 
                    sequence[child_index], sequence[parent_index]            

    def sift(parent_index, unsorted_length):                                 
        index_of_greater = lambda a, b: a if sequence[a] > sequence[b] else b
        while parent_index*2+2 < unsorted_length:                            
            left_child_index = parent_index*2+1                              
            right_child_index = parent_index*2+2                             

            greater_child_index = index_of_greater(left_child_index,         
                    right_child_index)                                       

            swap_if_greater(parent_index, greater_child_index)               

            parent_index = greater_child_index                               

    def heapify():                                                           
        for i in range((sequence_length/2)-1, -1, -1):                       
            sift(i, sequence_length)                                         

    def sort():                                                              
        count = sequence_length                                              
        while count > 0:                                                     
            count -= 1                                                       
        swap_if_greater(count, 0)                                        
        sift(0, count)                                                   

    heapify()                                                                
    sort()                                                        
def opt_heapsort(s):                               
    sl = len(s)                                    

    def swap(pi, ci):                              
        if s[pi] < s[ci]:                          
            s[pi], s[ci] = s[ci], s[pi]            

    def sift(pi, unsorted):                        
        i_gt = lambda a, b: a if s[a] > s[b] else b
        while pi*2+2 < unsorted:                   
            gtci = i_gt(pi*2+1, pi*2+2)            
            swap(pi, gtci)                         
            pi = gtci                              
    # heapify                                      
    for i in range((sl/2)-1, -1, -1):              
        sift(i, sl)                                
    # sort                                         
    for i in range(sl-1, 0, -1):                   
        swap(i, 0)                                 
        sift(0, i)                                 
for (int i = myvector.size()/2; i >= 0; i--) { in = Heapify(in, i);}

vector_of_int Sort::Heapify(vector_of_int in_vector, int in_index)
{

int min_index = in_index; // Track index of smallest out of parent and two children.
int left_child_index = 0; 
int right_child_index = 0;
int vector_size = in_vector.size(); 

left_child_index = LeftChildIndex(in_index);// index of left child, at position 2*in_index
right_child_index = left_child_index + 1;// index of right child, at position 2*in_index + 1

// If left_child_index is not overflowing, suggest swap...
if ((left_child_index) < vector_size) 
{
    // If parent larger than left child, min_index remembers left child position
    if (in_vector[min_index] > in_vector[left_child_index]) 
    { min_index = left_child_index; }
}

// If right_child_index is is not overflowing, suggest swap...
if (right_child_index < vector_size) 
{
    // If parent larger than right child, min_index remembers right child position
    if (in_vector[min_index] > in_vector[right_child_index]) 
    { min_index = right_child_index; }
}

// Now min_index has the index of the smallest out of parent and it's two children.
// If the smallest is not the parent, swap parent and smallest.
if (min_index != in_index) 
{
    in_vector = swap(in_vector, in_index ,min_index);
    in_vector = Heapify(in_vector, min_index); // RECURSION IS HERE
}

return in_vector;
}
// End heapify
def findMin(heapArr,i,firstChildLoc,secondChildLoc):
        a = heapArr[i]
        b = heapArr[firstChildLoc]
        c = heapArr[secondChildLoc]
        return i if ((a < b) and (a < c)) else firstChildLoc if (b < c) else secondChildLoc


def prelocateUp(heapArr):
    l = len(heapArr)
    i = l-1
    while True:
        parentLoc = (i+1)/2 - 1 
        if parentLoc >= 0:
            if heapArr[parentLoc] > heapArr[i]:
                temp = heapArr[parentLoc]
                heapArr[parentLoc] = heapArr[i]
                heapArr[i] = temp  
        else :
            break
        i = parentLoc
    return heapArr

def prelocateDown(heapArr):

    l = len(heapArr)
    i = 0

    while True:
        firstChildLoc = 2*(i+1) - 1
        secondChildLoc = 2*(i+1)
        if (firstChildLoc > l-1):
            break

        elif (secondChildLoc > l-1):
            if heapArr[i] > heapArr[firstChildLoc]:
                temp = heapArr[i]
                heapArr[i] = heapArr[firstChildLoc]
                heapArr[firstChildLoc] = temp
            break

        else :
            minLoc = findMin(heapArr,i,firstChildLoc,secondChildLoc)
            if minLoc !=i:
                temp = heapArr[i]
                heapArr[i] = heapArr[minLoc]
                heapArr[minLoc] = temp
                i = minLoc
            else :
                break
    return heapArr



def heapify(heapArr,op):
    if op==1:
        heapArr = prelocateUp(heapArr)
    else :
        heapArr = prelocateDown(heapArr)
    return heapArr

def insertHeap(heapArr,num):
    heapArr.append(num)
    heapArr = heapify(heapArr,1)
    return heapArr

def getMin(heapArr):
    ele = heapArr[0]
    heapArr[0] = heapArr[-1]
    heapArr.pop(-1)
    heapArr = heapify(heapArr,2)
    return ele,heapArr

a=[5,4,8,2,6]
heapArr = []
for i in xrange(0,len(a)):
    heapArr = insertHeap(heapArr,a[i])

#No 
sortedArr = []
for i in xrange(0,len(a)):
    [ele,heapArr] = getMin(heapArr)
    sortedArr.append(ele)
print sortedArr
from heapq import heappush, heappop
def heapsort(iterable):
    h = []
    for value in iterable:
        heappush(h, value)
    return [heappop(h) for i in range(len(h))]

heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
**Heap Sorting on any given Number,Below Program will first convert it into binary heap tree and then its performing heap sorting**

class HeapSort():
    def __init__(self):
        self.hst_list=[None]
        self.final_list=[]

    def add_element(self,value):
        self.hst_list.append(value)

    def build_hst(self):
        for _ in range((len(self.hst_list)//2)):
            self.convert_into_hst()

    def get_left_child(self,idx):
        for m in range(len(self.hst_list)):
            if m==2*idx:
                return self.hst_list[2*idx]
        return 999

    def get_right_child(self,idx):
        for m in range(len(self.hst_list)):
            if m==2*idx+1:
                return self.hst_list[2*idx+1]
        return 999

    def convert_into_hst(self):
        i=1
        while i<=len(self.hst_list)//2: 
            left_child=self.get_left_child(i)
            right_child=self.get_right_child(i) 
            if self.hst_list[i]>=left_child:
                p_val=self.hst_list[i]
                self.hst_list[i]=left_child
                self.hst_list[2*i]=p_val
                #print(self.hst_list)
            elif self.hst_list[i]>=right_child:
                p_val=self.hst_list[i]
                self.hst_list[i]=right_child
                self.hst_list[2*i+1]=p_val
            i=i+1

    def print_hst(self):
        print(self.hst_list)
        print(self.final_list)

    def perform_sorting(self):
        for i in range(1,len(self.hst_list)):
            self.perform_heap_sorting()

    def perform_heap_sorting(self):
        self.final_list.append(self.hst_list[1])
        self.hst_list.pop(1)
        self.build_hst()
        print(self.final_list)

hst_obj=HeapSort()
hst_obj.add_element(10)
hst_obj.add_element(5)
hst_obj.add_element(5)
hst_obj.add_element(30)
hst_obj.add_element(15)
hst_obj.add_element(50)
hst_obj.add_element(25)
hst_obj.add_element(35)
hst_obj.add_element(1)
hst_obj.add_element(100)
hst_obj.build_hst()
hst_obj.perform_sorting()