بستن پنجره
فرادرس - مجموعه آموزش‌های ویدئویی  مهندسی کامپیوتر - طراحی الگوریتم - ساختمان داده
بستن پنجره     از آخرین نوشته‌ها

»    مسابقه‌ی برنامه‌نویسی CodeCup 2018

»    دوره‌ی طراحی و تحلیل الگوریتم دانشگاه استنفورد

»    مسئله‌ی انتخابات

مرتب‌سازی حبابی - الگوریتمستان
الگوریتمستان
8114.285.00
  »  

       

آشنایی با روش مرتب‌سازی حبابی و بحث در مورد عملکرد آن، با قطعه کد به زبان برنامه‌نویسی ++C

http://www.aachp.ir آنچه می‌خوانید ویراست جدید نوشته‌ای است که اولین بار با عنوان «مرتب سازی حبابی» شهریور ماه 1385 از طریق وبگاه برنامه‌نویسی و طراحی الگوریتم (عنوان و طرح پیشین وبگاه الگوریتمستان) منتشر شده بود.


یکی از روش‌های مرتب‌سازی، روش مرتب‌سازی حبابی (Bubble Sort) است که به آن روش تعویض استاندارد (Standard Exchange) نیز می‌گویند. این روش شامل چند مرحله است که در هر مرحله یک عنصر از لیست به طور قطع در محل مناسب خود قرار می‌گیرد.

    لیست زیر را در نظر بگیرید که می‌خواهیم به صورت صعودی (از کوچک به بزرگ) مرتب کنیم:

      

4  3  8  1  6  2

      

    عنصر اول را با دومی مقایسه کرده و در صورتی که اولی بزرگتر باشد، جای آنها را تعویض می‌کنیم:

      

1 - 1)    4  3  8  1  6  2        3  4  8  1  6  2

      

    همین کار را با عناصر دوم و سوم انجام می‌دهیم:

      

1 - 2)    3  4  8  1  6  2        3  4  8  1  6  2

      

    و همینطور عناصر سوم و چهارم:

      

1 - 3)    3  4  8  1  6  2        3  4  1  8  6  2

      

    و الی آخر:

      

1 - 4)    3  4  1  8  6  2        3  4  1  6  8  2

1 - 5)    3  4  1  6  8  2    →    3  4  1  6  2  8

      

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

    در مرحله‌ی بعد، مجددا از ابتدا شروع کرده و تا انتها ادامه می‌دهیم. اما با توجه به این که به طور قطع عنصر nام در جای اصلی خود قرار دارد، تا عنصر (n - 1)ام پیش می‌رویم. در پایان این مرحله، بزرگترین عدد در لیست نامرتب باقیمانده، به انتهای آن منتقل می‌شود که دومین عدد از نظر بزرگی در کل لیست است:

      

2 - 1)    3  4  1  6  2  8    →    3  4  1  6  2  8

2 - 2)    3  4  1  6  2  8    →    3  1  4  6  2  8

2 - 3)    3  1  4  6  2  8    →    3  1  4  6  2  8

2 - 4)    3  1  4  6  2  8    →    3  1  4  2  6  8

      

    در هر مرحله، طول بازه‌ای که مرتب‌سازی روی آن انجام می‌گیرد، یک واحد کم شده و در نتیجه تعداد گام‌ها نیز یک گام کمتر می‌شود:

      

3 - 1)    3  1  4  2  6  8    →    1  3  4  2  6  8

3 - 2)    1  3  4  2  6  8    →    1  3  4  2  6  8

3 - 3)    1  3  4  2  6  8    →    1  3  2  4  6  8

  

4 - 1)    1  3  2  4  6  8    →    1  3  2  4  6  8

4 - 2)    1  3  2  4  6  8    →    1  2  3  4  6  8

  

5 - 1)    1  2  3  4  6  8    →    1  2  3  4  6  8

    

    

  [بازگشت به فهرست]

      

    در پایان این مراحل، لیست مرتب شده است.

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

      

