পাইথনের সাথে কুইস্কোর্ট


94

আমি অজগর থেকে সম্পূর্ণ নতুন এবং আমি এটিতে কুইকোর্টটি বাস্তবায়নের চেষ্টা করছি। কেউ দয়া করে আমার কোডটি সম্পূর্ণ করতে আমাকে সহায়তা করতে পারেন?

আমি জানি না কীভাবে তিনটি অ্যারে যুক্ত করতে এবং সেগুলি মুদ্রণ করা যায়।

def sort(array=[12,4,5,6,7,3,1,15]):
    less = []
    equal = []
    greater = []

    if len(array) > 1:
        pivot = array[0]
        for x in array:
            if x < pivot:
                less.append(x)
            if x == pivot:
                equal.append(x)
            if x > pivot:
                greater.append(x)
            sort(less)
            sort(pivot)
            sort(greater)

তালিকাগুলি একত্রিত করতে আপনি প্লাস অপারেটর ব্যবহার করতে পারেন my_list = list1 + list2 + ...। অথবা তালিকাগুলি নতুন তালিকায় আনপ্যাক করুনmy_list = [*list1, *list2]
نشان মিশিন

উত্তর:


255
def sort(array=[12,4,5,6,7,3,1,15]):
    """Sort the array by using quicksort."""

    less = []
    equal = []
    greater = []

    if len(array) > 1:
        pivot = array[0]
        for x in array:
            if x < pivot:
                less.append(x)
            elif x == pivot:
                equal.append(x)
            elif x > pivot:
                greater.append(x)
        # Don't forget to return something!
        return sort(less)+equal+sort(greater)  # Just use the + operator to join lists
    # Note that you want equal ^^^^^ not pivot
    else:  # You need to handle the part at the end of the recursion - when you only have one element in your array, just return the array.
        return array

8
অপ্রয়োজনীয় তুলনা করা এড়াতে এবং ifলুপের জন্য আপনি ২ য় elifelse
এসও সরিয়ে নিতে পারেন

13
এটি মার্জ সাজ্টের মতো দ্রুত সাজানোর মতো শব্দ নয়
এমাদ মোক্তার

47
এটি আসলে সবচেয়ে ভাল এবং সর্বাধিক পঠনযোগ্য পাইথন কোডটি আমি কোথাও কোয়ারকোর্টের জন্য খুঁজে পেয়েছি । কোনও সূচক নেই, কোনও সহায়ক ফাংশন স্পষ্টভাবে অ্যালগরিদমের সংক্ষিপ্তসার (বিভাজন এবং বিজয়) প্রদর্শন করে না। (অ্যারের জন্য ডিফল্ট মানটি বরং অপ্রয়োজনীয়)
সিমেটাস

20
@ জেএসমেডার এটি কোনও স্থান সংস্করণের চেয়ে বেশি মেমরি ব্যবহার করবে, স্থান দ্রুত সাজানোর জন্য উত্তরটির উত্তর দেখুন।
জন

15
খুব পঠনযোগ্য তবে দ্রুত পর্বতারোহণের উদ্দেশ্যটি কি এটি পরাভূত করে না কারণ এটি 'স্থানে' বাছাই করে না? @ রাসমিরঞ্জননায়ক সাজান এখানে ব্যবহারকারীর সংজ্ঞায়িত ফাংশন (এটির পুনরাবৃত্তি কল), কোনও ফাংশনে অন্তর্নিহিত নয়।
মকসুদ

161

অতিরিক্ত মেমরি ছাড়াই দ্রুত সাজানো (জায়গায়)

ব্যবহার:

array = [97, 200, 100, 101, 211, 107]
quicksort(array)
# array -> [97, 100, 101, 107, 200, 211]
def partition(array, begin, end):
    pivot = begin
    for i in xrange(begin+1, end+1):
        if array[i] <= array[begin]:
            pivot += 1
            array[i], array[pivot] = array[pivot], array[i]
    array[pivot], array[begin] = array[begin], array[pivot]
    return pivot



def quicksort(array, begin=0, end=None):
    if end is None:
        end = len(array) - 1
    def _quicksort(array, begin, end):
        if begin >= end:
            return
        pivot = partition(array, begin, end)
        _quicksort(array, begin, pivot-1)
        _quicksort(array, pivot+1, end)
    return _quicksort(array, begin, end)

23
এটি নির্বাচিত উত্তর হওয়া উচিত, কারণ কুইকোর্টটি প্রায়শই পছন্দের অ্যালগরিদম হয় (যেমন উদাহরণস্বরূপ মার্জ সাজান) কারণ এটি স্থানটি সাজায় (এবং এখনও ও (নলগন) রানটাইম দেয়)।
বোল্টজমানব্রেন

4
if end is None:অনেকবার যাচাই করা হবে এবং এটি একবারই হবে True। আপনার এটি একটি মোড়ক ফাংশনে রাখা উচিত যাতে এটি কেবল একবার ডাকা হয়।
গিলেস্পি

যথাযথভাবে, ব্রুহস, @ এমক্সটিভ সঠিক এবং এই লাইনটি ভুল। অতিরিক্তভাবে, সঙ্গে array[pivot], array[begin] = array[begin], array[pivot]প্রতিস্থাপন করা উচিত । beginend
রায়ান জে ম্যাককাল

4
যদিও জায়গাটিতে ভাল, এটি ধীর এবং এটি প্রচুর আইটেম থাকে যখন সর্বাধিক পুনরাবৃত্তির গভীরতা মারার কারণে এটি ত্রুটিযুক্ত হয়। দেখতে repl.it/@almenon/quicksorts?language=python3
Almenon

@ এমকস্টেভ এবং রায়ান, আমি এই পরিবর্তনগুলি পরীক্ষা করেছি এবং এটি বাছাইগুলি ভাঙ্গা করে
aljgom

68

আরও একটি সংক্ষিপ্ত এবং সুন্দর সংস্করণ রয়েছে

def qsort(arr): 
    if len(arr) <= 1:
        return arr
    else:
        return qsort([x for x in arr[1:] if x < arr[0]]) + \
               [arr[0]] + \
               qsort([x for x in arr[1:] if x >= arr[0]])

# this comment is just to improve readability due to horizontal scroll!!!

বিস্তারিত জানতে আমার উপরের কোডগুলি ব্যাখ্যা করুন

  1. পাইরেট arr[0]হিসাবে অ্যারের প্রথম উপাদানটি চয়ন করুন

    [arr[0]]

  2. qsort অ্যারেগুলির সেই উপাদানগুলি যা পিভটের চেয়ে কম List Comprehension

    qsort([x for x in arr[1:] if x < arr[0]])

  3. qsort পাইগুলির চেয়ে বড় আকারের অ্যারের উপাদানগুলি List Comprehension

    qsort([x for x in arr[1:] if x >= arr[0]])


15
ডাউনজোটের সম্ভাব্য কারণগুলিতে @ জাঙ্গউ: ১) ইতিমধ্যে বাছাই করা বা বিপরীত অ্যারেগুলিতে চতুষ্কোণ রানটাইম 2) সমাধানটি স্থানে নয়। অতএব, একটি ভয়াবহ বাস্তবায়ন, দুঃখিত।
এলিসিয়ানয়

16
মোটেই পঠনযোগ্য নয়, আপনি কি সত্যিই লাইনের সংখ্যা হ্রাস করার চেষ্টা করছেন? কোড মেশিন দ্বারা ব্যাখ্যা করা হয়, কিন্তু মানুষ দ্বারা বোঝা হয়।
jsmedmar 16'16

4
@ অ্যালফ্রেডো গ্যাল্লেগোস, কুইকোর্টের পুরো বিন্দুটি এটি জায়গায় ঘটেছে, আপনি যদি এটি করতে যাচ্ছেন তবে আপনি পাশাপাশি মার্জ সাজ্টও প্রয়োগ করতে পারেন।
প্যাডেরিক কানিংহাম

