انجمن های گفتگوی جامعه کاربران لینوکس استان یزد
18 شهريور 1389,ساعت 13:17:21 *
خوش آمدید، مهمان - لطفا برای ثبت نام اینجا و یا برای ورود اینجا را کلیک کنید.
آیا هنوز ایمیل فعال سازی حساب کاربری برای ما ارسال نشده است؟

لطفا برای ورود نام کاربری و رمز عبورتان را وارد نمایید
اخبار: لطفا برای استفاده بهتر از انجمن، ثبت نام کنید!
 
   فهرست   راهنمايي جستجو تقویم ورود عضويت  
صفحه: [1]
  چاپ صفحه  
نويسنده موضوع: روش مرتب سازی shellsort  (دفعات بازدید: 517 بار)
امید پیله ور
کاربر فعال
***
آفلاین آفلاین

جنسيت : پسر
تعداد ارسال: 107

تشكر
-اهدا شده: 23
-دريافت شده: 16


لینوکس برای پر درآوردن و اوبونتو برای پرواز!!!


WWW
« : 11 شهريور 1387,ساعت 13:19:49 »

با نام خدا
سلام
چون دیدم اغلب برای روبوکاپ باید چند امتیاز sort شود تصمیم به آموزش دو روش sort گرفتم:
1.shellsort
2.quicksort
چون حجم مطلب زیاد است در اینجا shellsort را توضیح میدهم و quicksort را در پست بعدی ارائه میدهم.

این مرتب سازی جالب توسط شخص SHELL اختراع شد. فرض کنید می خواهیم یک رشته dafcbe را مرتب کنیم:
شروع:                  d                a                f                    c                         b                      e
1:                        c                a                e                   d                         b                      f 
2:                        c                a                b                   d                         e                      f
3:                        a                b                c                   d                         e                      f
در مرحله اول داده ها با فاصله 3 و در مرحله 2 با فاصله 2 و در مرحله 1 با فاصله 1 و در مرحله 4 با فاصله صفر مقایسه و مرتب سازی میشوند (منظور از فاصله 2 یعنی مثلا داده 1 با داده 3 (1+2=3)) اگر دقت کنید میبینید با این کار داده ها برای مرحله آخر که فاصله 1 است آماده میشوند. فاصله نیز با تقسیم مکرر داده ها بر دو حاصل میشود تا به صفر برسد(تقسیمها با int است) که در مثال مرحله 4 صفر شده است. مثلا با n=5 داده ابتدا فاصله 2 (n=n/2) بعد 1 (n=n/2) و بعد صفر انتخاب میشود.
حتما خوب توضیح ندادم اما حتما با مطالعه کد زیر متوجه میشوید ولی سوالات شما مکمل بحث خواهد بود
کد:
void shell(int *itemp,int count)
{
   const int ct=count;
   register int i, j, step, k=0, p;
   int dis[ct];
   char x;
   dis[0]=count/2;
   while(dis[k]>1){
      k++;
      dis[k]=dis[k-1]/2;
   }
   for(i=0 ; i<=k ; i++){
      step=dis[i];
      for(j=0 ; j<count ; j++){
         x=item[j];
         p=j-step;
         while( p>=0 && x < item[p] ){
            item[p+step]=item[p];
            p-=step;
         }
         item[p+step]=x;
      }
   }
}
توضیح:
item  همان آرایه ورودی است(شما میتوانید رشته ارسال کند compiler خودش با تبدیل انواع حل میکند ) و count طول آرایه ورودی است (برای رشته از تابع  strlen استفاده کنید). کاراکتر x نیز برای جابجایی در آرایه است و متغییرهای خط 4 چون گامهای حلقه و پر کاربردند برای بهبود سرعت register انتخاب شدند مخصوصا شرط  [x<item[p که از کارایی الگوریتم میکاهد.
هدف از انتخاب const ct این بود تا بتوانیم آرایه dis  را تعریف کنیم(به جای y در [y] آرایه نمی توان متغییر نهاد) متوانستیم از عملگر new استفاده کنبم.
محاسبه زمان:
در روشهای حبابی و درج با n داده, ناظر n2 جابجایی در آرایه  هستیم ولی در این روش شاهد n1.2 هستیم (این اعداد با محاسبه نه چندان زیاد محاسبه میشوند در مورد این مبحث در آینده بحث میکنیم ).

پس از سوالات شما و جا افتادن یحث به quicksort  می پردازیم.

در آینده به مبحث وقفه ها (interrupt)  که بسیار مهم است و از پیاده سازی آن کمتر کسی میداند می پردازیم که میتوانید با ++C از پرینتر و جابجا کردن هدر هارد به مکان دلخواه و reset هارد و تمام میانبرها با صفحه کلید و... استفاده کنید.


منبع : اولین انجمن تخصصی فاری زبان آموزش روبوکاپ - روش مرتب سازی shellsort
خارج شده است


لینوکس برای پر درآوردن و اوبونتو برای پرواز!!!


فایل های خود را رایگان به اشتراک همه در شبکه جهانی وب قرار دهید!!!
lord.t
مدیر انجمن ها
کاربر حرفه ای
*****
آفلاین آفلاین

جنسيت : پسر
تعداد ارسال: 407

تشكر
-اهدا شده: 249
-دريافت شده: 245



« پاسخ #1 : 13 شهريور 1387,ساعت 11:52:34 »

با سلام

روش جالبی است ... اگر اشتباه نکرده باشم از نظر روش کار تقریبا شبیه به همان روش quicksort و در قالب الگوریتمهای Divide & Conquer قرار میگیرد..
ابتدا آرایه را به دو نیم میکند و بزرگترها را در نیمه دوم و کوچکترها را در نیمه اول
و به همین طریق این کار را ادامه میدهد..

البته فکر میکنم اگر کد به این صورت باشد اندکی کاراتر باشد
کد:
for(j=0 ; j<count-step ; j++){
         x=item[j];
         p=j+step;
         while( p<count && x > item[p] ){
            item[p-step]=item[p];
            p+=step;
         }
         item[p-step]=x;
      }

یک سوال: میتوانید در مورد طریقه بدست آوردن پیچیدگی زمانی تعداد جابه جایی ها یک توضیح بدید... به نظر میاد در بدترین حالت همون nlogn است...

موفق باشید
خارج شده است
صفحه: [1]
  چاپ صفحه  
 
پرش به :  

Powered by SMF 1.1.11 | SMF © 2006, Simple Machines LLC | Developed by Aftab Javid Pars | Hosted by Dibagroup