Golden man
03-12-2008, 09:51 AM
تحسين خوارزمية الفرز بالإقحام
السلام عليكم
يعتمد هذا التحسين على البحث الثنائي لإيجاد المكان المناسب لإقحام العنصر , و هاهي توابع البحث و الفرز بعد التعديل.
int BinarySearch(int Elem,int Low,int High)
{
int Mid;
while(Low < High)
{
Mid = (Low+High)/2;
if(InitArr[Mid] == Elem)
return Mid + 1;
else if(InitArr[Mid] > Elem)
High = Mid - 1;
else if(InitArr[Mid] < Elem)
Low = Mid + 1;
}
if(Elem > InitArr[High])
High++;
return High;
}
void NewInsertionSort()
{
int key=0;
for(int j=1; j<Size; j++)
{
key = InitArr[j];
int i = BinarySearch(key,0,j);
for(int k=j-1; k>=i; k--)
InitArr[k+1] = InitArr[k];
InitArr[i] = key;
}
}
}
و من يريد البرنامج كاملا فهو على الرابط التالي:
http://www.100hla.com/up/uploads/9515e7cf59.rar
بانتظار الأسئلة و الاستفسارات...
Golden man
03-13-2008, 12:15 PM
السلام عليكم
يقوم على أساس تقسيم المصفوفة إلى مصفوفتين جزئيتين حيث يكون عناصر الأولى أصغر من كافة عناصر الثانية
و يعاد تطبيق العملية من أجل كل المصفوفتين الجزئيتين
ولتحيق ذلك نختار عنصر نعتبره المحور pivote حيث تحقق المتراجحة على جوانب هذا العنصر.
هذا مثال على آلية الفرز السريع:
405
406
407
يقسم الفرز السريع إلى تابعين , تابع لاستدعاءات الفرز السريع العودية و تابع آخر لإيجاد مكان الـ pivote و ترتيب العناصر وفقه.
التوابع هي :
void QuickSort(int x[], int low, int high)
{
if (low < high)
{
int p = Pivote(x, low, high);
QuickSort(x, low, p-1);
QuickSort(x, p+1, high);
}
}
int Pivote(int x[], int p, int high)
{
int L = p+1;
int R = high;
while ( L <= R)
{
for (; x[R] > x[p]; R--);
for (; x[L]<= x[p]; L++);
if ( L < R)
{
swap(x[L], x[R]);
R--;
L++;
}
}
swap(x[p], x[R]);
return R;
}
و هناك خوارزمية أخرى لإيجاد الـ pivote و هي التالية :
408
و يكون تابع إيجاد الـ pivote الجديد هو :
int pivote(int *A,int p,int q)
{
int x = A[p];
int i = p;
for(int j=p+1; j<=q; j++)
if(A[j] <= x)
{
i++;
A[i] = A[i] + A[j] - (A[j] = A[i]);
}
A[p] = A[p] + A[i] - (A[i] = A[p]);
return i;
}
و لكن هناك مشكلة في الطريقتين السابقتين و هي أن عدد عناصر المصفوفة التي يمكن فرزها محدود بسعة المكدس بشكل مؤثر جدا مما يعيق عملية اختبار هذه الخوارزمية على سعات كبيرة .
لذا فقد أعطاني الأستاذ خوارزمية مشابها للتي أخذناها في المحاضرة و لكن مع بعض التعديلات كدمج تابع إيجاد الـ pivote مع تابع الفرز ....
و قد لاحظت سرعة رهيبة في هذا التابع لفرز مصفوفات ضخمة جدا حيث أنه أخذ لفرز مصفوفة مكونة من 10000000 زمن 3,5 ثانية تقريبا.
و هذا هو التابع:
void BestQuickSort(int *A,int iLo,int iHi)
{
int Lo, Hi, Mid;
Lo = iLo;
Hi = iHi;
Mid = A[(Lo + Hi) / 2];
while( Lo <= Hi)
{
while (A[Lo] < Mid) Lo++;
while (A[Hi] > Mid) Hi--;
if (Lo <= Hi)
{
int temp = A[Lo];
A[Lo] = A[Hi];
A[Hi] = temp;
Lo++;
Hi--;
}
}
if (Hi > iLo) BestQuickSort(A, iLo, Hi);
if (Lo < iHi) BestQuickSort(A, Lo, iHi);
}
و لكن أرجو منكم اختباره و تجريبه لأني إلى الآن لم أقتنع بهذا الفرق الكبير بالسرعة و أخشى أن يكون هناك خطأ ما لا أراه.
و هنا تجدون برنامج اختبار الفرز السريع كاملا :
http://www.100hla.com/up/uploads/d256c6931a.rar
أرجو ممن لديه أسئلة أو استفسارات أن لا يؤجلها إلى الامتحان .
وشوشني
03-13-2008, 03:07 PM
شكرا جدا يا غالي و الله انك تستاهل كل خير و ان شالله يكون هالجهد بميزان اعمالك
فراشَةٌ هامَتْ بضوءِ شمعةٍ
فحلّقتْ تُغازِلُ الضِّرام.
قالت لها الا نسام :
قبلَكِ كم هائمةٍ .. أودى بِها الهُيام !
خُذي يدي و ابتعدي
لم تَسمعِ الكلامْ
ظلّتْ تدورُ
تحَطّمتْ
ثُمَّ هَوَتْ
وحَشْر جَ الحُطامْ :
أموتُ في النورِ
ولا
أعيشُ في الظلامْ
*Islam_Rose*
03-15-2008, 11:45 AM
بسم الله الرحمن الرحيم
السلام عليكم
وبعد
يعطيك الصحة و العافية و السعادة و التفوق في حياتك العلمية و العملية
جزاك الله كل الخير أخي في الله
و السلام عليكم
*Islam_Rose*
03-15-2008, 12:28 PM
بسم الله الرحمن الرحيم
السلام عليكم
وبعد
يعطيك الصحة و العافية و السعادة و التفوق في حياتك العلمية و العملية
جزاك الله كل الخير أخي في الله
وهذه الكودات هي لجميع أنواع الفرز
1- الفرز الفقاعي
#include<iostream.h>
#include<windows.h>
void bubbleSort(int numbers[], int array_size)
{
int i, j, temp;
for (i = (array_size - 1); i >= 0; i--)
{
for (j = 1; j <= i; j++)
{
if (numbers[j-1] > numbers[j])
{
temp = numbers[j-1];
numbers[j-1] = numbers[j];
numbers[j] = temp;
}
}
}
}
void main()
{
const int size=10;
int Array;
for(int i=0;i<size;i++)
Array[i]=rand();
srand(Array[i]);
int x1=GetTickCount();
bubbleSort(Array,size);
for(i=0;i<size;i++)
cout<<Array[i]<<endl;
int x2=GetTickCount();
cout<<"the result:"<<x2-x1<<endl;
}
2- الفرز بالكومة
#include<iostream.h>
#include<windows.h>
void siftDown(int numbers[], int root, int bottom)
{
int done, maxChild, temp;
done = 0;
while ((root*2 <= bottom) && (!done))
{
if (root*2 == bottom)
maxChild = root * 2;
else if (numbers[root * 2] > numbers[root * 2 + 1])
maxChild = root * 2;
else
maxChild = root * 2 + 1;
if (numbers[root] < numbers[maxChild])
{
temp = numbers[root];
numbers[root] = numbers[maxChild];
numbers[maxChild] = temp;
root = maxChild;
}
else
done = 1;
}
}
void heapSort(int numbers[], int array_size)
{
int i, temp;
for (i = (array_size / 2)-1; i >= 0; i--)
siftDown(numbers, i, array_size);
for (i = array_size-1; i >= 1; i--)
{
temp = numbers[0];
numbers[0] = numbers[i];
numbers[i] = temp;
siftDown(numbers, 0, i-1);
}
}
void main()
{
const int size=10;
int Array[size];
for(int i=0;i<size;i++)
Array[i]=rand();
int x1=GetTickCount();
heapSort(Array,size);
int x2=GetTickCount();
for(i=0;i<size;i++)
cout<<Array[i]<<endl;
cout<<"the result is:"<<x2-x1;
}
3-الفرز بالإقحام
#include<iostream.h>
#include<windows.h>
void insertionSort(int numbers[], int array_size)
{
int i, j, index;
for (i=1; i < array_size; i++)
{
index = numbers[i];
j = i;
while ((j > 0) && (numbers[j-1] > index))
{
numbers[j] = numbers[j-1];
j = j - 1;
}
numbers[j] = index;
}
}
void main()
{
const int size=10;
int Array[size];
for (int i=0;i<size;i++)
{
Array[i]=rand();
}
int x1=GetTickCount();
insertionSort(Array,size);
for(i=0;i<size;i++)
cout<<Array[i]<<endl;
int x2=GetTickCount();
cout<<"the result:"<<x2-x1<<endl;
}
4-الفرز بالدمج
#include<iostream.h>
#include<windows.h>
void merge(int numbers[], int temp[], int left, int mid, int right)
{
int i, left_end, num_elements, tmp_pos;
left_end = mid - 1;
tmp_pos = left;
num_elements = right - left + 1;
while ((left <= left_end) && (mid <= right))
{
if (numbers[left] <= numbers[mid])
{
temp[tmp_pos] = numbers[left];
tmp_pos = tmp_pos + 1;
left = left +1;
}
else
{
temp[tmp_pos] = numbers[mid];
tmp_pos = tmp_pos + 1;
mid = mid + 1;
}
}
while (left <= left_end)
{
temp[tmp_pos] = numbers[left];
left = left + 1;
tmp_pos = tmp_pos + 1;
}
while (mid <= right)
{
temp[tmp_pos] = numbers[mid];
mid = mid + 1;
tmp_pos = tmp_pos + 1;
}
for (i=0; i <= num_elements; i++)
{
numbers[right] = temp[right];
right = right - 1;
}
}
void m_sort(int numbers[], int temp[], int left, int right)
{
int mid;
if (right > left)
{
mid = (right + left) / 2;
m_sort(numbers, temp, left, mid);
m_sort(numbers, temp, mid+1, right);
merge(numbers, temp, left, mid+1, right);
}
}
void mergeSort(int numbers[], int temp[], int array_size)
{
m_sort(numbers, temp, 0, array_size - 1);
}
void main()
{
const int size=10;
int Array[size];
for(int i=0;i<size;i++)
Array[i]=rand();
int temp[size];
int x1=GetTickCount();
mergeSort(Array,temp,size);
int x2=GetTickCount();
for(i=0;i<size;i++)
cout<<Array[i]<<endl;
cout<<"the result is:"<<x2-x1<<endl;
}
5- الفرز السريع ط1
#include<iostream.h>
#include<windows.h>
void q_sort(int numbers[], int left, int right)
{
int pivot, l_hold, r_hold;
l_hold = left;
r_hold = right;
pivot = numbers[left];
while (left < right)
{
while ((numbers[right] >= pivot) && (left < right))
right--;
if (left != right)
{
numbers[left] = numbers[right];
left++;
}
while ((numbers[left] <= pivot) && (left < right))
left++;
if (left != right)
{
numbers[right] = numbers[left];
right--;
}
}
numbers[left] = pivot;
pivot = left;
left = l_hold;
right = r_hold;
if (left < pivot)
q_sort(numbers, left, pivot-1);
if (right > pivot)
q_sort(numbers, pivot+1, right);
}
void quickSort(int numbers[], int array_size)
{
q_sort(numbers, 0, array_size - 1);
}
void main()
{
const int size=10;
int Array[size];
for(int i=0;i<size;i++)
Array[i]=rand();
int x1=GetTickCount();
quickSort(Array,size);
int x2=GetTickCount();
for(i=0;i<size;i++)
cout<<Array[i]<<endl;
cout<<"the result is:"<<Array[i]<<endl;
}
ط2
#include<iostream.h>
#include<windows.h>
void swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
int Pivote(int A[],int p,int q)
{
int x=A[p];
int i=p;
for(int j=p+1;j<=q;j++)
{
if (A[j]<=x)
{
i++;
swap(A[i],A[j]);
}
}
swap(A[p],A[i]);
return i;
}
void QuickSort(int x[],int low,int high)
{
if (low<high)
{
int p=Pivote(x,low,high);
QuickSort(x,low,p-1);
QuickSort(x,p+1,high);
}
}
void main()
{
const int size=10;
int Array[size];
srand(3);
for(int i=0;i<size;i++)
{
Array[i]=rand();
}
int x1=GetTickCount();
QuickSort(Array,0, size-1);
int x2=GetTickCount();
for(i=0;i<size;i++)
cout<<Array[i]<<endl;
cout<<"the result is:"<<x2-x1<<endl;
}
6-الفرز بالاختيار أو الانتخاب
#include<iostream.h>
#include<windows.h>
void selectionSort(int numbers[], int array_size)
{
int i, j;
int min, temp;
for (i = 0; i < array_size-1; i++)
{
min = i;
for (j = i+1; j < array_size; j++)
{
if (numbers[j] < numbers[min])
min = j;
}
temp = numbers[i];
numbers[i] = numbers[min];
numbers[min] = temp;
}
}
void main()
{
const int size=10;
int Array[size];
for(int i=0;i<size;i++)
Array[i]=rand();
int x1=GetTickCount();
selectionSort(Array,size);
int x2=GetTickCount();
for(i=0;i<size;i++)
cout<<Array[i]<<endl;
cout<<"the result is:"<<Array[i]<<endl;
}
7- الفرز الصدفي
#include<iostream.h>
#include<windows.h>
void shellSort(int numbers[], int array_size)
{
int i, j, increment, temp;
increment = 3;
while (increment > 0)
{
for (i=0; i < array_size; i++)
{
j = i;
temp = numbers[i];
while ((j >= increment) && (numbers[j-increment] > temp))
{
numbers[j] = numbers[j - increment];
j = j - increment;
}
numbers[j] = temp;
}
if (increment/2 != 0)
increment = increment/2;
else if (increment == 1)
increment = 0;
else
increment = 1;
}
}
void main()
{
const int size=10;
int Array[size];
for(int i=0;i<size;i++)
Array[i]=rand();
int x1=GetTickCount();
shellSort(Array,size);
int x2=GetTickCount();
for(i=0;i<size;i++)
cout<<Array[i]<<endl;
cout<<"the result is:"<<Array[i]<<endl;
}
أرجو الفائدة بالإشارة إلى أن الكودات مجربة و أرجو التنبيه للخطأ
[SIZE=4]و السلام عليكم
Golden man
03-15-2008, 12:41 PM
شيء رائع ما شاء الله, جزاكِ الله خيرا.
سوف أقوم بتجريبها و محاولة فهمها جميعا و دراسة الفرق بينها.
mmn87
03-15-2008, 02:48 PM
شكراً على المتابعة وحب المشاركة وحب العمل
أشكر كل من شارك في هذه المشاركة
وخاصة على باقي خوارزميات الفرز لأنها مفيدة لنا
وشكراً للجميع