算法设计与分析 实验1

一、实验目的和要求

理解分治法的算法思想,阅读实现书上已有的部分程序代码并完善程序,加深对分治法的算法原理及实现过程的理解。


二、实验环境(实验设备)

Code::Blocks13.12


三、实验原理及内容

一、用分治法实现一组无序序列的两路合并排序和快速排序。要求清楚合并排序及快速排 序的基本原理,编程实现分别用这两种方法将输入的一组无序序列排序为有序序列后输出。

 

二、采用基于“五元中值组取中值分割法”(median-of-median-of-five partitioning)的线性 时间选择算法,找出N 个元素集合 S 中的第 k 个最小的元素,使其在线性时间内解决。


源程序:

#include

#include

#include

#include

usingnamespace std;

constint INF = 2147483647;

 

classSortableList

{

public:

       SortableList(intmSize)

       {

              maxSize= mSize;

              l= newint[maxSize + 1];

              n= 0;

       }

       ~SortableList()

       {

              delete[]l;

       }

       void Input();

       void Output();

       void MergeSort();

       void QuickSort();

       void Select(intk) {

              int j = 0;

              j= Select(k, 0, n -1, 5);

              cout<<"k小元素是:"<< l[k];

       }

private:

       int *l;

       int n;             //数组中已有元素个数

       int maxSize;

       void MergeSort(intleft, intright);

       void Merge(intleft, intmid, intright);

       void InsertSort(intleft, intright);

       void Swap(inti, intj);   //交换下标为 i j的数组元素

       void QuickSort(intleft, intright);

       int Partition(intleft, intright);//  分化操作

       int RPartition(intleft, intright);

       int Select(intk, intleft, intright, intr);

};

 

voidSortableList::InsertSort(intleft, intright)

{

       for (int i = left + 1; i <= right; i++)

       {

              int j = i;

              int temp = l[i];

              while (j>left&&temp

              {

                     l[j]= l[j - 1];

                     j--;

              }

              l[i]= temp;

       }

}

 

voidSortableList::Input()

{

       cout<<"请输入元素"<< endl;

       for (int i = 0;i

       {

              cin>> l[i];

              n++;

       }

       l[n]= INF;

}

 

voidSortableList::Output()

{

       cout<<"序列元素为:"<< endl;

       for (int i = 0;i

       {

              cout<< l[i] <<" ";

       }

       cout<< endl;

}

 

voidSortableList::Swap(inti, intj)

{

       int c = l[i];

       l[i] = l[j];

       l[j] = c;

}

//两路合并排序

 

voidSortableList::MergeSort()

{

       MergeSort(0,n - 1);

}

 

voidSortableList::MergeSort(intleft, intright)

{

       if (left<right)

       {

              int mid = (left + right) / 2;

              MergeSort(left, mid);

              MergeSort(mid+ 1, right);

              Merge(left, mid, right);

       }

}

 

voidSortableList::Merge(intleft, intmid, intright)

{

       int *temp = newint[right - left + 1];

       int i = left, j = mid + 1, k = 0;

       while ((i <= mid) && (j<= right))

              if (l[i] <=l[j])

                     temp[k++]= l[i++];

              else

                     temp[k++]= l[j++];

       while (i <= mid)

              temp[k++]= l[i++];

       while (j <= right)

              temp[k++]= l[j++];

       for (i = 0, k = left; k <= right;)

              l[k++]= temp[i++];

}

 

//快速排序

 

intSortableList::RPartition(intleft, intright)

{

       srand((unsigned)time(NULL));

       int i = rand() % (right - left) + left;

       Swap(i,left);

       return Partition(left, right);

}

 

intSortableList::Partition(intleft, intright)

{

       int i = left, j = right + 1;

       do {

              do i++; while (l[i]left]);

              do j--; while (l[j]>l[left]);

              if (i

       }while (i

       Swap(left, j);

       return j;

}

 

voidSortableList::QuickSort(intleft, intright)

{

       if (left <= right)

       {

              int j = Partition(left, right);

              QuickSort(left, j - 1);

              QuickSort(j+ 1, right);

       }

}

 

voidSortableList::QuickSort()

{

       QuickSort(0,n - 1);

}

 

intSortableList::Select(intk, intleft, intright, intr)

{  //每个分组r个元素,寻找第k小元素

       int n = right - left + 1;

       if (n <= r)

       {

              InsertSort(left, right);

              returnleft + k - 1;  //返回第k小元素的下标

       }

       for (int i = 1; i <= n/ r; i++)

       {

              InsertSort(left + (i - 1)*r, left = i*r - 1); //二次取中规则求每组的中间值

              Swap(left + i - 1, left + (i - 1)*r + (int)ceil((double)r / 2) - 1);  //将每组的中间值交换到子表前部集中存放

       }

       int j = Select((int)ceil((double)n / r / 2), left, left + n / r - 1, r); //求二次中间值,其下标为j

       Swap(left, j);  //二次中间值为枢纽元,并换至left

       j= Partition(left, right);  //对表(子表)进行分划操作

       if (k = j - left + 1)  //返回第k小元素下标

              return j;

       elseif (kleft + 1)  //在左子表求第k小元素

              return Select(k, left, j - 1, r);

       else

              return Select(k - (j - left + 1), j + 1, right, r);  //在右子表求第k-(j-left+1)小元素

}

 

int main()

{

       SortableList sort(10);

       int k = 0;

       int m = 0;

       sort.Input();

       sort.Output();

       sort.MergeSort();

       sort.Output();

       sort.QuickSort();

       sort.Output();

       cout<<"请输入你要查找的第k小元素:"<< endl;

       cin>> k;

       sort.Select(k);

       return 0;

}



你可能感兴趣的:(算法设计与分析)