14
এই মন্তব্যগুলি কি বাস্তবের জন্য? আপনি যদি পারফরম্যান্স, ব্যবহার করতে চান তবে sortedএটি শিক্ষামূলক উদ্দেশ্যে স্পষ্ট। এবং এটি পাঠযোগ্য, গৃহীত উত্তরের চেয়ে বেশি পঠনযোগ্য।
নোবিলিস

4
এফডাব্লুআইডাব্লু, আমি ভেবেছিলাম এগুলি তাদের মধ্যে সবচেয়ে পঠনযোগ্য বাস্তবায়ন। এটি অন্য কোনও উত্তরের চেয়ে অ্যালগরিদমের পুনরাবৃত্ত কাঠামো দেখায়। অবশ্যই, পারফরম্যান্স খুব দুর্দান্ত হতে যাচ্ছে না।
সলভ ইট

36

এই উত্তরটি জন্য একটি ইন-জায়গা QuickSort হয় Python 2.x। আমার উত্তরটি রোসেটা কোড থেকে স্থানস্থ সমাধানের ব্যাখ্যা যা Python 3খুব কার্যকর হয়:

import random

def qsort(xs, fst, lst):
    '''
    Sort the range xs[fst, lst] in-place with vanilla QuickSort

    :param xs:  the list of numbers to sort
    :param fst: the first index from xs to begin sorting from,
                must be in the range [0, len(xs))
    :param lst: the last index from xs to stop sorting at
                must be in the range [fst, len(xs))
    :return:    nothing, the side effect is that xs[fst, lst] is sorted
    '''
    if fst >= lst:
        return

    i, j = fst, lst
    pivot = xs[random.randint(fst, lst)]

    while i <= j:
        while xs[i] < pivot:
            i += 1
        while xs[j] > pivot:
            j -= 1

        if i <= j:
            xs[i], xs[j] = xs[j], xs[i]
            i, j = i + 1, j - 1
    qsort(xs, fst, j)
    qsort(xs, i, lst)

এবং যদি আপনি স্থানের সম্পত্তিটি ত্যাগ করতে ইচ্ছুক হন তবে নীচে আরও একটি সংস্করণ রয়েছে যা কোয়েস্কোর্টের পিছনে থাকা মূল ধারণাগুলিকে আরও ভালভাবে চিত্রিত করে। পঠনযোগ্যতা ছাড়াও এর অন্যান্য সুবিধাটি হ'ল এটি স্থিতিশীল (সমান তালিকা অনুসারে বাছাই করা তালিকায় সমান উপাদান উপস্থিত থাকে যা তারা সাজানো তালিকায় রাখত না)। এই স্থায়িত্ব সম্পত্তি উপরে উপস্থাপিত কম মেমরি ক্ষুধার্ত ইন-প্লেস বাস্তবায়ন ধরে না।

def qsort(xs):
    if not xs: return xs # empty sequence case
    pivot = xs[random.choice(range(0, len(xs)))]

    head = qsort([x for x in xs if x < pivot])
    tail = qsort([x for x in xs if x > pivot])
    return head + [x for x in xs if x == pivot] + tail

এই সমাধান ভাগ করে নেওয়ার জন্য ধন্যবাদ। আপনি কি আমাদের সময়-জটিলতা বুঝতে সাহায্য করতে পারেন? আমি দেখতে পাচ্ছি যে পুনরাবৃত্তি এটি 15 বার কল করবে। এর মধ্যে 8 টি ফাংশনে বৈধ কল। এর অর্থ কি প্রথম জটিলতার জন্য সময়-জটিলতাটি হ'ল (এন) এবং স্থান জটিলতা হ'ল তার স্থানের ধরণ হিসাবে ও (1)?
ForeverLearner

@ ট্যামি দেখে মনে হচ্ছে আপনি বিগ-ও স্বরলিপিটি ভুল বুঝেছেন। তদুপরি, আমি আপনার প্রশ্নটি সত্যই বুঝতে পারি না। আপনি সম্ভবত এটি পৃথক হিসাবে জিজ্ঞাসা করতে পারেন? অবশেষে, অ্যালগরিদম হিসাবে কুইকসোর্ট ও (এন লগন) সময় এবং ও (এন) স্পেসে চলে।
অ্যালিসিয়ানোয়

4
আমার খারাপ কেন পৃথিবীতে আমি পুনরাবৃত্তি গণনা করছিলাম ?? :-) ভাল, 15 পুনরাবৃত্তি হ'ল [1 কল (স্তর 0) + 2 কল (স্তর 1 পার্টিশন) + 4 কল (স্তর 2 পার্টিশন) + 8 কল (স্তর 3 পার্টিশন বা লিফ নোড)। সুতরাং, আমাদের এখনও উচ্চতা (lg8 + 1) = lgn হিসাবে রয়েছে। প্রতিটি স্তরের মোট গণনা সি 1 (কিছু খরচ) * এন এর জন্য। অতএব O (n lgn)। স্থান মধ্যে একটির জন্য এক্সচেঞ্জ = ও (1) এর জন্য জটিলতা। সুতরাং এন উপাদানগুলির জন্য = ও (এন)। পয়েন্টারের জন্য ধন্যবাদ।
ForeverLearner

