八皇后 矩阵链乘 快速排序 合并排序 代码和实验报告

时间:2024.4.20

院  系:计 算 机 学 院

实验课程:算法分析与设计实验

实验项目:实验二

(应用已经学习的算法技术或者分析算法性能)

指导老师: 曹霑懋

    开课时间:2010 ~ 20##年度第 2学期

专    业:计算机科学与技术 师范类

班    级:09级  2 班

学    生: 程毅

学    号: 20092101056

华南师范大学教务处

实验名称:A.编程实现八皇后问题(验证性实验)

实验目标:使用深度优先搜索算法以及回溯法的思想进行暴力解题

实验任务:用8*8的二维数组去模拟皇后所在的棋盘,然后用1标记该位置可以放皇后,用0来标记该位置不可以放皇后。然后每次有一个合理的八皇后方案,就会counter++,记录摆放的方法,并且输出皇后摆放的坐标。

实验步骤:1.明确实验目标和实验任务

             2.理解实验所涉及到深度优先搜索的算法以及回溯法的思想

             3.编写程序实现求解八皇后问题。

             4.设计实验数据数据并运行程序,记录运行的结果

程序代码:

/***********************************************************************

这个题目我默认第一个皇后放第一行,第二个皇后放第二行,如此类推。

***********************************************************************/

#include<iostream>

using namespace std;

struct chessboard

{

       int b[8][8];                  //对棋盘的模拟

};

struct location

{

       int x,y;                      //记录皇后放的坐标

};

chessboard visited[9];          

location loc[8];

int num;                          //记录有多少种方法

void print()                      //输出皇后的方法以及种数

{

       int i;     

       cout<<++num<<ends;

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

       {

              cout<<loc[i].x<<ends<<loc[i].y<<ends;

       }

       cout<<endl;

}

int x1,y1,x2,y2;                  //用于标记坐标

void visit(int x,int y,int step)

{

       int i;

       x1=x;

       y1=y;

       x2=x;

       y2=y;

       visited[step]=visited[step-1];      //把上一次标记过不能走的坐标传到下一次

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

       {

              visited[step].b[x][i]=0;        //与皇后同行的都标为不能放

              visited[step].b[i][y]=0;        //与皇后同列的都标为不能放

       }

       while(x1<8 && y1<8)

       {

              visited[step].b[x1][y1]=0;      //与皇后对角线的标记为不能放

              x1++;

              y1++;

       }

    while(x2<8 && y2>=0)

       {

              visited[step].b[x2][y2]=0;      //与皇后对角线的标记为不能放

              x2++;

              y2--;

       }

}

void dfs(int step)

{

       int j;

       if(step==9)

       {

              print();

       }

       else

       {

             

              for(j=0;j<8;j++)

              {

                     if(visited[step-1].b[step-1][j])  

                     {

                            loc[step-1].x=step-1;            //放置皇后的位置

                            loc[step-1].y=j;

                            visit(step-1,j,step);            //进行标记

                            dfs(step+1);                     //递归进行下一个

                     }

              }

       }

}

int main()

{

       num=0;                                       //初始化计数变量num

       memset(visited,1,sizeof(visited));           //初始化visited标记数组

       dfs(1);                                      //从1开始,1作为步骤参数

       return 0;

}

数据测试: 

 

实验名称:B.矩阵链乘问题(验证性实验)

实验目标:用动态规划法去解决矩阵链乘,求链乘的最优解。

实验任务: 用6*6的二位数组去模拟需要填写的二维表,然后按照算法的顺序,按对角线的顺序去填写每一个格子的内容。

实验步骤:1.明确实验目标和实验任务

             2.理解实验所涉及到动态规划法的思想

             3.编写程序实现求矩阵链乘法的最优解。

             4.设计实验数据数据并运行程序,记录运行的结果

程序代码:

#include<iostream>

#include<iomanip>

using namespace std;

int main()

{

    int td,n=6,d,i,j,k,temp;

    int f[6][6];

    int a[7]={2,3,5,3,4,10,3};

    memset(f,0x7f,sizeof(f));

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

    {

       f[i][i]=0;                                //给对角填上0

    }

    for(d=1;d<6;d++)

    {

       for(i=0;i+d<6;i++)

       {

           j=i+d;                                 //对角线上i,j关系

           for(k=i+1;k<=j;k++)

           {

              temp=f[i][k-1]+f[k][j]+a[i]*a[k]*a[j+1];

               if(f[i][j]>temp)

              {

                  f[i][j]=temp;

              }

           }

       }

    }

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

    {

       for(j=0;j<6;j++)

       {

           if(i<=j) cout<<setw(6)<<f[i][j]<<ends;

           else cout<<"       ";

       }

       cout<<endl;

    }

    return 0;

}

数据测试:

       

实验名称:C.归并排序与快速排序平均时间比较(验证性实验)

实验目标: 1.比较两种算法在平均情况下哪一个更快

           2.加深对时间复杂度概念的理解

