算法分析与设计实验报告

时间:2024.3.20

实验一  分治策略排序

一、实验目的

1)以排序问题为例,掌握分治法的基本设计策略;

2)熟练掌握合并排序算法的实现;

3)熟练掌握快速排序算法的实现;

4) 理解常见的算法经验分析方法。

二、算法思路

1.      合并排序算法思想:

分而治之(divide - conquer);每个递归过程涉及三个步骤 
第一, 分解: 把待排序的 n 个元素的序列分解成两个子序列, 每个子序列包括 n/2 个元素. 
第二, 治理: 对每个子序列分别调用归并排序MergeSort, 进行递归操作 
第三, 合并: 合并两个排好序的子序列,生成排序结果. 

最坏时间复杂度 http://d.hiphotos.baidu.com/baike/s%3D69/sign=0ae48112b251f819f5250043dbb4bfb5/b3119313b07eca8056ce3ede932397dda144833b.jpg

最好时间复杂度 http://d.hiphotos.baidu.com/baike/s%3D69/sign=0ae48112b251f819f5250043dbb4bfb5/b3119313b07eca8056ce3ede932397dda144833b.jpg

空间复杂度 http://e.hiphotos.baidu.com/baike/s%3D33/sign=3124d6d4e51190ef05fb94dcce1b2048/0eb30f2442a7d9337c84e24aaf4bd11373f001de.jpg

2.快速排序算法思想:

通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后再按次方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。假设要排序的数组是A[1]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序。一躺快速排序的算法是: 

1)、设置两个变量I、J,排序开始的时候I:=1,J:=N;  

2)以第一个数组元素作为关键数据,赋值给X,即X:=A[1];  

3)、从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,两者交换; 

4)、从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,两者交换; 

5)、重复第3、4步,直到I=J;

三、实验内容:

1.      准备实验数据

要求:编写一个函数data-generate,生成2000个在区间[1,10000]上的随机整数,并将这些数输出到外部文件data.txt中。这些数作为本算法实验的输入数据。

2.      实现合并排序算法

要求:实现mergesort算法。

输入:待排数据文件data.txt;

输出:有序数据文件resultsMS.txt(注:建议将此排好序的数据作为实验二的算法输入);程序运行时间TimeMS。

合并排序算法(类C语言):

/* 数组A[] 中包含待排元素;array B[] is a work array */

TopDownMergeSort(A[], B[], n)

{

    TopDownSplitMerge(A, 0, n, B);

}

// iBegin is inclusive;  iEnd is exclusive (即:A[iEnd]不是待排元素)

TopDownSplitMerge(A[], iBegin, iEnd, B[])

{

    if(iEnd - iBegin < 2)          // 如果只有1个待排元素,返回。

        return;

    // recursively split runs into two halves until run size == 1,

    // then merge them

    iMiddle = (iEnd + iBegin) / 2;     // 划分

    TopDownSplitMerge(A, iBegin,  iMiddle, B);

    TopDownSplitMerge(A, iMiddle,    iEnd, B);

    TopDownMerge(A, iBegin, iMiddle, iEnd, B);  // 合并;元素放到数组B中。

    CopyArray(B, iBegin, iEnd, A);              // copy the merged runs back to A

}

// left half is A[iBegin : iMiddle-1]

// right half is A[iMiddle : iEnd-1]

TopDownMerge(A[], iBegin, iMiddle, iEnd, B[])

{

    i0 = iBegin, i1 = iMiddle;

   

    // While there are elements in the left or right runs

    for (j = iBegin; j < iEnd; j++) {

        // If left run head exists and is <= existing right run head.

        if (i0 < iMiddle && (i1 >= iEnd || A[i0] <= A[i1])) {

            B[j] = A[i0];

            i0 = i0 + 1;

        } else {

            B[j] = A[i1];

            i1 = i1 + 1;   

        }

    }

}

CopyArray(B[], iBegin, iEnd, A[])

{

    for(k = iBegin; k < iEnd; k++)

        A[k] = B[k];

}

3.      实现快速排序算法

要求:实现QuickSort 算法。

输入:待排数据文件data.txt;

输出:有序数据文件resultsQS.txt(注:建议将此排好序的数据作为实验二的算法输入);程序运行时间TimeQS。