کد پیاده‌سازی مرتب‌سازی حبابی

  [بازگشت به فهرست]

این الگوریتم را به زبان برنامه‌نویسی ++C - برای آرایه‌ای از اعداد صحیح - می‌توان به صورت زیر پیاده‌سازی کرد:

      

void bubble_sort_1(int arr[], int n){
  int i, j, t;
  for(i = n - 2 ; i >= 0 ; i--)
    for(j = 0 ; j <= i ; j++)
      if(arr[j] > arr[j + 1]){
        t = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = t;
      }
10 }

      

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

      

پیچیده‌گی زمانی مرتب‌سازی حبابی

  [بازگشت به فهرست]

فرض کنیم لیستی با n عنصر با روش مرتب‌سازی حبابی مرتب می‌شوند. عمل اصلی روش‌های مرتب‌سازی مبتنی بر مقایسه، مقایسه‌ها هستند. در مرحله‌ی اول، n - 1 مقایسه صورت می‌گیرد، تا بزرگترین عنصر به انتهای لیست منتقل شود. در مرحله‌ی دوم، n - 2 مقایسه و به همین ترتیب، در مرحله‌ی iام (i < n) تعداد n - i مقایسه صورت می‌گیرد. این تعداد را می‌توان از کد برنامه‌نویسی ذکر شده‌ی فوق هم استخراج کرد. پس تعداد کل مقایسه‌ها برای مرتب کردن n عنصر برابر است با:

      

\[ T(n) = (n - 1) + (n - 2) + (n - 3) + \cdots + 2 + 1 = \frac{ n (n - 1)}{ 2 } \]

      

    چنین عبارتی از مرتبه‌ی $\theta(n^2)$ است.

      

بهینه کردن الگوریتم مرتب‌سازی حبابی

  [بازگشت به فهرست]

قطعه کد فوق برای تمامی حالات چینش عناصر لیست به یک ترتیب عمل می‌کند. یعنی حتی اگر عناصر از قبل مرتب باشند، تمامی مقایسه‌ها - بدون جابجا شدن عنصری - انجام می‌شود. قطعه کد فوق در بهترین حالت، بدترین حالت و حالت متوسط از مرتبه‌ی $\theta(n^2)$ خواهد بود.

    برای بهینه‌تر شدن الگوریتم، کد را به صورت زیر تغییر می‌دهیم:

      

void bubble_sort_2(int arr[], int n){
  int i, j, t, c;
  for(i = n - 2 ; i >= 0 ; i--){
    c = 0;
    for(j = 0 ; j <= i ; j++)
      if(arr[j] > arr[j + 1]){
        t = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = t;
10         c++;
11       }
12     if(c == 0)
13       break;
14   }
15 }

      

    مقدار متغیر c قبل از شروع هر مرحله صفر شده و با هر جابجایی یک واحد به آن اضافه می‌شود. در پایان هر مرحله، این متغیر تعداد جابجایی‌های عناصر در آن مرحله را نشان می‌دهد. بنابراین، اگر مقدار آن در پایان مرحله صفر باشد، یعنی هیچگونه جابجایی در لیست صورت نگرفته و می‌توان نتیجه گرفت لیست مرتب است (چرا؟).

    چنین کدی مرتبه‌ی زمانی اجرای الگوریتم را در بهترین حالت به $\theta(n)$ تقلیل می‌دهد. چرا که اگر لیست از همان ابتدا مرتب باشد، با تمام شدن اولین مرحله (با n - 1 مقایسه) و بررسی مقدار متغیر c، مرتب بودن لیست مشخص شده و ادامه روند مرتب‌سازی متوقف می‌شود.

      

ویژگی‌های مرتب‌سازی حبابی

  [بازگشت به فهرست]

