কেন ন্যূনতম, উদাহরণস্বরূপ হাস্কেল কুইকোর্ট একটি "সত্য" কুইকোর্ট নয়?


118

হাস্কেলের ওয়েবসাইটটি খুব আকর্ষণীয় 5-লাইনের কুইকোর্টের ফাংশনটি উপস্থাপন করেছে , যা নীচে দেখানো হয়েছে।

quicksort [] = []
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
    where
        lesser = filter (< p) xs
        greater = filter (>= p) xs

এগুলির মধ্যে একটি "সিতে ট্রুই কুইকোর্ট" অন্তর্ভুক্ত রয়েছে ।

// To sort array a[] of size n: qsort(a,0,n-1)

void qsort(int a[], int lo, int hi) 
{
  int h, l, p, t;

  if (lo < hi) {
    l = lo;
    h = hi;
    p = a[hi];

    do {
      while ((l < h) && (a[l] <= p)) 
          l = l+1;
      while ((h > l) && (a[h] >= p))
          h = h-1;
      if (l < h) {
          t = a[l];
          a[l] = a[h];
          a[h] = t;
      }
    } while (l < h);

    a[hi] = a[l];
    a[l] = p;

    qsort( a, lo, l-1 );
    qsort( a, l+1, hi );
  }
}

সি সংস্করণের নীচের লিঙ্কটি এমন একটি পৃষ্ঠার দিকে নির্দেশ করে যা জানিয়েছে যে 'পরিচিতিতে উদ্ধৃত কুইকোর্ট "সত্যিকারের" কুইকোর্ট নয় এবং সি কোডের মতো দীর্ঘ তালিকার জন্য স্কেল করে না' "

উপরের হাস্কেল ফাংশনটি কেন সত্যিকারের কোয়েস্টোর্ট নয়? এটি কীভাবে দীর্ঘ তালিকার জন্য স্কেল করতে ব্যর্থ হয়?


আপনি যে ঠিক পৃষ্ঠাটির বিষয়ে কথা বলছেন তার লিঙ্ক যুক্ত করা উচিত add
স্টেভেন

14
এটি জায়গায় নেই, এইভাবে বেশ ধীর? আসলে ভাল প্রশ্ন!
ফুজ

4
@FUZxxl: হাস্কেল তালিকাগুলি অপরিবর্তনীয় তাই ডিফল্ট ডেটাটাইপগুলি ব্যবহার করে কোনও অপারেশন স্থানস্থ হবে না। এটির গতি হিসাবে - এটি অগত্যা ধীর হবে না; জিএইচসি হ'ল সংকলক প্রযুক্তির একটি চিত্তাকর্ষক অংশ এবং অপরিবর্তনীয় ডেটা স্ট্রাকচার ব্যবহার করে খুব প্রায়শই হ্যাসেল সমাধানগুলি অন্য ভাষায় অন্যান্য পরিবর্তনীয়গুলির সাথে গতি অর্জন করে।
কলম রজার্স

1
এটি কি আসলে কিসোর্ট নয়? মনে রাখবেন কিসোর্টের O(N^2)রানটাইম রয়েছে।
টমাস এডিং

2
এটি লক্ষ করা উচিত যে উপরের উদাহরণটি হাস্কেলের একটি প্রাথমিক উদাহরণ এবং সেই তালিকাগুলি তালিকা বাছাইয়ের জন্য খুব খারাপ পছন্দ very ডেটা.লিস্টে সাজানোটি ২০০২ সালে ফিরে একীভূত করার জন্য পরিবর্তন করা হয়েছিল: হ্যাকেজ.হেসেকেল.আর / প্যাকেজ / অর্চিভ / বেস / ৩.০.৩.১ ডক / এইচটিএমএল / এসসিআর /… , সেখানে আপনি পূর্বের দ্রুত সাজানোর বাস্তবায়নও দেখতে পাবেন। বর্তমান প্রয়োগটি হ'ল একীভূতকরণ যা ২০০৯ সালে তৈরি হয়েছিল: হ্যাকেজ.হেসকেল.আর / প্যাকেজ / অর্চিভ / বেস / ৪.৪.০.০/doc/html/src/…
হাস্কেলএলেফ্যান্ট