快速排序算法(伪码):

Procedure QuickSort(p, q)

integer p, q;global n, A(1:n)

if p< q then

j ← q+1

Partition(p, j);   //用元素A(p)划分元素表A[p : j-1];划分后,划分元素下标由参数j带出。

QuickSort (p, j-1);

QuickSort(j+1, q);

end if

end QuickSort

用元素A(m)划分元素表A[m : p-1]:

Procedure partition(m, p)

integer m, p, I; global A(m:p-1)

v=A(m); I=m;

loop

loop I=I+1 until A(I)>=v repeat

loop p=p-1 until A(p)<=v repeat

if I<p

then A(i) « A(p)

else exit

end if

repeat

A(m)=A(p); A(p)=v;

end partition

四、TimeIS、TimeQS的记录结果:

实验结果分析:

快速排序在一般情况下的时间效率明显优于合并排序;这个结果也与我们的理论分析结果一致。

五、实验心得:

    本次实验我对以前的排序有了更深的了解,这次是合并排序和快速排序的比较,从效率上看快排的平均时间相对要少一些,从时间的分析,看出来的,这次实验也让自己的动手难呢过力变得更好,也对一个程序完整的流程图有一定的了解。

程序清单:

#include <stdlib.h>

#include <stdio.h>

#include <time.h>

main( )

{

    int i;

    FILE *fp;//建立一个文件操作指针

    fp=fopen("data.txt","w+");//以追加的方式建立或打开1.txt

    srand( (unsigned)time( NULL ) ); 

       for( i = 0; i < 2000;i++ )//产生2000个1-10000的随机数

       fprintf(fp,"%d\n", rand()%10000+1);//输出到文本中

       fclose(fp);

}

快速排序:

#include <stdio.h>

void quick (int *p,int left,int right);

int main(void)

{

    int i;

    int a[2000];//开一个足够大的数组。   

    int k = 0;   

    FILE *fp;//文件指针   

    fp = fopen("data.txt", "r");//以文本方式打开文件。   

    if(fp == NULL) //打开文件出错。       

        return -1;   

    while(fscanf(fp, "%d", &a[k]) != EOF) //读取数据到数组,直到文件结尾(返回EOF)       

        k++;   

    fclose(fp);//关闭文件   

    quick(a,0,1999);

    for (i = 0; i <2000; i++)

    {

        printf("%d,",a[i]);

    }

    return 0;

}

void quick(int *p, int left,int right)

{

    if(left < right)

    {

        int i,j;

        int key;

        key = p[left];

        j = right;

        i = left;

        while(i < j)

        {

            while(i < j && p[j] >= key)

                j--;

            p[i] = p[j];

            while(i < j && p[i] < key)

                i++;

            p[j] = p[i];

        }

        p[i] = key;

        quick(p,left,i - 1);

        quick(p,i + 1,right);

    }

}

合并:

#include<stdio.h>

// 一个递归函数

void mergesort(int *num,int start,int end);

// 这个函数用来将两个排好序的数组进行合并

void merge(int *num,int start,int middle,int end);

int main()

{

    // 测试数组

    int num[10]= {12,54,23,67,86,45,97,32,14,65};

    int i;

    // 排序之前

    printf("Before sorting:\n");

    for (i=0; i<10; i++)

    {

        printf("%3d",num[i]);

    }

    printf("\n");

    // 进行合并排序

    mergesort(num,0,9);

    printf("After sorting:\n");

    // 排序之后

    for (i=0; i<10; i++)

    {

        printf("%3d",num[i]);

    }

    printf("\n");

    return 0;

}

//这个函数用来将问题细分

void mergesort(int *num,int start,int end)

{

    int middle;

    if(start<end)

    {

        middle=(start+end)/2;

        // 归并的基本思想

        // 排左边

        mergesort(num,start,middle);

        // 排右边

        mergesort(num,middle+1,end);

        // 合并

        merge(num,start,middle,end);

    }

}

//这个函数用于将两个已排好序的子序列合并

void merge(int *num,int start,int middle,int end)