1- همانگونه که بحث شد، پیچیده‌گی زمانی اجرای این الگوریتم در بدترین حالت و حالت متوسط از مرتبه‌ی $\theta(n^2)$ است. پیچیده‌گی زمانی بهترین حالت، با تابع bubble_sort_1 از مرتبه‌ی $\theta(n^2)$ و با تابع bubble_sort_2 از مرتبه‌ی $\theta(n)$ است.

    2- مرتب‌سازی حبابی یک روش مرتب‌سازی درجا است. یعنی نیاز به فضای کمکی نداشته و با جابجا کردن عناصر در داخل خود لیست، آنها را مرتب می‌کند.

    3- مرتب‌سازی حبابی - با پیاده‌سازی به یکی از روش‌های فوق - یک روش مرتب‌سازی پایدار است. یعنی در حین مرتب‌سازی ترتیب عناصری که مقدار یکسانی دارند تغییر نمی‌کند. اگر در قطعه کدهای فوق، در مقایسه‌ی عناصر آرایه به جای < از =< استفاده می‌کردیم، مرتب‌سازی ناپایدار می‌شد. چرا که عناصری با مقادیر یکسان را نیز جابجا کرده و ترتیب آنها را به هم می‌زد.


نوشته‌های مرتبط
        ویدئوهای آموزشی دوره‌ی Algorithms: Design and Analysis دانشگاه استنفورد با زیرنویس انگلیسی
        آشنایی با روش مرتب‌سازی سریع، همراه با قطعه کدهای نمونه به زبان برنامه‌نویسی ++C
        آشنایی با روش مرتب‌سازی ادغامی با قطعه کدهایی به زبان برنامه‌نویسی ++C
        آشنایی با روش مرتب‌سازی درجی، همراه با قطعه کد به زبان برنامه‌نویسی ++C
        آشنایی با روش مرتب‌سازی هرمی (Heap Sort)
        آشنایی با روش مرتب‌سازی انتخابی،همراه با قطعه کد به زبان برنامه‌نویسی ++C
پیوند کوتاه صفحه دسته‌بندی
امتیاز نوشته
  • 1
  • 2
  • 3
  • 4
  • 5
ارسال پیام

نام: *  

پست الکترونیک:

وبگاه:

متن پیام: *

right 01 02 03 04 05 06 07 08 09 10 11 12 13 14 left

 


» مریم

یکشنبه، ۳۱ اردیبهشت ماه ۱۳۹۶، ساعت ۱۷:۲۲
سلام .برنامه ای که دریافت نام 5دانشجو و سه درس آنها از ورودی چاپ نام و معدل هر دانشجو ؟؟لطفا زود جواب بدین

» امین

شنبه، ۳۰ اردیبهشت ماه ۱۳۹۶، ساعت ۱۴:۴۹
مرسی

» بافهم

چهارشنبه، ۲۳ فروردین ماه ۱۳۹۶، ساعت ۰۸:۳۳
خیلی پرنده و نافهم بود09090909
بی فهم090909090909

» popo

جمعه، ۷ خرداد ماه ۱۳۹۵، ساعت ۱۱:۲۴
سلام
میگم اگر بخواییم با سرچ باینری یکی از اطلاعات ارایه پیدا کنیم چجوری میشه؟

» پارسا

جمعه، ۱۸ اردیبهشت ماه ۱۳۹۴، ساعت ۱۳:۰۳
سلام ممنون از توضیحات خوبتون .من چند تا سوال درباره این برنامه داشتم ممنون میشم اگه جواب بدین
شما تو حلقه ی for از n - 2 استفاده کردین چرا این دستور رادر  i-- اعمال نکردین؟مثلا چرا ننوشتین 2- i=i
و اگه بخوایم این برنامه رو برای ارایه ی 20عنصری انجام بدیم همین ساختار رو حفظ میکنه ؟