4
এটি ইন্টারনেটের সেরা অজগর কুইকোর্টের দূরে এবং এটি এতগুলি হে (এন) স্থান সমাধানের অধীনে সমাধিস্থ হওয়া দেখে দুঃখজনক :(
সাশা কোন্ড্রাশভ

টিমোফাই এই ধরনের শব্দগুলির জন্য ধন্যবাদ। আপনি কটাক্ষপাত করা আমার আলগোরিদিম রেপো চাইতে পারেন, এটা প্রকারের অন্যান্য সংস্করণ গ্রাফ অ্যালগোরিদম, ইত্যাদি ইত্যাদি রয়েছে github.com/alisianoi/algos-py
alisianoi

23

পাইথনের সাথে কুইস্কোর্ট

বাস্তব জীবনে আমাদের সবসময় পাইথন দ্বারা সরবরাহিত বিল্টিন সাজানো ব্যবহার করা উচিত। তবে কুইকোর্টের অ্যালগরিদম বোঝা শিক্ষণীয়।

এখানে আমার লক্ষ্য বিষয়টিকে এমনভাবে ভাঙা যা রেফারেন্স উপকরণগুলিতে ফিরে না এসে পাঠক সহজেই বুঝতে এবং তার প্রতিরূপায়িত হয়।

কুইকসোর্ট অ্যালগরিদম মূলত নিম্নলিখিত:

  1. একটি পিভট ডেটা পয়েন্ট নির্বাচন করুন।
  2. সমস্ত তথ্য পয়েন্টকে পাইভট (নীচে) এর চেয়ে কম পিভটের নীচে অবস্থানে নিয়ে যান - পিভটটি এর চেয়ে বড় বা সমান (উপরে) এর উপরে অবস্থানে নিয়ে যান।
  3. পিভটের উপরে এবং নীচের অংশগুলিতে অ্যালগরিদম প্রয়োগ করুন

যদি ডেটা এলোমেলোভাবে বিতরণ করা হয়, পিভট হিসাবে প্রথম ডেটা পয়েন্ট নির্বাচন করা এলোমেলো নির্বাচনের সমতুল্য।

পাঠযোগ্য উদাহরণ:

প্রথমে আসুন এমন একটি পঠনযোগ্য উদাহরণটি দেখুন যা মন্তব্য এবং পরিবর্তনশীল নামগুলি মধ্যবর্তী মানগুলিতে নির্দেশ করার জন্য ব্যবহার করে:

def quicksort(xs):
    """Given indexable and slicable iterable, return a sorted list"""
    if xs: # if given list (or tuple) with one ordered item or more: 
        pivot = xs[0]
        # below will be less than:
        below = [i for i in xs[1:] if i < pivot] 
        # above will be greater than or equal to:
        above = [i for i in xs[1:] if i >= pivot]
        return quicksort(below) + [pivot] + quicksort(above)
    else: 
        return xs # empty list

এখানে প্রদর্শিত অ্যালগরিদম এবং কোডটি পুনরুদ্ধার করতে - আমরা পিভট থেকে উপরে ডানদিকে মানগুলি এবং পিভট এর নীচে বাম দিকে মানগুলি সরিয়ে ফেলি এবং তারপরে আরও বাছাই করার জন্য সেই অংশগুলি একই ফাংশনে পাস করি।

গল্ফড:

এটি 88 টি অক্ষরে গল্ফ করা যেতে পারে:

q=lambda x:x and q([i for i in x[1:]if i<=x[0]])+[x[0]]+q([i for i in x[1:]if i>x[0]])

আমরা কীভাবে সেখানে পৌঁছেছি তা দেখতে, প্রথমে আমাদের পঠনযোগ্য উদাহরণটি ধরুন, মন্তব্যগুলি এবং ডকাস্ট্রিংগুলি সরিয়ে ফেলুন এবং পাইভটকে জায়গাটিতে খুঁজে পান:

def quicksort(xs):
    if xs: 
        below = [i for i in xs[1:] if i < xs[0]] 
        above = [i for i in xs[1:] if i >= xs[0]]
        return quicksort(below) + [xs[0]] + quicksort(above)
    else: 
        return xs

এখন নীচে এবং উপরে, স্থানটিতে সন্ধান করুন:

def quicksort(xs):
    if xs: 
        return (quicksort([i for i in xs[1:] if i < xs[0]] )
                + [xs[0]] 
                + quicksort([i for i in xs[1:] if i >= xs[0]]))
    else: 
        return xs

এখন, জেনে রাখা যে andপূর্বের উপাদানটিকে মিথ্যা হিসাবে প্রত্যাবর্তন করে, অন্যথায় যদি এটি সত্য হয় তবে তা নীচের উপাদানটিকে মূল্যায়ন করে এবং প্রদান করে, আমাদের কাছে রয়েছে:

def quicksort(xs):
    return xs and (quicksort([i for i in xs[1:] if i < xs[0]] )
                   + [xs[0]] 
                   + quicksort([i for i in xs[1:] if i >= xs[0]]))

যেহেতু ল্যাম্বডাস একটি একক এক্সপ্রেশন ফিরিয়ে দেয় এবং আমরা একটি একক অভিব্যক্তিতে সরলীকৃত হয়েছি (যদিও এটি আরও অপঠনযোগ্য হয়ে উঠছে) আমরা এখন ল্যাম্বদা ব্যবহার করতে পারি:

quicksort = lambda xs: (quicksort([i for i in xs[1:] if i < xs[0]] )
                        + [xs[0]] 
                        + quicksort([i for i in xs[1:] if i >= xs[0]]))

এবং আমাদের উদাহরণ হ্রাস করার জন্য, ফাংশনটি এবং ভেরিয়েবলের নামগুলিকে একটি অক্ষরে সংক্ষিপ্ত করুন এবং প্রয়োজন নেই এমন সাদা স্থানটি মুছে ফেলুন।

q=lambda x:x and q([i for i in x[1:]if i<=x[0]])+[x[0]]+q([i for i in x[1:]if i>x[0]])

মনে রাখবেন যে এই ল্যাম্বদা বেশিরভাগ কোড গল্ফিংয়ের মতোই বরং খারাপ স্টাইল।

হোয়ার পার্টিশন স্কিম ব্যবহার করে ইন-প্লেস কুইকসোর্ট

পূর্ববর্তী বাস্তবায়ন অনেকগুলি অপ্রয়োজনীয় অতিরিক্ত তালিকা তৈরি করে। যদি আমরা এটি জায়গায় রাখতে পারি তবে আমরা জায়গার অপচয় করা এড়াব।

নীচের বাস্তবায়নটি হোয়ের পার্টিশনিং স্কিম ব্যবহার করে, যা আপনি উইকিপিডিয়াতে আরও পড়তে পারেন (তবে আমরা স্পষ্টত 4 ডু partition()-র পরিবর্তে ডু-ওয়ুপের পরিবর্তে লুপ শব্দার্থক ব্যবহার করে এবং সংকীর্ণ পদক্ষেপগুলি শেষের দিকে নিয়ে যাওয়ার মাধ্যমে কল প্রতি 4 রিডানড্যান্ট গণনা সরিয়ে ফেলেছি বাহ্যিক যখন লুপ।)।

def quicksort(a_list):
    """Hoare partition scheme, see https://en.wikipedia.org/wiki/Quicksort"""
    def _quicksort(a_list, low, high):
        # must run partition on sections with 2 elements or more
        if low < high: 
            p = partition(a_list, low, high)
            _quicksort(a_list, low, p)
            _quicksort(a_list, p+1, high)
    def partition(a_list, low, high):
        pivot = a_list[low]
        while True:
            while a_list[low] < pivot:
                low += 1
            while a_list[high] > pivot:
                high -= 1
            if low >= high:
                return high
            a_list[low], a_list[high] = a_list[high], a_list[low]
            low += 1
            high -= 1
    _quicksort(a_list, 0, len(a_list)-1)
    return a_list

আমি এটি পুরোপুরি ভালভাবে পরীক্ষা করেছি কিনা তা নিশ্চিত নয়:

def main():
    assert quicksort([1]) == [1]
    assert quicksort([1,2]) == [1,2]
    assert quicksort([1,2,3]) == [1,2,3]
    assert quicksort([1,2,3,4]) == [1,2,3,4]
    assert quicksort([2,1,3,4]) == [1,2,3,4]
    assert quicksort([1,3,2,4]) == [1,2,3,4]
    assert quicksort([1,2,4,3]) == [1,2,3,4]
    assert quicksort([2,1,1,1]) == [1,1,1,2]
    assert quicksort([1,2,1,1]) == [1,1,1,2]
    assert quicksort([1,1,2,1]) == [1,1,1,2]
    assert quicksort([1,1,1,2]) == [1,1,1,2]

উপসংহার

এই অ্যালগরিদম ঘন ঘন কম্পিউটার বিজ্ঞান কোর্সে শেখানো হয় এবং চাকরীর সাক্ষাত্কারের জন্য জিজ্ঞাসা করা হয়। এটি আমাদের পুনরাবৃত্তি এবং বিভাজন এবং বিজয় সম্পর্কে চিন্তা করতে সহায়তা করে।

পাইথনে ক্যুইসকোর্ট খুব বেশি ব্যবহারিক নয় কারণ আমাদের বিল্টিন টাইমসোর্ট অ্যালগরিদম বেশ দক্ষ এবং আমাদের পুনরাবৃত্তির সীমা রয়েছে। আমরা প্রত্যাশাগুলি একসাথে list.sortতালিকাগুলি বাছাই বা এর সাথে নতুন সাজানো তালিকাগুলি তৈরি করব sorted- যার উভয়টিই গ্রহণ করেkeyreverse যুক্তি এবং যুক্তি গ্রহণ করে।


তোমার partitionফাংশন জন্য সঠিকভাবে কাজ না বলে মনে হচ্ছে: partition([5,4,3,2,1], 0, 4)। প্রত্যাশিত রিটার্ন সূচকটি 4, যখন এটি 3
ফেরান

@ ম্যাটিনো এই প্রত্যাশাটি কোথা থেকে এল? আমি বিশ্বাস করি যে আমি অ্যালগরিদমকে সরলীকরণ করেছি (এই উত্তরটি লেখার সময় উইকিপিডিয়াতে যেমন বলা হয়েছিল), যদিও আমি ভুল হতে পারি বা সম্ভবত কম দক্ষ। আপনি যদি কোনও পরীক্ষা-কেস সন্ধান করতে পারেন যার জন্য পুরো কুইকোর্টের ফাংশন ব্যর্থ হয় তবে তা সহায়ক be
অ্যারন হল

অ্যারোনহাল @ যখন আমি পাইভট = এ_লিস্ট [উচ্চ] বেছে নিয়েছিলাম তবে কীভাবে এটি কার্যকর করা যায় তা আমি ঠিক বুঝতে পারি না। তুমি কি সাহায্য করতে পারো ?
কিউলাং

@ ম্যাটিনো আমারও একই বিভ্রান্তি ছিল! পার্টিশন ফাংশনটি ঠিক আছে, আক্রমণাত্মকরা এটি পূরণ করে যা আপনি প্রত্যাশা করছেন তার চেয়ে দুর্বল - এটি সঠিক স্থানটি খুঁজে পাবে না যা পাইভটের চেয়ে বাম এবং ডান থেকে ছোট এবং বৃহত্তর পৃথক করে। এটি কেবলমাত্র একটি তুচ্ছ পার্টিশনের গ্যারান্টি দেয় এবং প্রত্যাবর্তিত সূচকের সমস্ত বাম প্রত্যাবর্তিত সূচকের ডানদিকের চেয়ে ছোট হয়।
আতঙ্ক স্পাইজার

21

ইতিমধ্যে এর অনেক উত্তর রয়েছে তবে আমি মনে করি এই পদ্ধতির সর্বাধিক পরিচ্ছন্ন বাস্তবায়ন:

def quicksort(arr):
    """ Quicksort a list

    :type arr: list
    :param arr: List to sort
    :returns: list -- Sorted list
    """
    if not arr:
        return []

    pivots = [x for x in arr if x == arr[0]]
    lesser = quicksort([x for x in arr if x < arr[0]])
    greater = quicksort([x for x in arr if x > arr[0]])

    return lesser + pivots + greater

আপনি অবশ্যই ভেরিয়েবলের মধ্যে সমস্ত কিছু সঞ্চয় করে এড়িয়ে যেতে পারেন এবং সরাসরি তাদের এভাবে ফিরিয়ে দিতে পারেন:

def quicksort(arr):
    """ Quicksort a list

    :type arr: list
    :param arr: List to sort
    :returns: list -- Sorted list
    """
    if not arr:
        return []

    return quicksort([x for x in arr if x < arr[0]]) \
        + [x for x in arr if x == arr[0]] \
        + quicksort([x for x in arr if x > arr[0]])

11
চালু!)? এটি কি 'স্লোসোর্ট'?
স্কট 理论 理论