{

    int n1=middle-start+1;

    int n2=end-middle;

    // 动态分配内存,声明两个数组容纳左右两边的数组

    int *L=new int[n1+1];

    int *R=new int[n2+1];

    int i,j=0,k;

    //将新建的两个数组赋值

    for (i=0; i<n1; i++)

    {

        *(L+i)=*(num+start+i);

    }

    // 哨兵元素

    *(L+n1)=1000000;

    for (i=0; i<n2; i++)

    {

        *(R+i)=*(num+middle+i+1);

    }

    *(R+n2)=1000000;

    i=0;

    // 进行合并

    for (k=start; k<=end; k++)

    {

        if(L[i]<=R[j])

        {

            num[k]=L[i];

            i++;

        }

        else

        {

            num[k]=R[j];

            j++;

        }

    }

    delete [] L;

    delete [] R;

}


第二篇:算法分析与设计实验报告-合并排序、快速排序


实验报告

实验一   合并排序、快速排序

一.实验目的

(1)   学习合并排序和快速排序算法的思想,掌握原理。

(2)   运用合并排序和快速排序算法的思想进行编程实现,以加深理解。

二.实验内容

(1)输入几个整数,运用合并排序的思想进行编程实现,输出正确的排序结果。

(2)输入10个整数,运用快速排序的思想进行编程实现,输出正确的排序结果

三.实验代码

(1)合并排序源代码如下:

#include <iomanip.h>//调用setw

#include <iostream.h>  //将b[0]至b[right-left+1]拷贝到a[left]至a[right]

template <class T> 

void Copy(T a[],T b[],int left,int right)

{  int size=right-left+1;

   for(int i=0;i<size;i++)

   {  

   a[left++]=b[i];

   }

}  //合并有序数组a[left:i],a[i+1:right]到b,得到新的有序数组b

template <class T> 

void Merge(T a[],T b[],int left,int i,int right)

{  int a1cout=left,//指向第一个数组开头  

   a1end=i,//指向第一个数组结尾  

   a2cout=i+1,//指向第二个数组开头  

   a2end=right,//指向第二个数组结尾  

   bcout=0;//指向b中的元素    

for(int j=0;j<right-left+1;j++)//执行right-left+1次循环

{  if(a1cout>a1end)

 {   b[bcout++]=a[a2cout++]; 

     continue; }  //如果第一个数组结束,拷贝第二个数组的元素到b

  if(a2cout>a2end) 

 {

       b[bcout++]=a[a1cout++];

       continue; }  //如果第二个数组结束,拷贝第一个数组的元素到b

if(a[a1cout]<a[a2cout])

{  b[bcout++]=a[a1cout++];

   continue; }  //如果两个数组都没结束,比较元素大小,把较小的放入b

 else 

 {  b[bcout++]=a[a2cout++];

    continue;} } }  //对数组a[left:right]进行合并排序

template <class T> 