شنبه، ۱۹ اردیبهشت ماه ۱۳۹۴، ساعت ۱۲:۱۹
مسعود:
بر اساس ساختار حلقه‌ی تکرار for، در زمان ورود به حلقه تنها مقداردهی اولیه (یعنی n - 2) و شرط تکرار حلقه (یعنی  0 >= i) اجرا می‌شه و بخش --i نقشی نداره. در تکرارهای بعدی هم اگه i = i - 2 باشه عملکرد الگوریتم به هم می‌خوره. چون هر بار دو واحد از i کم می‌شه که مورد نظر ما نیست.
برای مطالعه‌ی توضیحات بیشتر راجع به حلقه‌های تکرار این لینک رو ببینید:
http://www.algorithmha.ir/category-برنامه-نویسی-سی-پلاس-پلاس/post-حلقه-های-تکرار-در-سی-پلاس-پلاس/

» یاسمین

جمعه، ۲۱ فروردین ماه ۱۳۹۴، ساعت ۲۱:۵۰
سلام .مرتبه ی زمانی یک ماتریس n*nکه به صورت صعودی مرتب شده رو میخوام .لطفا امشب جواب بدید فردا باید تحویل استاد بدم.

» آرمین

پنجشنبه، ۱۸ دی ماه ۱۳۹۳، ساعت ۱۲:۳۳
الان ک فک میکنم میبینم n-2 درسته 10

» آرمین

پنجشنبه، ۱۸ دی ماه ۱۳۹۳، ساعت ۱۲:۱۸
for اول باید از n-1 شروع شه!!!

» ali zamani

