使用中位数作为枢轴工作进行快速排序(但显示不正确的计数)

时间:2016-08-17 12:24:54

标签: python recursion quicksort median

我在python中使用快速排序来对数字列表进行排序。这必须使用中位数作为枢轴来完成。 我怎么找到中位数? 它是第二大的号码(在原始列表的第一个,中间和最后一个元素的3个数字列表中)

如果列表长度均匀(2j),则中间的no将是第j个元素。

如果列表的长度为奇数(比如5),则中间没有。将是第3个元素

我的代码成功运行。但是,总数没有。所做的比较是不正确的(使用变量 tot_comparisons 找到)

我在做什么?

1.找到枢轴(这是第一个,中间和最后一个元素的中位数)

  1. 用第一个元素替换上面找到的pivot(因为我已经为quicksort准备了代码,第一个元素作为pivot)
  2. 我不需要代码。我在下面发布的是成功的(除了比较部分的总数)。我只需要知道我的代码中的错误

    def swap(A,i,k):
        temp=A[i]
        print "temp is "
        print temp
        A[i]=A[k]
        A[k]=temp
    
    
    def find_median(input_list,start,end):
        #print 'input list is'
        #print input_list
    
        temp_list1=[]
        temp_list1.append(input_list[start])    
        if len(input_list) % 2 ==0:
            middle_element_index=(len(input_list) / 2)-1
            middle_element=input_list[middle_element_index]
            temp_list1.append(middle_element)
        else:
            middle_element_index=len(input_list)/2
            middle_element=input_list[middle_element_index]
            temp_list1.append(middle_element)    
        temp_list1.append(input_list[end])
        temp_list1.sort()
        #print temp_list1
        if len(temp_list1)==3:
            print temp_list1[1]    
            return temp_list1[1]
        elif len(temp_list1)==2:
            print temp_list1[1]    
            return temp_list1[1]
        else:
            print temp_list1[0]    
            return temp_list1[0] 
    
    
    def partition(A,start,end,median_index):
    
        swap(A,start,median_index)
        pivot=A[start]
        pivot_index=start + 1
        for i in range(start+1,end+1):
            if A[i] < pivot:
                swap(A,i,pivot_index)
                pivot_index+=1
        swap(A,pivot_index-1,start)
        return pivot_index-1
    
    def quicksort(A,start,end):
        global tot_comparisons
        if start<end:
            median=find_median(A, start, end)
            median_index=A.index(median)
    
            pivot_index=partition(A,start,end,median_index)
            tot_comparisons+=end-start
            print "pivot_index"
            print pivot_index
            print "ENDS"
    
    
            quicksort(A, start,pivot_index-1)
    
            #tot_comparisons+=end-pivot_index
            #quicksort(A, pivot_index, end)
    
            quicksort(A, pivot_index+1, end)
    
    #A=[45,21,23,4,65]
    
    #A=[21,23,19,22,1,3,7,88,110]
    #A=[1,22,3,4,66,7]
    
    #A=[1, 3, 7, 19, 21, 22, 23, 88, 110]
    #A=[7,2,1,6,8,5,3,4]
    
    temp_list=[]
    f=open('temp_list.txt','r')
    for line in f:
        temp_list.append(int(line.strip()))
    f.close()
    print 'list is '
    #print temp_list
    print 'list ends'
    
    tot_comparisons=0
    #quicksort(A, 0, 7)
    quicksort(temp_list, 0, 9999)
    #quicksort(temp_list, 0, len(temp_list))
    print 'hhh'
    print temp_list
    print tot_comparisons
    #print A
    

1 个答案:

答案 0 :(得分:1)

我相信我发现了一个关键问题: find_median 抓取给定列表的左右元素,但随后添加了原始的中间元素名单。因此,如果您要查找列表位置5:7,则可以获取元素5,7和3.最后一个应该是元素6.这可能会迫使您进行额外的排序工作。

中间元素有索引

  

(开始+结束)/ 2

(整数除法;看起来你正在使用Python 2.?)。对于奇数和偶数长度,你不需要单独的案例。该位置取决于给定的列表,原始长度, len(input_list)

只需列出三个必需元素,对其进行排序,然后返回中间元素。由于只有一个临时列表(显然是列表),因此请缩短该名称。

*/master
${sha1}
:refs/heads/v\d*\.\d*

您可以将其减少为单指令功能。我将输入列表重命名为 ,以帮助提高可读性。

temp = [
    input_list[start],
    input_list[end],
    input_list[(start+end) / 2]
]
temp.sort()
return temp[1]