উত্তর:


75

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

  1. ভাগ করুন এবং বিজয় করুন: সমস্যাটিকে দুটি ছোট সমস্যায় বিভক্ত করুন।
  2. উপাদানগুলিকে জায়গায় জায়গায় ভাগ করুন।

সংক্ষিপ্ত হাস্কেল উদাহরণ (1) প্রদর্শন করে, তবে (2) নয়। আপনি যদি ইতিমধ্যে কৌশলটি না জানেন তবে কীভাবে (2) সম্পন্ন করা হবে তা স্পষ্ট নয়!


17
informit.com/articles/article.aspx?p=1407357&seqNum=3 - আন্দ্রে আলেকজান্দ্রেস্কু
দ্য_গোস্ট 11'11

পার্টিশন-ইন-প্লেস প্রক্রিয়াটির সুস্পষ্ট বর্ণনার জন্য ইন্টারেক্টিভপীথন.আর . / কোর্সেলিব / স্ট্যাটিক / স্পাইন্ডস / সোর্টস অনুসন্ধান / see দেখুন ।
পিভিলা

57

হাস্কেলের সত্যিকারের স্থান

import qualified Data.Vector.Generic as V 
import qualified Data.Vector.Generic.Mutable as M 

qsort :: (V.Vector v a, Ord a) => v a -> v a
qsort = V.modify go where
    go xs | M.length xs < 2 = return ()
          | otherwise = do
            p <- M.read xs (M.length xs `div` 2)
            j <- M.unstablePartition (< p) xs
            let (l, pr) = M.splitAt j xs 
            k <- M.unstablePartition (== p) pr
            go l; go $ M.drop k pr

অস্থির পার্টিশনের উত্সটি প্রকাশ করে যে এটি প্রকৃতপক্ষে একই স্থানের অদলবদল কৌশল (যতদূর আমি বলতে পারি)।
ড্যান বার্টন

3
এই সমাধানটি ভুল। unstablePartitionখুব অনুরূপ partitionজন্য quicksort, কিন্তু এটা নিশ্চয়তা দেয় না এ উপাদান mতম অবস্থানে ঠিক হয় p
নিমক

29

এখানে "সত্য" কুইকসোর্ট সি কোডকে হাসকেলে রূপান্তর করা হয়েছে। নিজেকে বন্ধনী।

import Control.Monad
import Data.Array.IO
import Data.IORef

qsort :: IOUArray Int Int -> Int -> Int -> IO ()
qsort a lo hi = do
  (h,l,p,t) <- liftM4 (,,,) z z z z

  when (lo < hi) $ do
    l .= lo
    h .= hi
    p .=. (a!hi)

    doWhile (get l .< get h) $ do
      while ((get l .< get h) .&& ((a.!l) .<= get p)) $ do
        modifyIORef l succ
      while ((get h .> get l) .&& ((a.!h) .>= get p)) $ do
        modifyIORef h pred
      b <- get l .< get h
      when b $ do
        t .=. (a.!l)
        lVal <- get l
        hVal <- get h
        writeArray a lVal =<< a!hVal
        writeArray a hVal =<< get t

    lVal <- get l
    writeArray a hi =<< a!lVal
    writeArray a lVal =<< get p

    hi' <- fmap pred (get l)
    qsort a lo hi'
    lo' <- fmap succ (get l)
    qsort a lo' hi