یکشنبه، ۱۶ آذر ماه ۱۳۹۳، ساعت ۲۳:۵۸
برنامه عالیه ولی یه مشکلی داره
تو حلفه :
   (-- for( i = n - 2 ; i >= 0 ; i
باید بشه
(-- for( i = n - 1 ; i >= 0 ; i
لطفا تصحیح کنید


دوشنبه، ۱۷ آذر ماه ۱۳۹۳، ساعت ۲۳:۲۶
مسعود:
ممنون از توجهتون. اما اگه دقت کنید، مقدار j از 0 تا i تغییر می‌کنه و هر مرحله عنصر j با j+1 مقایسه می‌شه. پس j+1 باید کمتر یا مساوی n - 1 باشه که نتیجه می‌ده i می‌تونه حداکثر n - 2 بشه.
برای i = n-1 مقایسه‌ی [a[n-1] > a[n در آخرین تکرار اتفاق می‌افته که مجاز نیست. چون عناصر از اندیس 0 تا n - 1 قرار دارن.

» محمدحیدری

شنبه، ۱۵ آذر ماه ۱۳۹۳، ساعت ۲۱:۱۶
خیلی ممنون از اینکه کامل و جامع توضیح داد 01

»  sepideh bandari

یکشنبه، ۲۵ آبان ماه ۱۳۹۳، ساعت ۱۸:۱۰
06060606060606


عالی بود مسی

» محمد حسین از شهرستان جیرفت

سه‌شنبه، ۱۳ آبان ماه ۱۳۹۳، ساعت ۱۴:۰۹
سلام .این برنامه تا حدودی درسته یعنی اگه دو مقدار یکسان در هر یک از خونه های ارایه وجود داشته باشن جاشون تغییری نمیکنه و ارایه مرتب نمیشه میتوان برنامه رو اینجوری اصلاح کرد:
   for(j=s-1;j>=1;j--)                              
    for(i=1;i<=j;i++)
      if(a[i]>a[i+1])
      {
        jabeja=a[i];
        a[i]=a[i+1];
        a[i+1]=jabeja;
       }
متغیر ها فرقی نمیکنه که چی باشن من اینجوری تعریفشون کردم
نکته:(s-2)برنامه قبل شده (s-1)



سه‌شنبه، ۱۳ آبان ماه ۱۳۹۳، ساعت ۲۳:۳۹
مسعود:
اگه مقدار یکسان داشته باشن مهم نیست جابجا شدن. همونطور که در متن هم اشاره شده، در این حالت الگوریتم ما پایدار هست و ترتیب عناصر با مقدار یکسان رو تغییر نمی‌ده.
این کد که شما ارسال کردید اگه j تا s-1 بره (که s رو تعداد عناصر آرایه در نظر می‌گیریم)[a[i+1 می‌تونه تا [a[s پیش بره، که این عنصر جزو عناصر مورد نظر ما نیست. در کل چنین تغییری تاثیری در پایداری یا ناپایداری الگوریتم مرتب‌سازی نداره.

» ماندانا

جمعه، ۲۲ فروردین ماه ۱۳۹۳، ساعت ۱۲:۴۱
سلام.من یه سوال برنامه نویسی c++دارم.کسی هست بلد باشه؟
دیوونه شدم از دستش
07

» مهسا

سه‌شنبه، ۱۹ فروردین ماه ۱۳۹۳، ساعت ۱۳:۵۶
خوب بود و البته خلاصه و مفید .ممنون01

» zainab

جمعه، ۲۲ آذر ماه ۱۳۹۲، ساعت ۱۸:۴۶
عالی بود very much
جای مطالب بیشتر خیلی  خیلی  خالی

» asma

جمعه، ۱۹ آبان ماه ۱۳۹۱، ساعت ۱۴:۱۸
س . کمک. یک ماتریس10*10که از روش مرتب سازی ادغامی وحبابی استفاده کند برام میل کنید خیلی مهمه


جمعه، ۱۹ آبان ماه ۱۳۹۱، ساعت ۱۵:۰۶
مسعود:
اسما خانم
شما دو بار درخواست برنامه آماده با ذکر آدرس ایمیل و درخواست برای ارسال به ایمیل کردید. بدون اینکه یکبار تذکرات بخش قرمز رنگ بالای قسمت ارسال پیام رو بخونید یا بهشون اهمیت بدید.
اینجا برنامه‌ی آماده برای کسی نوشته و ارسال نمی‌شه. اسباب این کار با ارتباط ایمیلی هم برقرار نمی‌شه.
موفق باشید.

» jetboy

پنجشنبه، ۱۸ آبان ماه ۱۳۹۱، ساعت ۱۸:۴۴
سلام :
خیلی عالی بود حالا شنبه می برم سرکلاس به استاد نشون می‌دم حالشو می‌بره
دستتــــــــــــــــــــــــــــــــــون درد نکنــــــــــــــــــــــــــــــــــــــــــــــــه
121212121208080606

» محسن

چهارشنبه، ۲۴ خرداد ماه ۱۳۹۱، ساعت ۱۰:۴۹
عالی بود. 3 نمره کمکم کردید.مرسی

» بنده ی خدا

شنبه، ۱۳ اسفند ماه ۱۳۹۰، ساعت ۱۷:۳۲
با تشکر بسیار.
فقط ان منهای یک باید باشه

» haji

یکشنبه، ۳۰ بهمن ماه ۱۳۹۰، ساعت ۰۸:۴۴
متـــــــــــــــــــــــــــــــشکرم06

» أأ

شنبه، ۲۴ دی ماه ۱۳۹۰، ساعت ۲۰:۵۰
010101

» hasty``

دوشنبه، ۱۲ دی ماه ۱۳۹۰، ساعت ۱۶:۵۸
04 kheili khob bood merc

» ارزو

سه‌شنبه، ۲۶ مهر ماه ۱۳۹۰، ساعت ۱۲:۴۴
سلام خسته نباشید
عالـــــــــــــــــــــــــــــــــــــــــــــــــی بود0606060606060606060606060606060606

» saeid

جمعه، ۱۶ اردیبهشت ماه ۱۳۹۰، ساعت ۱۳:۰۸
مطالب بیشتری در مورد مرتب سازی ها در سایت قرار دهید
با تشکر از زحمات گرانقدرتان.