4
আমি প্রথম কোড উদাহরণে বিশ্বাস করি এটি '[কম]' এবং '[বৃহত্তর]' এর পরিবর্তে 'কম' এবং 'বৃহত্তর' হওয়া উচিত - অন্যথায় আপনি ফ্ল্যাটগুলির পরিবর্তে নেস্টেড তালিকা দিয়ে শেষ করতে পারেন with
এলিস

@ স্কট 混合 still আমি এখনও সময়ের জটিলতা শিখছি, আপনি কি ব্যাখ্যা করতে পারেন যে এই বাস্তবায়ন কেন O(N!)? নেস্টেড তালিকা ধরে নেওয়া যাক [lesser]এবং [greater]টাইপস, তাই না এটা গড় হবে O(3N logN)যা গড় প্রত্যাশিত কমাতে হবে O(N logN)? মঞ্জুর, 3 তালিকার কমপগুলি অপ্রয়োজনীয় কাজ করে ..
ক্রিসি

@ ক্রিস্পি আপনি যদি 5,4,3,2,1 এর মতো একটি উল্টানো অর্ডার তালিকাটি বাছাই করেন তবে
স্কট 理论 理论

@ স্কট 混合 理论 আপনি ঠিক বলেছেন যে দ্রুততম ধরণের চলমান সময়টি ধীর Θ (এন ^ 2), তবে "অ্যালগরিদমের সাথে পরিচিতি" অনুসারে, গড়-কেস চলমান সময় Θ (n lg n)। এবং, আরও গুরুত্বপূর্ণভাবে, দ্রুত বাছাই সাধারণত অনুশীলনে হিপ
সাজানকে

6

কার্যকরী পদ্ধতির:

def qsort(list):
    if len(list) < 2:
        return list

    pivot = list.pop()
    left = filter(lambda x: x <= pivot, list)
    right = filter(lambda x: x > pivot, list)

    return qsort(left) + [pivot] + qsort(right)

অজগর তালিকায় সংরক্ষিত আছে 3.. আপনার কোডটির
কুন্থার

আক্কার এবং @ কুন্থার এই উভয় সমাধানই পাইথন 2 বা পাইথন 3-এ উভয় ক্ষেত্রেই তালিকাগুলি চালানোর সময় তালিকাগুলি থেকে পপ করবে, সুতরাং তালিকাটি ধ্বংস করে দেবে। এখানে একটি স্থির সংস্করণ রয়েছে: gist.github.com/joshuatvernon/634e0d912401899af0fdc4e23c94192b
জোশুয়াথেরন


4

গ্রুকিং অ্যালগরিদম থেকে সহজ প্রয়োগ

def quicksort(arr):
    if len(arr) < 2:
        return arr #base case
    else:
        pivot = arr[0]
        less = [i for i in arr[1:] if i <= pivot] 
        more = [i for i in arr[1:] if i > pivot]
        return quicksort(less) + [pivot] + quicksort(more)

3

আমি মনে করি যে এখানে উভয় উত্তর সরবরাহিত তালিকার জন্য সঠিকভাবে কাজ করে (যা মূল প্রশ্নের উত্তর দেয়), তবে অদ্বিতীয় মান সহ একটি অ্যারে পাস হলে তা ভেঙে যায়। সম্পূর্ণতার জন্য, আমি কেবল প্রত্যেকের মধ্যে ছোট্ট ত্রুটিটি নির্দেশ করব এবং সেগুলি কীভাবে ঠিক করব তা ব্যাখ্যা করব।

উদাহরণস্বরূপ, নীচের অ্যারেটি বাছাই করার চেষ্টা করছেন [12,4,5,6,7,3,1,15,1] (দ্রষ্টব্য যে 1 টি একবার প্রদর্শিত হয়েছে) সাথে ব্রায়নিয়াস অ্যালগরিদমের সাথে .. কিছুটা সময় কম অ্যারে খালি দিয়ে শেষ হবে এবং এক জোড়া মানগুলির সমান অ্যারে (1,1) যা পরের পুনরাবৃত্তিতে এবং লেন ()> 1 এ পৃথক করা যায় না ... সুতরাং আপনি অসীম লুপটি সহ শেষ করবেন

জাংউ উত্তরের মত আপনার সমান অ্যারেতে বাছাই না করে কম ফাঁকা থাকলে বা আরও ভাল হলে আপনি অ্যারে দিয়ে ফিরে এটি ঠিক করতে পারেন

def sort(array=[12,4,5,6,7,3,1,15]):
    less = []
    equal = []
    greater = []

    if len(array) > 1:
        pivot = array[0]
        for x in array:
            if x < pivot:
                less.append(x)
            if x == pivot:
                equal.append(x)
            if x > pivot:
                greater.append(x)

        # Don't forget to return something!
        return sort(less)+ equal +sort(greater)  # Just use the + operator to join lists
    # Note that you want equal ^^^^^ not pivot
    else:  # You need to hande the part at the end of the recursion - when you only have one element in your array, just return the array.
        return array

ফ্যানসিয়ার সলিউশনটিও ভেঙে যায় তবে অন্য কোনও কারণে, এটির প্রত্যাবর্তন অনুপস্থিত পুনরাবৃত্ত লাইনে অনুচ্ছেদটি , যার ফলে কোনও একসময় কোনওটি ফিরে আসবে না এবং এটি একটি তালিকায় যুক্ত করার চেষ্টা করবে ...

এটি ঠিক করতে কেবল এই লাইনে একটি রিটার্ন যুক্ত করুন

def qsort(arr): 
   if len(arr) <= 1:
      return arr
   else:
      return qsort([x for x in arr[1:] if x<arr[0]]) + [arr[0]] + qsort([x for x in arr[1:] if x>=arr[0]])