মজা ছিল, তাই না? আমি letপ্রথমে শুরুতে এই বড়টি কেটে ফেলেছিলাম, পাশাপাশি whereফাংশনটির শেষে, পূর্ববর্তী কোডটি কিছুটা সুন্দর করার জন্য সমস্ত সহায়ককে সংজ্ঞায়িত করেছি।

  let z :: IO (IORef Int)
      z = newIORef 0
      (.=) = writeIORef
      ref .=. action = do v <- action; ref .= v
      (!) = readArray
      (.!) a ref = readArray a =<< get ref
      get = readIORef
      (.<) = liftM2 (<)
      (.>) = liftM2 (>)
      (.<=) = liftM2 (<=)
      (.>=) = liftM2 (>=)
      (.&&) = liftM2 (&&)
  -- ...
  where doWhile cond foo = do
          foo
          b <- cond
          when b $ doWhile cond foo
        while cond foo = do
          b <- cond
          when b $ foo >> while cond foo

এবং এখানে, এটি কাজ করে কিনা তা দেখার জন্য একটি বোবা পরীক্ষা।

main = do
    a <- (newListArray (0,9) [10,9..1]) :: IO (IOUArray Int Int)
    printArr a
    putStrLn "Sorting..."
    qsort a 0 9
    putStrLn "Sorted."
    printArr a
  where printArr a = mapM_ (\x -> print =<< readArray a x) [0..9]

আমি হাস্কেলগুলিতে খুব প্রায়ই প্রয়োজনীয় কোডটি লিখি না, তাই আমি নিশ্চিত যে এই কোডটি পরিষ্কার করার প্রচুর উপায় রয়েছে are

তাতে কি?

আপনি লক্ষ্য করবেন যে উপরের কোডটি খুব দীর্ঘ। এর হৃদয় সি কোড হিসাবে প্রায় দীর্ঘ, যদিও প্রতিটি লাইন প্রায়শই কিছুটা আরও ভার্বোজ থাকে। এটি কারণ সি গোপনে প্রচুর পরিমাণে বাজে কাজ করে যা আপনি মেনে নিতে পারেন। উদাহরণস্বরূপ a[l] = a[h];,। এই চপল ভেরিয়েবল ব্যবহারের lএবং h, এবং তারপর চপল অ্যারে ব্যবহারের aতারপর mutates চপল অ্যারে, এবং a। পবিত্র রূপান্তর, ব্যাটম্যান! হাস্কেল-তে, রূপান্তরকরণ এবং মিউটেবল ভেরিয়েবলগুলি অ্যাক্সেস করা সুস্পষ্ট। "নকল" কিউসোর্টটি বিভিন্ন কারণে আকর্ষণীয়, তবে তাদের মধ্যে প্রধান এটি হ'ল রূপান্তর ব্যবহার করে না; এই স্ব-চাপিয়ে দেওয়া সীমাবদ্ধতা এক নজরে বুঝতে এটি আরও সহজ করে তোলে।


3
এটি দুর্দান্ত, একধরণের কৌতুকপূর্ণ উপায়ে। আমি ভাবছি জিএইচসি এরকম কিছু থেকে কী ধরণের কোড উত্পাদন করে?
আয়ান রস

@ আইয়ানরোস: অপরিষ্কার কুইকোর্ট থেকে? জিএইচসি আসলে বেশ শালীন কোড উত্পাদন করে।
জেডি

"" নকল "কিউসোর্টটি বিভিন্ন কারণে আকর্ষণীয় ..." আমি আশঙ্কা করেছি যে জায়গাটিতে হেরফের না করেই এর কার্য সম্পাদন (ইতিমধ্যে উল্লিখিত) ভয়াবহ হতে পারে। এবং সর্বদা পাইভট হিসাবে 1 ম এলিমেন্ট গ্রহণ করা কোনওভাবেই সহায়তা করে না।
ডবল্টর

25

আমার মতে, এটি "সত্যিকারের চিকিত্সা নয়" এই মামলাটিকে তাত্পর্যপূর্ণ করে তোলে। আমি মনে করি এটি কুইকসোর্ট অ্যালগরিদমের বৈধ বাস্তবায়ন , কেবল একটি বিশেষ দক্ষ নয়।