实验任务: 1. 用C/C++语言编程实现归并排序算法6.3 和快速排序 算法6.6。对于快速排序,SPLIT中的划分元素采用三者A(low), A(high),A((low+high)/2)中其值居中者。 

             2. 随机产生20组数据(比如n=5000i,1≤i≤ 20)。数据均属于范围(0,105)内的整数。对于同一组数据,运行快速排序和归并排序算法,并计录各自的运行时间(以毫秒为单位)。

实验步骤:1.明确实验目标和实验任务

             2.理解实验所涉及到动态规划法的思想

             3.编写程序实现求矩阵链乘法的最优解。

             4.设计实验数据数据并运行程序,记录运行的结果

程序代码:

             合并排序:

#include<iostream>

#include<ctime>

using namespace std;

//copy函数将b[0]至[high-low+1]拷贝到a[low]至a[high]

//数组b只是一个辅助数组

template <class T>

void copy(T a[],T b[],int low,int high)

{

    int i,size;

    size=high-low+1;                 

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

    {

       a[low]=b[i];

       low++;

    }

}

template <class T>

void merge(T a[],T b[],int low,int mid,int high)

{

    int a1h=low,        //指向第一个数组的开头

       a1t=mid,        //只想第一个数组的结尾

       a2h=mid+1,      //指向第二个数组的开头

       a2t=high,       //指向第二个数组的结尾

       b1=0,           //指向数组b的元素

       j;

    for(j=0;j<high-low+1;j++)

    {

       if(a1h>a1t)            //如果第一个数组拷贝完地话,就去拷贝第二个数组

       {

           b[b1]=a[a2h];     

           b1++;

           a2h++;

           continue;

       }

       if(a2h>a2t)            //如果第二个数组拷贝完的话,就去拷贝第一个数组

       {

           b[b1]=a[a1h];

           b1++;

           a1h++;

           continue;

       }

        if(a[a1h]<a[a2h])      //如果两个数组都没有拷贝完,那么就比较两个组之间的元素

       {                      //把小的拷贝进b

           b[b1]=a[a1h];

           b1++;

           a1h++;

           continue;

       }

        else

       {                      //同上

           b[b1]=a[a2h];     

           b1++;

           a2h++;

           continue;

       }

    }

}

//对数组a进行合并排序,拆分

template <class T>

void mergesort(T a[],int low,int high)

{

    int mid;

    T *b=new int [high-low+1];

    if(low<high)

    {

       mid=(low+high)/2;                  //取中点

       mergesort(a,low,mid);              //让左半边进行合并排序

       mergesort(a,mid+1,high);           //让右半边进行合并排序

       merge(a,b,low,mid,high);           //左右合并到辅助数组b中

        copy(a,b,low,high);                //把b拷回到a

    }

}

int main()

{

    int a[20],i,j;

    srand((unsigned)time(NULL));

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

    {

       a[i]=rand()%105+1;

    }

cout<<"排序之前"<<endl;

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

    {

       cout<<a[i]<<ends;

    }

    cout<<endl;

mergesort(a,0,19);

cout<<"排序之后"<<endl;

    for(j=0;j<20;j++)

    {

       cout<<a[j]<<ends;

    }

    cout<<endl;

    return 0;

}

数据测试:

快速排序

#include<iostream>

#include<ctime>

using namespace std;

template <class T>

int quickpass(T a[],int low,int high)

{

    int down,up;

    down=low;                                 //指向数组的头部

    up=high;                                  //指向数组的尾部+

    a[0]=a[low];                              //把数组的第一个数作为参考值

    while(down<up)

    {

       while((down<up) && (a[up]>=a[0]))     //从数组尾部向头部扫描,寻找比参考值小的数

       {

           up--;                             //指针向头部移动

       }

       if(down<up)

       {

           a[down]=a[up];                    //找到了,且指针没有重合,就把扫描到的值填入到空出来的地方

           down++;

       }

       while((down<up) && a[down]<=a[0])     //从数组头部向尾部扫描,寻找比参考值打得数

       {

           down++;                           //指针向尾部移动

       }

        if(down<up)

       {

           a[up]=a[down];                    //找到了,且指针没有重合,就把扫描到得值填入空出来的地方

           up--;

       }

    }

    a[down]=a[0];                             //最后把参考值填入到空出来的地方

    return down;                              //返回参考值当前位置

}

template <class T>

void quicksort(T a[],int low,int high)

{

    int mid;                                 

    if(low<high)

    {

       mid=quickpass(a,low,high);            //对数组进行一趟处理

       quicksort(a,low,mid-1);               //递归处理左半部分

       quicksort(a,mid+1,high);              //递归处理右半部分

    }

}

int main()

{

    int a[21],i;

    srand((unsigned)time(NULL));

cout<<"排序之前"<<endl;

    for(i=1;i<21;i++)

    {

       a[i]=rand()%105+1;

        cout<<a[i]<<ends;

    }

    cout<<endl;

    quicksort(a,1,21);

    cout<<"排序之后"<<endl;

for(i=1;i<21;i++)

    {

       cout<<a[i]<<ends;

    }

    cout<<endl;

    return 0;

}