যাইহোক, সংক্ষিপ্ত সংস্করণটি দীর্ঘের তুলনায় কম কর্মক্ষমতা রয়েছে, যেহেতু এটি তালিকাটি বোঝার ক্ষেত্রে অ্যারে পুনরুক্ত করে চলেছে।
ফেডএন

3

এটি হোয়ের পার্টিশন স্কিম ব্যবহার করে এবং কম অদলবদল এবং স্থানীয় ভেরিয়েবল সহ কুইকোর্টের একটি সংস্করণ

def quicksort(array):
    qsort(array, 0, len(array)-1)

def qsort(A, lo, hi):
    if lo < hi:
        p = partition(A, lo, hi)
        qsort(A, lo, p)
        qsort(A, p + 1, hi)

def partition(A, lo, hi):
    pivot = A[lo]
    i, j = lo-1, hi+1
    while True:
      i += 1
      j -= 1
      while(A[i] < pivot): i+= 1
      while(A[j] > pivot ): j-= 1

      if i >= j: 
          return j

      A[i], A[j] = A[j], A[i]


test = [21, 4, 1, 3, 9, 20, 25, 6, 21, 14]
print quicksort(test)

3

পার্টিশন - ছোট্ট উপাদানগুলি বাম দিকে সরানো হয় এবং বৃহত্তর এলিমেটগুলি ডান বা বিপরীত দিকে সরানো হয় iv একটি পিভট একটি অ্যারের থেকে এলোমেলো উপাদান হতে পারে। এই অ্যালগরিদটি তৈরি করতে আমাদের একটি অ্যারের সূচনা এবং শেষ সূচীটি কী এবং পিভটটি কোথায় তা জানতে হবে। তারপরে দুটি সহায়ক পয়েন্টার এল, আর সেট করুন

সুতরাং আমাদের কাছে একটি অ্যারে ব্যবহারকারী রয়েছে [..., শুরু, ..., শেষ, ...]

এল এবং আর পয়েন্টারগুলির সূচনা অবস্থান
[..., শুরু, পরবর্তী, ..., শেষ, ...]
     আর এল

যখন L <শেষ
  1 হয়। যদি কোনও ব্যবহারকারী [পিভট]> ব্যবহারকারী [এল] তবে আর এক করে আর সরান ব্যবহারকারী [আর] এর সাথে ব্যবহারকারী [এল]
  ২। এল এক করে নিয়ে যান

ব্যবহারকারী [পিভট] সাথে ব্যবহারকারী [আর] অদলবদল করার পরে

দ্রুত সাজান - পিভট দ্বারা বিভাজনের প্রতিটি পরবর্তী অংশ শেষ সূচকগুলির চেয়ে সূচকটি বৃহত্তর বা সমান হতে শুরু না হওয়া অবধি পার্টিশন অ্যালগরিদম ব্যবহার করুন।

def qsort(user, begin, end):

    if begin >= end:
        return

    # partition
    # pivot = begin
    L = begin+1
    R = begin
    while L < end:
        if user[begin] > user[L]:
            R+=1
            user[R], user[L] = user[L], user[R]
        L+= 1
    user[R], user[begin] = user[begin], user[R]

    qsort(user, 0, R)
    qsort(user, R+1, end)

tests = [
    {'sample':[1],'answer':[1]},
    {'sample':[3,9],'answer':[3,9]},
    {'sample':[1,8,1],'answer':[1,1,8]},
    {'sample':[7,5,5,1],'answer':[1,5,5,7]},
    {'sample':[4,10,5,9,3],'answer':[3,4,5,9,10]},
    {'sample':[6,6,3,8,7,7],'answer':[3,6,6,7,7,8]},
    {'sample':[3,6,7,2,4,5,4],'answer':[2,3,4,4,5,6,7]},
    {'sample':[1,5,6,1,9,0,7,4],'answer':[0,1,1,4,5,6,7,9]},
    {'sample':[0,9,5,2,2,5,8,3,8],'answer':[0,2,2,3,5,5,8,8,9]},
    {'sample':[2,5,3,3,2,0,9,0,0,7],'answer':[0,0,0,2,2,3,3,5,7,9]}
]

for test in tests:

    sample = test['sample'][:]
    answer = test['answer']

    qsort(sample,0,len(sample))

    print(sample == answer)

দয়া করে আপনার কোড / সংযোজনগুলি ব্যাখ্যা করুন যাতে ওপি এবং ভবিষ্যতের মতামত আরও বেশি উপকার করতে পারে।
ওমর ইয়না

2

অথবা আপনি যদি একটি ওয়ান-লাইনার পছন্দ করেন যা সি / সি ++ ভেরাগস, ল্যাম্বডা এক্সপ্রেশন এবং যদি এক্সপ্রেশনগুলির সাথে পাইথন সমতুল্য চিত্রিত করে:

qsort = lambda x=None, *xs: [] if x is None else qsort(*[a for a in xs if a<x]) + [x] + qsort(*[a for a in xs if a>=x])

2
def quick_sort(self, nums):
    def helper(arr):
        if len(arr) <= 1: return arr
        #lwall is the index of the first element euqal to pivot
        #rwall is the index of the first element greater than pivot
        #so arr[lwall:rwall] is exactly the middle part equal to pivot after one round
        lwall, rwall, pivot = 0, 0, 0
        #choose rightmost as pivot
        pivot = arr[-1]
        for i, e in enumerate(arr):
            if e < pivot:
                #when element is less than pivot, shift the whole middle part to the right by 1
                arr[i], arr[lwall] = arr[lwall], arr[i]
                lwall += 1
                arr[i], arr[rwall] = arr[rwall], arr[i]
                rwall += 1
            elif e == pivot:
                #when element equals to pivot, middle part should increase by 1
                arr[i], arr[rwall] = arr[rwall], arr[i]
                rwall += 1
            elif e > pivot: continue
        return helper(arr[:lwall]) + arr[lwall:rwall] + helper(arr[rwall:])
    return helper(nums)

2

আমি জানি যে অনেকে এই প্রশ্নের সঠিক উত্তর দিয়েছেন এবং আমি সেগুলি পড়ে আনন্দিত। আমার উত্তরটি প্রায় জাংডব্লিউর মতোই তবে আমি মনে করি যে পূর্ববর্তী অবদানকারীরা জিনিসগুলি কীভাবে বাস্তবে কাজ করে তা দৃষ্টিভঙ্গি দিয়ে ব্যাখ্যা করার জন্য ভাল কাজ করেন নি ... তাই ভবিষ্যতে এই প্রশ্ন / উত্তরগুলি দেখতে যেতে পারে এমন অন্যদের সহায়তা করার জন্য আমার চেষ্টা এখানে কুইকোর্টের বাস্তবায়নের সহজ সমাধান।

এটা কিভাবে কাজ করে ?

  1. আমরা মূলত আমাদের তালিকা থেকে প্রথম আইটেমটিকে পাইভট হিসাবে নির্বাচন করি এবং তারপরে আমরা দুটি উপ তালিকা তৈরি করি।
  2. আমাদের প্রথম সাবলিস্টে আইটেমগুলি পিভটের চেয়ে কম রয়েছে
  3. আমাদের দ্বিতীয় সাবলিস্টে আমাদের আইটেমগুলি রয়েছে যা পাইভটের চেয়ে দুর্দান্ত বা সমান
  4. এরপরে আমরা তাদের প্রত্যেককে দ্রুত বাছাই করি এবং চূড়ান্ত ফলাফল পেতে আমরা তাদের প্রথম গ্রুপ + পাইভট + দ্বিতীয় গ্রুপকে একত্রিত করি।

ভিজ্যুয়াল সহ এটির সাথে যেতে এখানে একটি উদাহরণ রয়েছে ... (পিভট) 9,11,2,0

গড়: এন লগ এর n

খারাপ ক্ষেত্রে: এন n 2

এখানে চিত্র বর্ণনা লিখুন

কোড:

def quicksort(data):
if (len(data) < 2):
    return data