9
কারও সাথে আমার এই যুক্তি একবার হয়েছিল: আমি প্রকৃত কাগজটি সন্ধান করেছি যা কুইকসোর্ট নির্দিষ্ট করেছে এবং প্রকৃতপক্ষে স্থানে রয়েছে।
আইভানম

2
@ivanm হাইপারলিঙ্কস বা এটি ঘটেনি :)
ড্যান বার্টন

1
আমি পছন্দ করি যে এই কাগজটি কীভাবে সমস্ত অপরিহার্য এবং এমনকি লোগারিথমিক স্পেস ব্যবহারের গ্যারান্টি দেওয়ার কৌশলও অন্তর্ভুক্ত রয়েছে (যে সম্পর্কে অনেক লোক জানেন না) যখন ALGOL এ (বর্তমানে জনপ্রিয়) পুনরাবৃত্তি সংস্করণটি কেবল একটি পাদটীকা। অনুমান করুন আমাকে এখন অন্য
কাগজগুলি

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

16

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


5
এবং মার্জেসোর্ট হ'ল (অপরিবর্তনীয়) পছন্দের তালিকার জন্য আরও অনেক প্রাকৃতিক বাছাই করা অ্যালগরিদম, যেখানে এটি সহায়ক অ্যারেগুলির সাথে কাজ করার প্রয়োজনীয়তা থেকে মুক্ত।
hugomg

16

অলস মূল্যায়নের জন্য ধন্যবাদ, একটি হাস্কেল প্রোগ্রাম যা দেখায় তেমনটি করে না (প্রায়শই পারে না )।

এই প্রোগ্রামটি বিবেচনা করুন:

main = putStrLn (show (quicksort [8, 6, 7, 5, 3, 0, 9]))

উত্সাহী ভাষায়, প্রথমে quicksortদৌড়াতে হবে, তারপরে show, তারপর putStrLn। ফাংশনটি চলমান শুরু হওয়ার আগে কোনও ফাংশনের যুক্তি গণনা করা হয়।

হাস্কেলে, এটি বিপরীত। ফাংশনটি প্রথমে চলতে শুরু করে। ফাংশনটি আসলে তাদের ব্যবহার করলেই যুক্তিগুলি গণনা করা হয়। এবং একটি যৌগিক যুক্তি, তালিকার মতো, প্রতিটি টুকরোগুলি ব্যবহৃত হওয়ার সাথে সাথে এক সময় এক টুকরো গণনা করা হয়।

সুতরাং এই প্রোগ্রামে প্রথম যেটি ঘটে তা হ'ল putStrLnচলমান শুরু।

স্ট্রিংয়েরputStrLn আর্গুমেন্টের অক্ষরগুলিকে আউটপুট বাফারে অনুলিপি করে কাজটি GHC এর বাস্তবায়ন । কিন্তু যখন এটি এই লুপটি প্রবেশ করে, showএখনও চালানো হয়নি। সুতরাং, যখন এটি স্ট্রিং থেকে প্রথম চরিত্রটি অনুলিপি করে চলে যায়, হাস্কেল তার চরিত্রটি গণনা করার জন্য কলগুলির ভগ্নাংশটি মূল্যায়ন করে showএবং quicksortকল করে । তারপরে পরবর্তী চরিত্রে চলে আসে। সব তিনটি functions- সঞ্চালনের সুতরাং , , এবং - ইন্টারলিভড্ করা হয়। ক্রমহ্রাসমান কার্যকর করে , মূল্যহীন থাঙ্কগুলির একটি গ্রাফ রেখে যেখানে এটি রেখে গেছে তা মনে রাখে।putStrLnputStrLnshowquicksortquicksort

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