void MergeSort(T a[],int left,int right)

 {  T *b=new

    int[right-left+1];

  if(left<right)

{  

  int i=(left+right)/2;//取中点 

  MergeSort(a,left,i);//左半边进行合并排序

  MergeSort(a,i+1,right);//右半边进行合并排序

  Merge(a,b,left,i,right);//左右合并到b中

  Copy(a,b,left,right);//从b拷贝回来

 }

 int main()

 { int n; 

  cout<<"请输入您将要排序的数目:"; cin>>n; 

 int *a=new int[n];  cout<<"请输入相应的数字:";

 for(int i=0;i<n;i++)

 {  cin>>a[i]; } 

 MergeSort( a, 0, n-1); cout<<"排序结果:";

 for(int j=0;j<n;j++)

 {  cout<<setw(5)<<a[j];  } 

    cout<<endl;

    return 1;

 } 

(2)快速排序源代码如下:

#include <iostream.h>

#define MAX 10

int QuickSort(int a[],int l,int r)

{

       int pivot; //枢轴

       int i=l;

       int j=r;

       int tmp;

       pivot=a[(l+r)/2];//取数组中间的数为枢轴

       do {

              while (a[i]<pivot) i++;  //i右移

              while (a[j]>pivot) j--;   // j左移

              if (i<=j)

              {

                     tmp=a[i];

                     a[i]=a[j];

                     a[j]=tmp; //交换a[i]和a[j]

                     i++;

                     j--;

              }

       } while(i<=j);

       if (l<j) QuickSort(a,l,j);

       if (i<r) QuickSort(a,i,r);

       return 1;

}

int main()

{

       int array[MAX];

       int i;

cout<<"请输入"<<MAX<<" 个整数:";

       for (i=0;i<MAX;i++)

       cin>>array[i];

       QuickSort(array,0,MAX-1);

       cout<<"快速排序后:"<<endl;

       for (i=0;i<MAX;i++)

              cout<<array[i]<<" ";

cout<<endl;

      

       return 0;

}

四.实验结果

五.总结与思考

更多相关推荐:
算法设计与分析实验报告1

攀枝花学院实验报告实验名称算法设计与分析课程实验实验内容比较排序算法的效率实验日期20xx0326院系数学与计算机姓名吴永昊学号20xx10804043同组人指导老师银星成绩一目的与任务通过算法的程序实现和执行...

算法设计与分析实验报告

算法设计与分析课程报告课题名称算法设计与分析课题负责人名学号同组成员名单角色指导教师评阅成绩评阅意见提交报告时间20xx年6月12日第二章递归与分治策略23改写二分搜索算法1问题描述设a0n1是已排好序的数组请...

计算机算法与设计分析实验报告

计算机算法与设计分析实验报告班级姓名学号目录实验一分治与递归11基本递归算法12棋盘覆盖问题23二分搜索34实验小结5实验二动态规划算法51最长公共子序列问题52最大子段和问题73实验小结8实验三贪心算法81多...

算法设计与分析实验报告格式

算法设计与分析实验报告一实验名称统计数字问题评分实验日期年月日指导教师刘长松姓名刘飞初专业班级计算机0901学号10一实验要求1掌握算法的计算复杂性概念2掌握算法渐近复杂性的数学表述3掌握用C语言描述算法的方法...

算法设计与分析实验报告

算法分析与设计实验报告实验报告题目实验一递归与分治策略一实验目的1加深学生对分治法算法设计方法的基本思想基本步骤基本方法的理解与掌握2提高学生利用课堂所学知识解决实际问题的能力3提高学生综合应用所学知识解决实际...

算法设计与分析实验报告格式

算法设计与分析实验报告班级姓名学号20xx年11月18日目录实验一二分查找程序实现01页实验二棋盘覆盖问题04页实验三01背包问题的动态规划算法设计07页实验四背包问题的贪心算法10页指导教师对实验报告的评语成...

算法设计与分析试验报告

武汉理工大学学生实验报告书实验课程名称算法设计与分析开课学院计算机科学与技术学院指导老师姓名何九周学生姓名王鹏学生专业班级软件100420xx20xx学年第1学期实验课程名称算法设计与分析intmiddleif...

算法设计与分析实验报告

算法设计与分析实验报告软件XXXXXXXX号实验一排序算法设计一实验内容快速排序冒泡排序希尔排序算法的编写二实验问题分析三数学模型四程序流程图五源代码六测试结果实验二递归算法设计一实验内容1判断S字符是否为回文...

算法设计与分析实验报告

算法设计与分析实验报告目录实验一分治法211实验要求212实验内容2131415实验二2122232425实验三3132333435实验四4142434445实验五5152535455核心算法2程序代码4实验结...

算法设计与分析实验报告--排序

计算机算法设计与分析实验报告学号20xx211773姓名吕功建班级0411103实验一快速排序一实验目的1以排序分类问题为例掌握分治法的基本设计策略2熟练掌握一般插入排序算法的实现3熟练掌握快速排序算法的实现4...

算法设计与分析实验报告

计算机算法设计与分析实验报告实验题目学院专业班级学号姓名指导教师20xx年20xx年第一学期一实验目的掌握递归和分治法的基本设计思想二实验环境Windows系统VC60三实验内容问题描述有这样一种单片机只支持8...

算法设计与分析实验报告样本

算法分析与设计实验报告实验报告题目实验一递归与分治策略开课实验室数学实验室指导老师时间20xx9学院理学院专业信息与计算科学班级20xx级1班姓名学号一实验目的1加深学生对分治法算法设计方法的基本思想基本步骤基...

算法设计与分析实验报告(40篇)