else:
    pivot = data[0]  # pivot
    #starting from element 1 to the end
    rest = data[1:]
    low = [each for each in rest if each < pivot]
    high = [each for each in rest if each >= pivot]
    return quicksort(low) + [pivot] + quicksort(high)

আইটেম = [9,11,2,0] মুদ্রণ (কুইকোর্ট (আইটেম))


2

অ্যালগরিদমে দুটি সীমানা রয়েছে, একটি পিভটের চেয়ে কম উপাদান রয়েছে (সূচী "j" দ্বারা চিহ্নিত) এবং অন্যটি পিভটের চেয়ে বড় উপাদান রয়েছে (সূচক "i" দ্বারা চিহ্নিত)।

প্রতিটি পুনরাবৃত্তিতে একটি নতুন উপাদান j বাড়িয়ে প্রক্রিয়া করা হয়।

আক্রমণকারী: -

  1. পিভট এবং আমি এর মধ্যে সমস্ত উপাদান পিভটের চেয়ে কম এবং এবং
  2. i এবং j এর মধ্যে সমস্ত উপাদান পিভটের চেয়ে বেশি।

যদি আক্রমণকারীটি লঙ্ঘিত হয় তবে ith এবং jth উপাদানগুলি অদলবদল করা হয়, এবং আমি বৃদ্ধি পেয়েছি।

সমস্ত উপাদানগুলি প্রক্রিয়া করার পরে, এবং পাইভট বিভাজন হওয়ার পরে সমস্ত কিছু পরে, পিভট উপাদানটি তার চেয়ে ছোট ছোট উপাদান দিয়ে অদলবদল করা হয়।

পিভট উপাদানটি এখন ক্রমের সঠিক জায়গায় থাকবে। এর আগের উপাদানগুলি এর চেয়ে কম হবে এবং এর পরের উপাদানগুলি এর চেয়ে বেশি হবে এবং সেগুলি সাজানো হবে না।

def quicksort(sequence, low, high):
    if low < high:    
        pivot = partition(sequence, low, high)
        quicksort(sequence, low, pivot - 1)
        quicksort(sequence, pivot + 1, high)

def partition(sequence, low, high):
    pivot = sequence[low]
    i = low + 1
    for j in range(low + 1, high + 1):
        if sequence[j] < pivot:
            sequence[j], sequence[i] = sequence[i], sequence[j]
            i += 1
    sequence[i-1], sequence[low] = sequence[low], sequence[i-1]
    return i - 1

def main(sequence):
    quicksort(sequence, 0, len(sequence) - 1)
    return sequence

if __name__ == '__main__':
    sequence = [-2, 0, 32, 1, 56, 99, -4]
    print(main(sequence))

একটি পিভট নির্বাচন করা হচ্ছে

একটি "ভাল" পিভট প্রায় একই আকারের দুটি উপ-অনুক্রমের ফলাফল করবে। নির্ধারিতভাবে, একটি পাইভট উপাদানটি নির্দোষ পদ্ধতিতে বা অনুক্রমের মধ্যক গণনা করে বাছাই করা যায়।

পিভট বাছাইয়ের একটি নিষ্পাপ বাস্তবায়ন হ'ল প্রথম বা শেষ উপাদান। এই ক্ষেত্রে সবচেয়ে খারাপতম রানটাইমটি তখন হবে যখন ইনপুট ক্রমটি ইতিমধ্যে বাছাই করা বা বিপরীতভাবে সাজানো হয়, যেহেতু পরের একটিটি খালি থাকবে যার ফলে পুনরাবৃত্তিকারী কল অনুসারে কেবলমাত্র একটি উপাদান মুছে ফেলা হবে।

পিভটটি ক্রমের মধ্যম উপাদান হ'লে পুরোপুরি সুষম বিভক্ত হয় achieved এর চেয়ে বড় এবং এর চেয়ে কম সংখ্যক উপাদান রয়েছে। এই পদ্ধতির উন্নত সামগ্রিক চলমান সময়ের গ্যারান্টি দেয় তবে এটি অনেক বেশি সময়সাপেক্ষ।

পিভট বাছাই করার একটি অ-নিয়ন্ত্রক / এলোমেলো উপায় হল এলোমেলোভাবে অভিন্ন উপাদান পছন্দ করা। এটি একটি সহজ এবং লাইটওয়েট পদ্ধতির যা সবচেয়ে খারাপ পরিস্থিতি হ্রাস করবে এবং মোটামুটি ভারসাম্যপূর্ণ বিভাজনের দিকে পরিচালিত করবে। এটি নিষ্প্রভ পদ্ধতির এবং পাইভট নির্বাচন করার মধ্যম পদ্ধতির মধ্যে একটি ভারসাম্যও সরবরাহ করবে।


2
def quicksort(array):
 if len(array) < 2:
  return array
 else:
  pivot = array[0]

 less = [i for i in array[1:] if i <= pivot]
 greater = [i for i in array[1:] if i > pivot]
 return quicksort(less) + [pivot] + quicksort(greater)

এই কোডটি সমস্যার সমাধান দিতে পারে এমন সময়ে, এই কোডটি কেন এবং / অথবা কীভাবে প্রশ্নের উত্তর দেয় সে সম্পর্কে আপনাকে অতিরিক্ত প্রসঙ্গ সরবরাহ করার পক্ষে বাঞ্ছনীয়। কোডের উত্তরগুলি সাধারণত দীর্ঘমেয়াদে অকেজো হয়ে যায় কারণ ভবিষ্যতের দর্শকদের অনুরূপ সমস্যার মুখোমুখি হওয়া সমাধানের পিছনে যুক্তি বুঝতে পারে না।
পালা

1
def quick_sort(array):
    return quick_sort([x for x in array[1:] if x < array[0]]) + [array[0]] \
        + quick_sort([x for x in array[1:] if x >= array[0]]) if array else []

1
def Partition(A,p,q):
    i=p
    x=A[i]
    for j in range(p+1,q+1):
        if A[j]<=x:
            i=i+1
            tmp=A[j]
            A[j]=A[i]
            A[i]=tmp
    l=A[p]
    A[p]=A[i]
    A[i]=l
    return i

def quickSort(A,p,q):
    if p<q:
        r=Partition(A,p,q)
        quickSort(A,p,r-1)
        quickSort(A,r+1,q)
    return A

4
আপনার কোডটি কী করে এবং এটি কীভাবে প্রশ্নের উত্তর দেয় তার ব্যাখ্যা অন্তর্ভুক্ত করুন। বিশেষত এটি প্রশ্নে পোস্ট করা কোডের সাথে কীভাবে সম্পর্কিত। উত্তরে ওপি এবং ভবিষ্যতের দর্শকদের কীভাবে তাদের সমস্যাটিকে ডিবাগ করতে হবে এবং ঠিক করতে হবে তার গাইডেন্স দিতে হবে। আপনার কোডের পেছনের ধারণাটি কী, তা নির্দেশ করে, সমাধানটি কার্যকরভাবে প্রয়োগ করতে এবং আপনার সমাধানটি প্রয়োগ বা পরিবর্তন করতে সহায়তা করে। স্ট্যাক ওভারফ্লো কোনও কোড রাইটিং সার্ভিস নয়, এটি একটি শিক্ষণ এবং শেখার জায়গা।
প্লেকে

1

"সত্য" ইন-প্লেস বাস্তবায়ন [মাইকেল টি। গুডরিচ এবং রবার্তো টামাসিয়া রচিত অ্যালগরিদম ডিজাইন এবং অ্যাপ্লিকেশন বই থেকে অ্যালগরিদম 8.9, 8.11]:

from random import randint