উদাহরণস্বরূপ, কুইকোর্টের পার্টিশনের সি সংস্করণ প্রথম পুনরাবৃত্তির কল হওয়ার আগে সমস্ত ডেটা দেয়। হাস্কেল সংস্করণে, প্রথম পার্টিশনটি শেষ হওয়ার আগে ফলাফলের প্রথম উপাদানটি গণনা করা হবে (এবং আপনার পর্দায় প্রদর্শিত হতে পারে) - আসলে কোনও কাজ শেষ হওয়ার আগেইgreater

পিএস হ্যাসেল কোডটি আরও চিকুইসোর্ট-এর মতো হবে যদি এটি কোয়িকোর্টের মতো একই সংখ্যার তুলনা করে; লিখিত হিসাবে কোড দ্বিগুণ তুলনা করতে পারে কারণ lesserএবং greaterতালিকার মাধ্যমে দুটি লিনিয়ার স্ক্যান করে স্বতন্ত্রভাবে গণনা করা নির্দিষ্ট করা হয়েছে। অতিরিক্ত তুলনা দূর করার জন্য কম্পাইলারটি যথেষ্ট স্মার্ট হওয়ার জন্য এটি নীতিগতভাবেই সম্ভব; অথবা কোডটি ব্যবহারের জন্য পরিবর্তন করা যেতে পারে Data.List.partition

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


2
lpaste.net/108190 । - এটি "অরণ্যযুক্ত গাছের বাছাই" করছে, এটি সম্পর্কে একটি পুরানো reddit থ্রেড আছে। cf. stackoverflow.com/questions/14786904/… এবং সম্পর্কিত।
নেস

1
দেখতে হ্যাঁ, প্রোগ্রামটি আসলে যা করে তা এটির একটি দুর্দান্ত বৈশিষ্ট্য।
জেসন ওরেডরফ

চালনী মন্তব্য পুনরায়, এটি একটি সমতুল্য হিসাবে লেখা হয়েছে primes = unfoldr (\(p:xs)-> Just (p, filter ((> 0).(`rem` p)) xs)) [2..], তার অধিকাংশ অবিলম্বে সমস্যা সম্ভবত পরিষ্কার হবে। এবং আমরা সত্য চালনী অ্যালগরিদমে স্যুইচ করার বিবেচনা করার আগে এটি।
নেস

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

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

12

আমি বিশ্বাস করি যে বেশিরভাগ লোকেরা যে কারণে বলেছিলেন যে সুন্দর হাস্কেল কুইকোর্ট একটি "সত্য" কুইকোর্টের জায়গাটি ঠিক তা নয় - এটি স্পষ্টতই বলা যায় যে অপরিবর্তনীয় ডেটাটাইপগুলি ব্যবহার করার সময় এটি হতে পারে না। তবে এটি "তড়িঘড়ি" নয় বলেও আপত্তি রয়েছে: আংশিক ব্যয়বহুল ++ এর কারণেই এবং স্পেস লিক হওয়ার কারণেও - আপনি কম উপাদানগুলিতে পুনরাবৃত্তি কল করার সময় ইনপুট তালিকায় থাকুন এবং কিছু ক্ষেত্রে - উদাহরণস্বরূপ যখন তালিকা হ্রাস পাচ্ছে - এর ফলে চতুর্ভুজ স্থান ব্যবহারের ফলাফল। (আপনি বলতে পারেন যে এটিকে রৈখিক স্থানে চালিত করা অপরিবর্তনীয় ডেটা ব্যবহার করে আপনি "ইন-প্লেস" পেতে পারেন সবচেয়ে কাছাকাছি)) জমে থাকা প্যারামিটার, টিপলিং এবং ফিউশন উভয় সমস্যার ঝরঝরে সমাধান রয়েছে; রিচার্ড পাখির S7.6.1 দেখুন


4

এটি নিখুঁত কার্যকরী সেটিংসে উপাদানগুলিকে স্থান পরিবর্তন করার ধারণা নয়। পরিবর্তনীয় অ্যারে সহ এই থ্রেডের বিকল্প পদ্ধতিগুলি বিশুদ্ধতার আত্মাকে হারিয়েছে।