数据测试:

实验小结:

首先是八皇后问题。关于八皇后问题,主要是先对回溯法进行理解。毕竟理解不了回溯法,就无法写递归程序。在做的时候简化了一下过程。把第一个皇后就放第一排,第二个皇后放第二排,而不是随机放的,降低了代码难度和复杂度。另外在回溯的时候,要做好标记,包括放下皇后的时候也要做好标记,标记好不能放的地方。

接下来是两个排序的问题。关于排序,其实很简单,就是按照书上的伪代码翻译成C++代码就可以了,加上一个产生随机数的头文件以及函数,基本上就可以交工了,代码完成毫无压力。

矩阵链乘法也挺简单的,由于有了最长公共子序列的一些经验,所以做起来也很方便。问题就是,输出矩阵的时候,一开始老是对不齐。后来突然发现自己可以用setw来控制格式,真是脑残。矩阵链乘法其实也挺简单的。

更多相关推荐:
八皇后实验报告

实验项目1实验目的通过求解皇后问题熟悉深度优先搜索法DFS回溯法BacktrackingAlgorithms技术2实验内容由n2个方块排成n行n列的正方形称为n元棋盘如果两个皇后位于n元棋盘上的同一行同一列或同...

数据结构实验报告-八皇后问题

数据结构实验报告1.实验要求实验目的:利用栈结构实现八皇后问题八皇后问题如下:八皇后问题是19世纪著名的数学家高斯于1850年提出的。他的问题是,在8*8的棋盘上放置8个皇后,使其不能互相攻击,即任意两个皇后都…

八皇后实验报告

北京邮电大学信息与通信工程学院数据结构实验报告实验名称实验二八皇后问题学生姓名姜山班级20xx211106班内序号14学号20xx210167日期20xx年11月16日1实验要求实验目的1进一步掌握指针模板类异...

八皇后实验报告

实验名称编程实现八皇后问题验证性实验实验目标使用深度优先搜索算法以及回溯法的思想进行暴力解题实验任务用88的二维数组去模拟皇后所在的棋盘然后用1标记该位置可以放皇后用0来标记该位置不可以放皇后然后每次有一个合理...

八皇后数据结构实验报告 完整版

数据结构实验报告八皇后问题实验目的熟练掌握栈操作的基本算法实现实现功能利用回溯法和栈来实现八皇后问题在88的国际象棋棋盘上安放8个皇后要求没有一个皇后能够吃掉任何其他一个皇后即没有两个或两个以上的皇后占据棋盘上...

八皇后实验报告

目录一二三四五六引言2算法分析及流程2实验过程分析4结果与讨论5改进5结语7一算法分析及流程1八皇后问题是一个古老而著名的问题该问题是十九世纪著名的数学家高斯1850提出在88格的国际象棋上摆放八皇后使其不能互...

八皇后问题 实验报告 源程序

八皇后问题实验报告需求分析八皇后问题是一个古老而著名的问题该问题是十九世纪著名的数学家高斯1850年提出的八皇后问题要求在一个的棋盘上放上个皇后使得每一个皇后既攻击不到另外七个皇后也不被另外七个皇后所攻击按照国...

河师大算法设计与分析N皇后问题实验报告

计算机与信息技术学院实验报告专业计算机科学与技术年级班级20xx级20xx20xx学年第一一实验项目N皇后问题二需求分析八皇后问题是一个古老而著名的问题该问题是十九世纪著名的数学家高斯1850年提出的八皇后问题...

PASCAL 八皇后问题解题报告

八皇后问题是一个古老而著名的问题是回溯算法的典型例题该问题是十九世纪著名的数学家高斯1850年提出在8X8格的国际象棋上摆放八个皇后使其不能互相攻击即任意两个皇后都不能处于同一行同一列或同一斜线上问有多少种摆法...

数据结构八皇后问题实习报告

数据结构实习报告专业数字媒体技术姓名李义年级20xx级学号20xx010520xx完成日期20xx1231题目八皇后问题一项目简介八皇后问题是一个古老而著名的问题是回溯算法的典型例题该问题是十九世纪著名的数学家...

算法设计与实验分析五:八皇后问题

算法设计与实验分析无五八皇后问题班级网络1101姓名齐岳川学号1111610210日期20xx521一实验名称八皇后问题二实验内容在88格的国际象棋上摆放八皇后使其不能互相攻击即任意两个皇后都不能处于同一行同一...

北邮数据结构实验二八皇后问题

数据结构实验报告实验名称学生姓名班级班内序号学号日期实验描述利用栈结构实现八皇后问题八皇后问题19世纪著名的数学家高斯于1850年提出的他的问题是在88的棋盘上放置8个皇后使其不能互相攻击即任意两个皇后都不能处...

八皇后实验报告(30篇)