def partition (A, a, b):
    p = randint(a,b)
    # or mid point
    # p = (a + b) / 2

    piv = A[p]

    # swap the pivot with the end of the array
    A[p] = A[b]
    A[b] = piv

    i = a     # left index (right movement ->)
    j = b - 1 # right index (left movement <-)

    while i <= j:
        # move right if smaller/eq than/to piv
        while A[i] <= piv and i <= j:
            i += 1
        # move left if greater/eq than/to piv
        while A[j] >= piv and j >= i:
            j -= 1

        # indices stopped moving:
        if i < j:
            # swap
            t = A[i]
            A[i] = A[j]
            A[j] = t
    # place pivot back in the right place
    # all values < pivot are to its left and 
    # all values > pivot are to its right
    A[b] = A[i]
    A[i] = piv

    return i

def IpQuickSort (A, a, b):

    while a < b:
        p = partition(A, a, b) # p is pivot's location

        #sort the smaller partition
        if p - a < b - p:
            IpQuickSort(A,a,p-1)
            a = p + 1 # partition less than p is sorted
        else:
            IpQuickSort(A,p+1,b)
            b = p - 1 # partition greater than p is sorted


def main():
    A =  [12,3,5,4,7,3,1,3]
    print A
    IpQuickSort(A,0,len(A)-1)
    print A

if __name__ == "__main__": main()

1

অ্যালগরিদমের 4 টি সহজ পদক্ষেপ রয়েছে:

  1. অ্যারেটিকে 3 টি আলাদা আলাদা ভাগে ভাগ করুন: বাম, পিভট এবং ডানদিকে, যেখানে পিভটটিতে কেবল একটি উপাদান থাকবে। অ্যারে প্রথম উপাদান হিসাবে এই পিভট উপাদানটি নির্বাচন করি
  2. পিভট উপাদানগুলির সাথে তুলনা করে উপাদানগুলিকে সংশ্লিষ্ট অংশে যুক্ত করুন। (মন্তব্যে ব্যাখ্যা)
  3. অ্যারেতে সমস্ত উপাদান বাছাই না করা অবধি এই অ্যালগরিদমটি পুনরায় করুন
  4. অবশেষে, বাম + পিভট + ডান অংশগুলিতে যোগদান করুন

পাইথনে অ্যালগরিদমের কোড:

def my_sort(A):

      p=A[0]                                       #determine pivot element. 
      left=[]                                      #create left array
      right=[]                                     #create right array
      for i in range(1,len(A)):
        #if cur elem is less than pivot, add elem in left array
        if A[i]< p:
          left.append(A[i])         
          #the recurssion will occur only if the left array is atleast half the size of original array
          if len(left)>1 and len(left)>=len(A)//2:          
              left=my_sort(left)                            #recursive call
        elif A[i]>p: 
          right.append(A[i])                                #if elem is greater than pivot, append it to right array
          if len(right)>1 and len(right)>=len(A)//2:        # recurssion will occur only if length of right array is atleast the size of original array
              right=my_sort(right)
     A=left+[p]+right                                        #append all three part of the array into one and return it
     return A

my_sort([12,4,5,6,7,3,1,15])

এই অ্যালগরিদমের সাথে বাম এবং ডান অংশগুলির সাথে পুনরাবৃত্তি করুন ry


1

আরেকটি কুইকোর্টের বাস্তবায়ন:

# A = Array 
# s = start index
# e = end index
# p = pivot index
# g = greater than pivot boundary index

def swap(A,i1,i2):
  A[i1], A[i2] = A[i2], A[i1]

def partition(A,g,p):
    # O(n) - just one for loop that visits each element once
    for j in range(g,p):
      if A[j] <= A[p]:
        swap(A,j,g)
        g += 1

    swap(A,p,g)
    return g

def _quicksort(A,s,e):
    # Base case - we are sorting an array of size 1
    if s >= e:
      return

    # Partition current array
    p = partition(A,s,e)
    _quicksort(A,s,p-1) # Left side of pivot
    _quicksort(A,p+1,e) # Right side of pivot

# Wrapper function for the recursive one
def quicksort(A):
    _quicksort(A,0,len(A)-1)

A = [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,-1]

print(A)
quicksort(A)
print(A)

1

সংস্করণ পাইথন ৩.x এর জন্য : operatorমূলত পাঠযোগ্যতার উন্নতি করতে মডিউল ব্যবহার করে একটি কার্যকরী শৈলী ।

from operator import ge as greater, lt as lesser

def qsort(L): 
    if len(L) <= 1: return L
    pivot   = L[0]
    sublist = lambda op: [*filter(lambda num: op(num, pivot), L[1:])]

    return qsort(sublist(lesser))+ [pivot] + qsort(sublist(greater))

এবং হিসাবে পরীক্ষিত হয়

print (qsort([3,1,4,2,5]) == [1,2,3,4,5])

নিস (যতদূর অনথিভুক্ত কোড যায়), যদি অনুরূপ acarca এর , Arnaldo পি মধ্যে Figueira মধ্যে Figueira এর এবং Birger এর বছর নিকট থেকে উত্তর চলে। প্রশ্নটি পড়ার সময় নিশ্চিত না যে এটি একটি উত্তর … complete my code?lambdaসংজ্ঞায়িত করতে ব্যবহার করা sublist()কঠোরভাবে প্রয়োজনীয় বলে মনে হচ্ছে না।
গ্রেইবার্ড

@ গ্রেইবার্ড আসলে, আর্নাল্ডোর কোডটি পাইথন ৩-তে সংকলন করেননি, এছাড়াও, কীভাবে sublistকেবলমাত্র ব্যবহার করে সংজ্ঞায়িত করা যায় filter? এটা কি সম্ভব?
লাইফব্লেন্স