দ্রুত বাছাইয়ের প্রাথমিক সংস্করণ (যা সর্বাধিক উদ্বেগজনক সংস্করণ) অনুকূলকরণের জন্য কমপক্ষে দুটি পদক্ষেপ রয়েছে।

  1. সংশ্লেষকারীদের দ্বারা সংঘবদ্ধকরণ (++) অনুকূল করা, যা লিনিয়ার অপারেশন:

    qsort xs = qsort' xs []
    
    qsort' [] r = r
    qsort' [x] r = x:r
    qsort' (x:xs) r = qpart xs [] [] r where
        qpart [] as bs r = qsort' as (x:qsort' bs r)
        qpart (x':xs') as bs r | x' <= x = qpart xs' (x':as) bs r
                               | x' >  x = qpart xs' as (x':bs) r
  2. ডুপ্লিকেট উপাদানগুলি হ্যান্ডেল করার জন্য, টার্নারি দ্রুত সাজানোর (বেন্টলি এবং সেজউইক দ্বারা উল্লিখিত 3-পার্টির বিভাজন) অনুকূলিতকরণ করুন:

    tsort :: (Ord a) => [a] -> [a]
    tsort [] = []
    tsort (x:xs) = tsort [a | a<-xs, a<x] ++ x:[b | b<-xs, b==x] ++ tsort [c | c<-xs, c>x]
  3. 2 এবং 3 একত্রিত করুন, রিচার্ড বার্ডের বইটি দেখুন:

    psort xs = concat $ pass xs []
    
    pass [] xss = xss
    pass (x:xs) xss = step xs [] [x] [] xss where
        step [] as bs cs xss = pass as (bs:pass cs xss)
        step (x':xs') as bs cs xss | x' <  x = step xs' (x':as) bs cs xss
                                   | x' == x = step xs' as (x':bs) cs xss
                                   | x' >  x = step xs' as bs (x':cs) xss

অথবা বিকল্পভাবে যদি সদৃশ উপাদানগুলি সংখ্যাগরিষ্ঠ না হয়:

    tqsort xs = tqsort' xs []

    tqsort' []     r = r
    tqsort' (x:xs) r = qpart xs [] [x] [] r where
        qpart [] as bs cs r = tqsort' as (bs ++ tqsort' cs r)
        qpart (x':xs') as bs cs r | x' <  x = qpart xs' (x':as) bs cs r
                                  | x' == x = qpart xs' as (x':bs) cs r
                                  | x' >  x = qpart xs' as bs (x':cs) r

দুর্ভাগ্যক্রমে, তিনটি মধ্যমিকে একই প্রভাব দিয়ে প্রয়োগ করা যায় না, উদাহরণস্বরূপ:

    qsort [] = []
    qsort [x] = [x]
    qsort [x, y] = [min x y, max x y]
    qsort (x:y:z:rest) = qsort (filter (< m) (s:rest)) ++ [m] ++ qsort (filter (>= m) (l:rest)) where
        xs = [x, y, z]
        [s, m, l] = [minimum xs, median xs, maximum xs] 

কারণ এটি নিম্নলিখিত 4 টি ক্ষেত্রে এখনও খারাপ কাজ করে:

  1. [১, ২, ৩, ৪, ...., এন]

  2. [এন, এন -১, এন -২, ..., ১]

  3. [মি -1, এম -2, ... 3, 2, 1, এম + 1, এম + 2, ..., এন]

  4. [এন, 1, এন -1, 2, ...]

এই চারটি কেসই অপরিহার্য মিডিয়েন অফ-থ্রি পদ্ধতির দ্বারা পরিচালনা করা হয়েছে।

প্রকৃতপক্ষে, একটি সম্পূর্ণরূপে কার্যকরী সেটিংয়ের জন্য সর্বাধিক উপযুক্ত বাছাই করা অ্যালগরিদমটি এখনও মার্জ-সাজানো, তবে দ্রুত সাজানোর নয়।

বিস্তারিত জানার জন্য, দয়া করে এখানে আমার চলমান লেখাটি দেখুন: https://sites.google.com/site/algoxy/dcsort


আপনি মিস করেছেন এমন আরও একটি অপ্টিমাইজেশন রয়েছে: সাব-তালিকা উত্পাদন করতে 2 ফিল্টারের পরিবর্তে পার্টিশনটি ব্যবহার করুন (বা 3 টি উপ-তালিকা উত্পাদন করতে অনুরূপ অভ্যন্তরীণ ফাংশনে ফোল্ডার)।
জেরেমি তালিকা

3

সত্যিকারের কোকোস্টোর্ট কী এবং কোনটি সে সম্পর্কে কোনও স্পষ্ট সংজ্ঞা নেই।

তারা এটিকে সত্যিকারের চিকুইসোর্ট নয়, কারণ এটি স্থানে স্থানে নয়:

সি-তে সত্যিকারের কুইকোর্টটি একই জায়গায় orts


-1

কারণ তালিকা থেকে প্রথম উপাদানটি নেওয়া খুব খারাপ রানটাইমের ফলাফল in 3 এর মধ্যকটি ব্যবহার করুন: প্রথম, মধ্যম, শেষ।


2
তালিকাটি এলোমেলো হলে প্রথম উপাদানটি নেওয়া ঠিক আছে।
কিথ থমসন

2
তবে বাছাই করা বা প্রায় বাছাই করা তালিকা সাধারণভাবে সাজানো সাধারণ।
জোশুয়া

7
তবে কিসোর্ট আইএস O(n^2)
টমাস এডিং

8
qsort হ'ল গড় n লগ এন, সবচেয়ে খারাপ এন ^ 2।
জোশুয়া

3
প্রযুক্তিগতভাবে, ইনপুটটি ইতিমধ্যে বাছাই করা বা প্রায় বাছাই করা না হলে এলোমেলো মান বাছাইয়ের চেয়ে খারাপ কিছু নয়। খারাপ পিভটগুলি হ'ল পিভট যা মধ্যমা থেকে দূরে থাকে; যদি সর্বনিম্ন বা সর্বাধিকের কাছাকাছি হয় তবে প্রথম উপাদানটি কেবলমাত্র একটি খারাপ পাইভট।
প্লাটিনাম আউজুর

-1

কাউকে হাস্কেলতে কুইকোর্ট লিখতে বলুন, এবং আপনি মূলত একই প্রোগ্রামটি পাবেন - এটি অবশ্যই কুইকোর্ট। এখানে কিছু সুবিধা এবং অসুবিধা রয়েছে:

প্রো: এটি স্থিতিশীল হয়ে "সত্য" কুইকোর্টে উন্নতি করে, অর্থাৎ এটি সমান উপাদানের মধ্যে ক্রম ক্রম সংরক্ষণ করে।

প্রো: এটি একটি ত্রি-মুখী বিভক্তিকে (<=>) সাধারণকরণ করা তুচ্ছ, যা ও (এন) বারের সাথে কিছু মূল্য সংঘটিত হওয়ার কারণে চতুর্ভুজ আচরণকে এড়িয়ে চলে।

প্রো: এটি পড়া সহজ - এমনকি যদি ফিল্টারটির সংজ্ঞাও অন্তর্ভুক্ত করতে হয় to

কন: এটি আরও মেমরি ব্যবহার করে।

কন: অন্য নমুনা ব্যবহার করে পিভট পছন্দকে সাধারণীকরণ করা ব্যয়বহুল, যা নির্দিষ্ট লো-এনট্রপি অর্ডারগুলিতে চতুর্ভুজীয় আচরণ এড়াতে পারে।

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