مرتب‌سازی رتبه‌ای

مرتب‌سازی رتبه‌ای  یا مرتب‌سازی سرشماری  یک الگوریتم مرتب‌سازی از مرتبه‌ی زمانی  است که در آن برای مشخص کردن جایگاه هر عدد در لیست مرتب شده، تعداد عناصر کوچک‌تر از آن شمرده می‌شود.

این الگوریتم با توجّه به این که ورودی در یک داده‌ساختار میانی ذخیره می‌شود، یک نوع مرتّب‌سازی توزیعی است.

 تحلیل 

بندانگشتی|محاسبه‌ی رتبه‌ی هر عنصر در مرتب‌سازی رتبه‌ای|400px

 روش کار 
برای به دست آوردن رتبه‌ی هر عنصر، کافی است تعداد اعداد کوچک‌تر از آن را بشماریم. شکل مقابل، نمونه‌ای از این کار را نشان می‌دهد.

 عملکرد 
مرتبه‌ی زمانی اجرای مرتب‌سازی رتبه‌ای در تمام حالت‌ها  است؛ زیرا مستقل از مرتب بودن یا نبودن آرایه‌ی ورودی، محاسبه‌ی رتبه‌ی تمام عنصرها لازم است. با این حال، می‌توان با پردازش موازی زمان اجرا را بهبود داد. با استفاده از  پردازنده، می‌توان زمان اجرا را به  رساند؛ در این حالت، هر پردازنده با اجرای یک حلقه، رتبه‌ی یک عنصر را محاسبه می‌کند. با وجود عملیاتی نبودن، می‌توان با استفاده از  پردازنده زمان اجرای الگوریتم را تا  هم کاهش داد.

 پیاده‌سازی 
 پیاده‌سازی ترتیبی 
قطعه کد زیر، پیاده‌سازی ترتیبی مرتب‌سازی رتبه‌ای را به زبان پایتون نشان می‌دهد. در این قطعه، آرایه‌ی نامرتب Input به صورت مرتب شده در آرایه‌ی Output ذخیره می‌شود.
for i in range(n):
    rank = 0 # Number of elements less than Input[i]
    for j in range(n):
        if Input[j] < Input[i]:
            rank += 1
    Output[rank] = Input[i] # Put Input[i] in output array based on its rank

اگر لیست اولیه شامل اعداد تکراری باشد، قطعه کد بالا درست کار نمی‌کند؛ اما می‌توان با اعمال تغییراتی، این مشکل را برطرف کرد. قطعه کد زیر، نسخه‌ی بهبود یافته‌ی مرتب‌سازی رتبه‌ای را به زبان پایتون نشان می‌دهد.

Output = [None] * n

for i in range(n):
    rank = 0 # Number of elements less than Input[i]
    for j in range(n):
        if Input[j] < Input[i]:
            rank += 1

    while Output[rank] is not None: # As long as an element has the same rank
        rank += 1

    Output[rank] = Input[i] # Put Input[i] in output array based on its rank

 پیاده‌سازی موازی 

بندانگشتی|روش‌های پیاده‌سازی موازی مرتب‌سازی رتبه‌ای|300px

از آن جا که محاسبه کردن رتبه‌ی هر عنصر مستقل از عناصر دیگر است، می‌توان مرتب‌سازی رتبه‌ای را به صورت موازی پیاده‌سازی کرد. از دیدگاه تئوری، با این کار می‌توان زمان اجرای این الگوریتم را تا  کاهش داد. برای پیاده‌سازی موازی روش‌های مختلفی وجود دارد. دو تا از این روش‌ها عبارت‌اند از:

الف) عناصر آرایه را طوری بین پردازنده‌ها تقسیم کنیم که هر پردازنده، رتبه‌ی تعدادی از عناصر را محاسبه کند.

ب) آرایه به چند بخش تقسیم کنیم و در اختیار هر پردازنده قرار دهیم. هر پردازنده رتبه‌ی تمام عناصر را در لیستی که در اختیار دارد محاسبه می‌کند (رتبه‌ی جزئی). رتبه‌ی نهایی حاصل جمع رتبه‌های جزئی است.

قطعه کد زیر، پیاده‌سازی موازی مرتب‌سازی رتبه‌ای در زبان سی شارپ را نشان می‌دهد.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ranksort
{
    class Ranksorter
    {
        private int[] unsorted_array,sorted_array;
        private int n;
        public int[] GetSortedList
        {
            get { return sorted_array; }
        }
        public Ranksorter(int[] unsorted,int num)
        {
            n = num;
            unsorted_array = new int[n];
            sorted_array = new int[n];
            Array.Copy(unsorted,unsorted_array,n);

        }
        public void Sort(int index)
        {
            int rank = 0;
            int inval = unsorted_array[index];
            //int j = index;
            for(int x=0;x<n;x++)
                if (
                     (unsorted_array[x] < inval) ||
                     ((unsorted_array[x] == inval) && x<index)
                   ) rank++;

            /*
            do
            {
                j = (j % (n-1))+1;

            } while (j==index);
             * */
            sorted_array[rank] = inval;
        }

        public void Print()
        {
            for (int i = 0; i < n; i++)
            {
                Console.Write(sorted_array[i].ToString() + " ");
            }
        }
        public void WriteTo(string path)
        {
            System.IO.StreamWriter wr = new System.IO.StreamWriter(path);
            for (int i = 0; i < n; i++)
            {
                wr.WriteLine(sorted_array[i].ToString());
            }
            wr.Dispose();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var sw = new System.Diagnostics.Stopwatch();

            Random rnd = new Random();
            int n = 90000;
            int[] A = new int[n];
            System.IO.StreamReader reader = new System.IO.StreamReader("input.in");
            for (int i = 0; i < n; i++) 
                A[i] = int.Parse(reader.ReadLine());
            reader.Dispose();
            Ranksorter rank_sorter = new Ranksorter(A,n);
            sw.Start();
            Parallel.For(0,n, (int k) => {rank_sorter.Sort(k); });
            sw.Stop();
            rank_sorter.WriteTo("result_sorted.txt");
            Console.WriteLine("\nElaspsed time : {0}" + sw.Elapsed.ToString());
            Console.WriteLine("\nArray size is {0}.",n);
            Console.ReadKey();

        }
    }
}

برای آسان‌تر شدن پردازش موازی، از یک آرایه‌ی واسط به نام آرایه‌ی رتبه‌ها  استفاده می‌شود که در جایگاه iاُم آن، رتبه‌ی iامین عنصر آرایه‌ی ورودی قرار می‌گیرد. اگر این آرایه را با R نشان دهیم
Output[R[i]] = Input[i]

 جستارهای وابسته 
 الگوریتم‌های مرتب‌سازی

 منابع 

 پیوند به بیرون 
 مرتب‌سازی رتبه‌ای به زبان سی
 مرتب‌سازی رتبه‌ای و مرتب‌سازی پایه‌ای 

رده:الگوریتم‌های مرتب‌سازی
رده:مرتب‌سازی‌های پایدار