4
(অস্থায়ী মন্তব্য: থিঙ্কিন ' def- এখনও টিঙ্কিং শুরু হয়নি কারণ আমি পুনরাবৃত্তিযোগ্য উপাদানগুলির পৃথক তালিকার জন্য "বিতরণ" করার আরও কার্যকর উপায় আছে কিনা তা সনাক্ত করার চেষ্টা করছি (বা, বিকল্পের সাথে একটিতে একটি তালিকা " বিভাগ "অন্যের পরে)।)
গ্রেইবার্ড

1

এখানে একটি সহজ বাস্তবায়ন: -

def quicksort(array):
            if len(array) < 2:
                  return array
            else:
                  pivot= array[0]
                  less = [i for i in array[1:] if i <= pivot]

                  greater = [i for i in array[1:] if i > pivot]

                  return quicksort(less) + [pivot] + quicksort(greater)

print(quicksort([10, 5, 2, 3]))

0
  1. প্রথমে আমরা অ্যারেতে প্রথম মানটিকে পিভট_ভ্যালু হিসাবে ঘোষণা করি এবং আমরা বাম এবং ডান চিহ্নও নির্ধারণ করি
  2. আমরা প্রথম লুপটি তৈরি করি যখন এটি প্রয়োজনীয় শর্তটি পূরণ না করে পার্টিশন প্রক্রিয়াটি আবার চালানোর জন্য লুপটি সেখানে থাকে
  3. তারপরে আমরা পার্টিশন প্রক্রিয়া প্রয়োগ করি
  4. উভয় বিভাজন প্রক্রিয়া চলার পরে, আমরা এটি যথাযথ শর্তটি সন্তুষ্ট করে কিনা তা পরীক্ষা করে দেখুন। যদি এটি হয়, আমরা এটি হিসাবে চিহ্নিত হিসাবে চিহ্নিত করি, যদি না হয় তবে আমরা বাম এবং ডান মানগুলিকে স্যুইচ করে আবার প্রয়োগ করি apply
  5. এটি হয়ে গেলে বাম এবং ডান মানগুলিতে স্যুইচ করুন এবং স্প্লিট_পয়েন্টটি ফেরত দিন

আমি নীচের কোডটি সংযুক্ত করছি! পিভট মানটির অবস্থানের কারণে এই কুইকোর্টটি একটি দুর্দান্ত শেখার সরঞ্জাম । যেহেতু এটি একটি স্থির জায়গায় রয়েছে, আপনি এটির মাধ্যমে একাধিকবার হাঁটতে পারেন এবং সত্যিই কীভাবে এটি সমস্ত কাজ করে তা একটি হ্যাং পেতে পারেন। অনুশীলনে হে (এন ^ 2) রানটাইম এড়ানোর জন্য পিভটটি এলোমেলো করা ভাল।

def quicksort10(alist):
    quicksort_helper10(alist, 0, len(alist)-1)

def quicksort_helper10(alist, first, last):
    """  """
    if first < last:
        split_point = partition10(alist, first, last)
        quicksort_helper10(alist, first, split_point - 1)
        quicksort_helper10(alist, split_point + 1, last)

def partition10(alist, first, last):
    done = False
    pivot_value = alist[first]
    leftmark = first + 1
    rightmark = last
    while not done:
        while leftmark <= rightmark and alist[leftmark] <= pivot_value:
            leftmark = leftmark + 1
        while leftmark <= rightmark and alist[rightmark] >= pivot_value:
            rightmark = rightmark - 1

        if leftmark > rightmark:
            done = True
        else:
            temp = alist[leftmark]
            alist[leftmark] = alist[rightmark]
            alist[rightmark] = temp
    temp = alist[first]
    alist[first] = alist[rightmark]
    alist[rightmark] = temp
    return rightmark

0
def quick_sort(l):
    if len(l) == 0:
        return l
    pivot = l[0]
    pivots = [x for x in l if x == pivot]
    smaller = quick_sort([x for x in l if x < pivot])
    larger = quick_sort([x for x in l if x > pivot])
    return smaller + pivots + larger

অন্যান্য 18 টি উত্তর, অর্ধেকেরও বেশি ওপির "তিনটি অ্যারেটিকে কীভাবে সংযুক্ত করতে হবে" এর মূল প্রশ্নের উত্তর দেয়। আপনার উত্তর কি নতুন কিছু যুক্ত করে?
তিপিম্ম

0

পার্টিশনের পদক্ষেপে মুদ্রিত ভেরিয়েবলগুলির সাথে সম্পূর্ণ উদাহরণ:

def partition(data, p, right):
    print("\n==> Enter partition: p={}, right={}".format(p, right))
    pivot = data[right]
    print("pivot = data[{}] = {}".format(right, pivot))

    i = p - 1  # this is a dangerous line

    for j in range(p, right):
        print("j: {}".format(j))
        if data[j] <= pivot:
            i = i + 1
            print("new i: {}".format(i))
            print("swap: {} <-> {}".format(data[i], data[j]))
            data[i], data[j] = data[j], data[i]

    print("swap2: {} <-> {}".format(data[i + 1], data[right]))
    data[i + 1], data[right] = data[right], data[i + 1]
    return i + 1


def quick_sort(data, left, right):
    if left < right:
        pivot = partition(data, left, right)
        quick_sort(data, left, pivot - 1)
        quick_sort(data, pivot + 1, right)

data = [2, 8, 7, 1, 3, 5, 6, 4]

print("Input array: {}".format(data))
quick_sort(data, 0, len(data) - 1)
print("Output array: {}".format(data))

0
def is_sorted(arr): #check if array is sorted
    for i in range(len(arr) - 2):
        if arr[i] > arr[i + 1]:
            return False
    return True

def qsort_in_place(arr, left, right): #arr - given array, #left - first element index, #right - last element index
    if right - left < 1: #if we have empty or one element array - nothing to do
        return
    else:
        left_point = left #set left pointer that points on element that is candidate to swap with element under right pointer or pivot element
        right_point = right - 1 #set right pointer that is candidate to swap with element under left pointer

        while left_point <= right_point: #while we have not checked all elements in the given array
            swap_left = arr[left_point] >= arr[right] #True if we have to move that element after pivot
            swap_right = arr[right_point] < arr[right] #True if we have to move that element before pivot

            if swap_left and swap_right: #if both True we can swap elements under left and right pointers
                arr[right_point], arr[left_point] = arr[left_point], arr[right_point]
                left_point += 1
                right_point -= 1
            else: #if only one True we don`t have place for to swap it
                if not swap_left: #if we dont need to swap it we move to next element
                    left_point += 1
                if not swap_right: #if we dont need to swap it we move to prev element
                    right_point -= 1

        arr[left_point], arr[right] = arr[right], arr[left_point] #swap left element with pivot

        qsort_in_place(arr, left, left_point - 1) #execute qsort for left part of array (elements less than pivot)
        qsort_in_place(arr, left_point + 1, right) #execute qsort for right part of array (elements most than pivot)

def main():
    import random
    arr = random.sample(range(1, 4000), 10) #generate random array
    print(arr)
    print(is_sorted(arr))
    qsort_in_place(arr, 0, len(arr) - 1)
    print(arr)
    print(is_sorted(arr))

if __name__ == "__main__":
    main()

4
দয়া করে কিছু ব্যাখ্যা সরবরাহ করুন
রায়

0

এই অ্যালগরিদম পুনরাবৃত্তি ফাংশন ব্যবহার করে না।

Nএর সাথে সংখ্যার যে কোনও তালিকা থাকুক len(N) > 0K = [N]নিম্নলিখিত প্রোগ্রামটি সেট করুন এবং সম্পাদন করুন।

দ্রষ্টব্য: এটি একটি স্থিতিশীল বাছাই অ্যালগরিদম।

def BinaryRip2Singletons(K, S):
    K_L = []
    K_P = [ [K[0][0]] ] 
    K_R = []
    for i in range(1, len(K[0])):
        if   K[0][i] < K[0][0]:
            K_L.append(K[0][i])
        elif K[0][i] > K[0][0]:
            K_R.append(K[0][i])
        else:
            K_P.append( [K[0][i]] )
    K_new = [K_L]*bool(len(K_L)) + K_P + [K_R]*bool(len(K_R)) + K[1:]
    while len(K_new) > 0:
        if len(K_new[0]) == 1:
            S.append(K_new[0][0])
            K_new = K_new[1:]
        else: 
            break
    return K_new, S

N = [16, 19, 11, 15, 16, 10, 12, 14, 4, 10, 5, 2, 3, 4, 7, 1]
K = [ N ]
S = []

print('K =', K, 'S =', S)
while len(K) > 0:
    K, S = BinaryRip2Singletons(K, S)
    print('K =', K, 'S =', S)

প্রোগ্রাম আউটপুট:

K = [[16, 19, 11, 15, 16, 10, 12, 14, 4, 10, 5, 2, 3, 4, 7, 1]] S = []
K = [[11, 15, 10, 12, 14, 4, 10, 5, 2, 3, 4, 7, 1], [16], [16], [19]] S = []
K = [[10, 4, 10, 5, 2, 3, 4, 7, 1], [11], [15, 12, 14], [16], [16], [19]] S = []
K = [[4, 5, 2, 3, 4, 7, 1], [10], [10], [11], [15, 12, 14], [16], [16], [19]] S = []
K = [[2, 3, 1], [4], [4], [5, 7], [10], [10], [11], [15, 12, 14], [16], [16], [19]] S = []
K = [[5, 7], [10], [10], [11], [15, 12, 14], [16], [16], [19]] S = [1, 2, 3, 4, 4]
K = [[15, 12, 14], [16], [16], [19]] S = [1, 2, 3, 4, 4, 5, 7, 10, 10, 11]
K = [[12, 14], [15], [16], [16], [19]] S = [1, 2, 3, 4, 4, 5, 7, 10, 10, 11]
K = [] S = [1, 2, 3, 4, 4, 5, 7, 10, 10, 11, 12, 14, 15, 16, 16, 19]

0

সম্ভবত কেবল একটি পছন্দসই জিনিস, তবে আমি আমার ফাংশনগুলির শীর্ষে বৈধতা যুক্ত করতে চাই।

def quicksort(arr):
  if len(arr) <= 1:
    return arr

  left  = []
  right = []
  equal = []
  pivot = arr[-1]
  for num in arr:
    if num < pivot:
      left.append(num)
    elif num == pivot:
      equal.append(num)
    else:
      right.append(num)

  return quicksort(left) + equal + quicksort(right)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.