فصل هفتم:
مقدمه ای بر پیچیدگی محاسباتی:
مسئله مرتب سازی
1- 7 پیچیدگی محاسباتی
- پیچیدگی محاسباتی عبارت از مطالعه تمام الگوهای امکن پذیر برای حل یک مسئله مفروض است.
- در تحلیل پیچیدگی محاسباتی کوشش می کنیم تا حد پایینی کارایی همه ی الگوریتم ها را برای یک مسئله مفروض به دست آوریم.
- تحلیل پیچیدگی محاسباتی را با مطالعه مسئله مرتب سازی معرفی می کنیم.
- این انتخاب دو دلیل دارد:
1- چند الگوریتم ابداع شده اند که که مسئله را حل می کنند.
2- مسئله مرتب سازی یکی از معدود مسائلی است که در بسط الگوریتم هایی با پیچیدگی زمانی نزدیک به حد پایینی برای آن موفق بوده ایم.
2-7 مرتب سازی درجی و مرتب سازی انتخابی
- الگوریتم مرتب سازی درجی الگوریتمی اس که مرتب سازی را با درج رکوردها در یک آرایه مرتب شده ی موجود مرتب سازی می کند.
الگوریتم 1-7: مرتب سازی درجی
void insertionsort ( int n , keytype S[ ] )
for ( i = 2 ; i <= n ; i ++) {
while ( j >0 && S [i] > x ) {
تحلیل پیچیدگی زمانی تعداد مقایسه های کلید ها درا لگوریتم مرتب سازی درجی در بدترین حالت
عمل اصلی : مقایسه S [ j] با x .
اندازه ورودی : n ، تعداد کلید هایی که باید مرتب شوند.
W (n) = n( n - 1) / 2
تحلیل پیچیدگی زمانی تعداد مقایسه های کلید ها درا لگوریتم مرتب سازی درجی
در حالت میانگین
عمل اصلی : مقایسه S [ j] با x .
اندازه ورودی : n ، تعداد کلید هایی که باید مرتب شوند.
A (n) = n² / 4
تحلیل استفاده از فضای اضافی برای الگوریتم 1-7 ( مرتب سازی درجی)
- تنها فضایی که با n افزایش می یابد، اندازه ی آرایه ورودیS است. پس ،این الگوریتم یک مرتب سازی درجا است و فضای اضافی به(1)θ تعلق دارد.
جدول 1- 7 : خلاصه تحلیل مرتب سازی تعویضی ، درجی و انتخابی
الگوریتم 2-7: مرتب سازی انتخابی
void selectionsort ( int n , keytype S [ ] )
for ( i = 1; i <= n-1 ; i ++ )
if ( S [j] < S [ smallest])
exchange S [i] and S [smsllest ] ;
قضیه 1-7
- هر الگوریتمی که n کلید متمایز را فقط از طریق مقایسه کلید ها انجام دهد و پس از هر بار مقایسه ، حد اکثر یک وارونگی را حذف کنید، باید در بدترین حالت حداقل
n( n- 1) /4 مقایسه روی کلید ها انجام دهد.
الگوریتم مرتب سازی تعویضی
void exchangesort ( int n , keytype S [ ] )
for ( i = 1 ; i <= n -1 ; i ++ )
exchange S [i] and S [j];
4-7 نگاهی دوباره به مرتب سازی ادغامی
- پیچیدگی زمانی تعداد مقایسه های کلید ها در مرتب سازی ادغامی در بدترین حالت، وقتی که n توانی از 2 است، به طور کلی به θ(n lg n) تعلق دارد:
W (n) = n lg n – ( n – 1 )
- پیچیدگی زمانی تعداد مقایسه های رکورد ها در مرتب سازی ادغامی در حالت معمول تقریبا به صورت زیر است:
T ( n) = 2n lg n
بهبود بخشیدن به مرتب سازی ادغامی
- می توانیم مرتب سازی ادغامی را به سه شیوه بهبود ببخشیم:
1- نسخه ای ازمرتب سازی ادغامی به روش برنامه نویسی پویا
2- نسخه پیوندی
3- الگوریتم ادغامی پیچیده تر
الگوریتم 3-7: مرتب سازی ادغامی 3 ( نسخه برنامه نویسی پویا)
void mergesort ( int n , keytype S [ ] )
index low , mid , high , size ;
for ( low = 1; low <= m -2 * size + 1 ;
high = minimun ( low + 2 * size – 1 , n );
merge3 ( low , mid , high , S );
الگوریتم 4-7 : مرتب سازی ادغامی 4 ( نسخه پیوندی)
void mergesort4(int low,indexhigh, index&mergedlist)
index mid , list 1 , list 2;
S [ mergedlist ].link = 0 ;
mid = Į (low + high ) / 2⌡;
mergesort4 ( low , mid , list1 );
mergesort4 ( mid + 1, high , list 2);
mergesort4 ( list1 , list 2, mergedlist );
void merge4(index list1,indexlist2,index& mergedlist)
if S [ list 1].key < S
[list 2 ] .key {
list1 = S
[list 2 ].link;
list 2 = S
[list 2 ] .link;
while ( list1 != 0 && list2 != 0 )
if S
[list 1].key < S
[list 2].key {
S [ lastsorted ].link = list 1 ;
list 1 = S [ list 1] .link;
S [ lastsorted ].link = list 2 ;
list 2 = S [ list 2] .link;
S [ lastsorted ].link = list 2 ;
S [ lastsorted ] .link = list 1 ;
تحلیل استفاده از فضای اضافی برای الگوریتم 4-7(مرتب سازی ادغامی 4)
- در هر حالت استفاده از فضای اضافی به(n)θ پیوند تعلق دارد.
- منظور از (n)θ پیونداین است که تعداد پیوند ها به (n)θ
تعلق دارد.
5-7 نگاهی دوباره به مرتب سازی سریع
void quicksort ( index low , index high )
partition ( low , high , pivotpoint ) ;
quicksort ( low , high , pivotpoint – 1);
quicksort (pivotpoint + 1 , high );
روش های بهبود بخشیدن به الگوریتم مرتب سازی سریع
- استفاده از فضای اضافی در مرتب سازی سریع را می توان به پنج شیوه کاهش داد:
1- در روال quicksort ، تعیین می کنیم کدام زیر آرایه کوچک تراست و همواره آن را در پشته قرار می دهیم و دیگری را نگه می داریم.
- در این نسخه استفاده از فضای اضافی در بد ترین حالت به (lg n)θ اندیس تعلق دارد.
2- نسخه ای از partition وجود دارد که تعداد انتساب های رکورد ها را به طرزی چشمگیر کاهش می دهد.
- برای این نسخه، پیچیدگی زمانی تعداد انتساب های انجام شده توسط مرتب سازی سریع در حالت میانگین عبارت است از:
A (n) = 0.69 ( n + 1 ) lg n
3- مقدار زیادی از اعمال pop و push بی مورد است. می توانیم با نوشتن quicksort به شیوه تکرار و دستکاری پشته در روال، ازعملیات بیهوده پرهیز کنیم، یعنی به جای استفاده از پشته و بازگشتی ،پشته را خودمان می سازیم.
4- الگوریتم های بازگشتی مثل مرتب سازی سریع را می توان با تعیین یک مقدار آستانه که در آن الگوریتم به جای تقسیم بیشتر نمونه ، یک الگوریتم تکراری را فراخوانی می کند ، بهبود بخشید.
5- انتخاب میانه S [low] ، S [ Į low + high )/2⌡ ،
S [high] برای نقطه ی محوری است.
6-7 مرتب سازی heap
- درخت دودویی کامل یک درخت دودویی است که واجد شرایط زیر باشد:
-همه ی گره های داخلی دو فرزند داشته باشند.
-همه ی برگ ها دا رای عمق d باشند.
- درخت دودویی اساسا کامل یک درخت دودویی است که:
- تا عمق (n – 1) یک درخت دودویی کامل باشد.
- گره هایی با عمقd تا حد امکان در طرف چپ واقع شوند.
Heap- یک درخت دودویی اساس کامل است به طوری که:
- مقادیر نگهداری شده در گره های آن از یک مجموعه مرتب باشند.
- مقادیر نگهداری شده درهر گره بزرگ تر یا مساوی مقادیر نگهداری شده در فرزندان آن باشد.
2-6-7 پیاده سازی مرتب سازی heap
ساختمان داده های heap
void siftdown ( heap& H , index i )
index parent, largerchild; keytype siftkey;
parent = i ; spotfound = false;
while (2* parent <= H.hepsize &&! spotfound) {
if ( 2 * parent < H.heapsize && H.S [ 2*parent]
largerchild = 2 * parent + 1;
largerchild = 2 * parent ;
if ( siftkey < H.S[largerchild ]) {
H.S [parent] = H.S[largerchild ];
H.heapsize = H.heapsize -1;
for ( i = n; i >= 1 ; i --)
for ( i = Į n/2⌡; i >= 1 ; i --)
الگوریتم 5-7: مرتب سازی heap
void heapsort ( int n , heap& H)
removekeys ( n, H , H.S );
7-7مقایسه مرتب سازی ادغامی، مرتب سازی سریع ومرتب سازی heap
- مرتب سازی سریع معمولا بر مرتب سازی heap ارجحیت دارد.
- مرتب سازی سریع معمولا بر مرتب سازی ادغامی ترجیح داده می شود.
1-8-1 درخت ها ی تصمیم گیری برای الگوهای مرتب سازی
- لم 1-7: متناظر با هر الگوریتم قطعی برای مرتب سازی n کلید متمایز، یک درخت تصمیم گیری دودویی ، معتبر و هرس شده با دقیقا n! برگ وجود دارد.
- لم 2-7: تعداد مقایسه های انجام شده توسط یک درخت تصمیم گیری در بدترین حالت برابر با عمق درخت است.
- لم 3-7: اگرm تعداد برگ ها در یک درخت دودویی و d
عمق آن باشد، داریم:
d ≥ ┌ lg m ┐
قضیه 2-7
- هر الگوریتم قطعی که n کلید متمایزرا فقط با مقایسه کلید ها مرتب سازی می کند، باید در بدترین حالت حد اقل
┌ lg ( n!) ┐ مقایسه کلید ها راانجام دهد.
- لم 4-7: به ازای هر عدد مثبت و صحیح n، داریم:
lg (n!) ≥ n lg n – 1.45 n
قضیه 3-7
- هر الگوریتم قطعی که n کلید متمایز را فقط با مقایسه ی کلید ها انجام می دهد باید در بدترین حالت حداقل ┌ n lg n – 1.45n┐ مقایسه کلید ها را انجام دهد.
3-8-7 حدود پایینی برای رفتار در حالت میانگین
- لم 5-7: متنا ظر با هر درخت تصمیم گیری دودویی معتبر هرس شده برای مرتب سازی n کلید متمایز، یک درخت -2 تصمیم گیری معتبر هرس شده وجود دارد که حد اقل به اندازه درخت اول کارایی دارد.
- لم 6-7: هر الگوریتم قطعی که n کلید متمایز را فقط با مقایسه کلید ها مرتب سازی می کند، حد اقل تعداد محاسبه کلید های که انجام می دهد به طور میانگین برابر است با:
mimEPL (n!) / n!
- لم 7-7: هر درخت دودویی-2 که دارای m برگ باشد و EPLآن برابر minEPL(m) باشد، باید همه ی برگ های آن در پایین ترین سطح باشند.
- لم 8-7: هر درخت -2 که دارای m برگ وEpl آن برابر
minEPL(m) باشد ، باید 2^d – m برگ در سطح d – 1 و 2m – 2 ^d برگ درسطح d داشته باد و برگ دیگری نداشته باشد، d عمق درخت است.
- لم 9-7: به ازای هر درخت -2 که m برگ و EPL آن برابرباminEPL(m) باشد، عمق d عبارت است از:
d = ┌ lg m ┐
- لم 10-7: به ازای همه ی مقادیر m ≥ 1 داریم :
mimEPL(M) ≥ m Į lg m⌡
قضیه 4-7
- هر الگوریتم قطعی که n کلید متمایزرا تنها با مقایسه کلیدها مرتب سازی کند، به طور میانگین باید حداقل این تعداد مقایسه ها را انجام دهد:
n lg n – 1.45n⌡Į
9-7 مرتب سازی از طریق توزیع (مرتب سازی مبنایی)
الگوریتم 6-7: مرتب سازی مبنایی
void radixsort ( node_pointer& mastrrlist;
for ( i = 1 ; i <= numdigits ; i ++) {
void distrebute ( index i )
for ( j = 0 ; j <= 9 ; j++)
j = value of ith digit (from the right)in p -> key;
link p to the end of list [j];
for ( j = 0 ; j <= 9 ; j++)
link the nodes in list [j] to the end of masterlist;
}
علاقه مندی ها (Bookmarks)