南京邮电大学算法与设计实验一:分治策略(最全最新,与题目要求一致)

这篇具有很好参考价值的文章主要介绍了南京邮电大学算法与设计实验一:分治策略(最全最新,与题目要求一致)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实验原理:

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

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

实验内容:

1、两路合并排序和快速排序

(1)排序是数据处理中常用的重要手段,是指将一个元素序列调整为按指定关键字值的递增(或递减)次序排列的有序序列。用分治法求解排序问题的思路是,按某种方式将序列分成两个或多个子序列,分别进行排序,再将已排序的子序列合并成一个有序序列。合并排序和快速排序是两种典型的符合分治策略的排序算法。

(2)如果采用顺序存储的可排序表作为算法实现的数据结构,则需要定义一个可排序表类SortableList,两路合并算法和快速排序算法均由定义在该类上的函数实现。

//可排序表类的定义
class SortableList
{
    public:
        SortableList(int mSize)
        {
        maxSize=mSize;
        l=new int[maxSize];
        n=0; //数组中已有元素个数
        }
        ~SortableList()
        {
            delete []l;
        }
        void Input()
        {
                int i;
                for(i=0;i<maxSize;i++)
                    cin>>l[i];
        }
        void Output()
        {
                int i;
                for(i=0;i<maxSize;i++)
                    cout<<l[i]<<", ";
                    cout<<endl;
        }
    private:
        int *l;
        int maxSize;
        int n;
};

(3)结合书上已有的程序代码,使用分治法的两路合并排序算法,实现对初始序列的排序

class SortableList
{
    public:
        SortableList(int mSize,int num)
        {
        maxSize=mSize;
        l=new int[maxSize];
        n=num; //数组中已有元素个数
        }
    
        ~SortableList()
        {
            delete []l;
        }
        void Input()
        {
            int i;
            cout << "请输入待排序的数组:";
            for(i=0;i<n;i++)
                cin>>l[i];
        }
        void Output()
        {
            int i;
            for(i=0;i<n;i++)
                cout<<l[i]<<", ";
            cout<<endl;
        }
    //两路合并算法
        void MergeSort()
        {
            MergeSort(0, n-1);
        }
    
    private:
        int *l;
        int maxSize;
        int n;
    //两路合并排序算法
    void MergeSort(int left,int right)
    {
        if(left<right){                 //若序列长度超过1则划分成2个子序列
            int mid = (left+right)/2;   //将待排序序列一分为二
            MergeSort(left,mid);        //对左子序列排序
            MergeSort(mid+1, right);    //对右子序列排序
            Merge(left, mid, right);    //将2个序列合并
        }
    }
    //将2个有序序列合成一个有序序列的Merge函数
    void Merge(int left,int mid,int right)
    {
        int *temp = new int [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;i<k;i++){
                l[left++]=temp[i];
            }
    }
};

int main()
{
    int num;
    cout << "请输入待排序的数组个数:";
    cin >> num;
    SortableList List(20,num);
    List.Input();
    cout << "合并排序前的结果为:";
    List.Output();
    List.MergeSort();
    cout << "合并排序后的结果为:";
    List.Output();
    return 0;
}

实验结果:

南京邮电大学算法实验报告,实验报告:算法与设计,算法,动态规划,Powered by 金山文档
南京邮电大学算法实验报告,实验报告:算法与设计,算法,动态规划,Powered by 金山文档

由实验结果可得知两路合并排序算法成功

(4)结合书上已有的程序代码,使用分治法的快速排序算法,实现对初始序列的排序。

//快速排序算法
class SortableList
{
    public:
        SortableList(int mSize,int num)
        {
            maxSize=mSize;
            l=new int[maxSize];
            n=num; //数组中已有元素个数
        }
        ~SortableList()
        {
            delete []l;
        }
        void Input()
        {
            int i;
            cout << "请输入待排序的数组:";
            for(i=0;i<n;i++)
                cin>>l[i];
        }
        void Output()
        {
            int i;
            for(i=0;i<n;i++)
                cout<<l[i]<<", ";
            cout<<endl;
        }
    //快速排序算法
    void QuickSort()
    {
        QuickSort(0, n-1);
    }
    
    private:
        int *l;
        int maxSize;
        int n;
    void Swap(int i,int j)//交换下标i、j的数组
    {
    int c=l[i];
    l[i]=l[j];
    l[j]=c;
    }
    //快速排序算法的实现
    void QuickSort(int left,int right)
    {
        if (left<right)
        {
        int j=Partition(left,right);
        QuickSort(left,j-1);
        QuickSort(j+1,right);
        }
    }
    //定位
    int Partition(int left,int right)
    {
    int i=left,j=right+1;
    do{
    do i++; while (l[i]<l[left]);
    do j--; while (l[j]>l[left]);
    if (i<j) Swap(i,j);
    }while (i<j);
    Swap(left,j);
    return j;
    }
};

int main()
{
    int num;
    cout << "请输入待排序的数组个数:";
    cin >> num;
    SortableList List(20,num);
    List.Input();
    cout << "快速排序前的结果为:";
    List.Output();
    List.QuickSort();
    cout << "快速排序后的结果为:";
    List.Output();
    return 0;
} 

实验结果:

南京邮电大学算法实验报告,实验报告:算法与设计,算法,动态规划,Powered by 金山文档
南京邮电大学算法实验报告,实验报告:算法与设计,算法,动态规划,Powered by 金山文档

由实验结果可得知快速排序算法成功

//寻找第k个最小元
class SortableList
{
    public:
        SortableList(int mSize,int num)
        {
            maxSize=mSize;
            l=new int[maxSize];
            n=num; //数组中已有元素个数
        }
        ~SortableList()
        {
            delete []l;
        }
        void Input()
        {
            int i;
            cout << "请输入待排序的数组:";
            for(i=0;i<n;i++)
                cin>>l[i];
        }

        void Output(int m, int index)
        {
            cout<<"第"<<m<<"个最小元是"<<l[index]<<endl;
        }
   
    int Select(int m){
        return Select(m,0,n-1,5);
    }
    
    private:
        int *l;
        int maxSize;
        int n;
    
    void Swap(int i,int j)//交换下标i、j的数组
    {
    int c=l[i];
    l[i]=l[j];
    l[j]=c;
    }
   //寻找第k小元素
    int Select(int k,int left,int right,int r) {
        int n=right-left+1;
        if(n<=r) {//若问题足够小,使用直接插入排序,取其中得第k小元素,其下标为;left+k-1
            InsertSort(left,right);
            return  left+k-1;
        }
        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+Ceil(r,2)-1);//将每组的中间值集中存放在子表前部
        }
        int j=Select(Ceil(n/r,2),left,left+(n/r)-1,r);//求二次中间值,其下标为j
        Swap(left,j);                                // 二次中间值为主元,并换至left处
        j=Partition(left,right);                    //对表(子表)进行分划操作
        if(k==j-left+1) return j;                    //返回第K小元素下标
        else if(k<j-left+1) return Select(k,left,j-1,r);//在左子表求第k小元素
        else return Select(k-(j-left+1),j+1,right,r);//在右子表求第k-(j-left+1)小元素
    }
    //直接插入排序算法
    void InsertSort(int left,int right) {
        for(int i=left+1; i<=right; i++) {
            int key=l[i];
            int j=i-1;
            while(j>=0 && l[j]>key) {
                l[j+1]=l[j];
                j--;
            }
            l[j+1]=key;
        }
    }
    //定位
    int Partition(int left,int right)
    {
    int i=left,j=right+1;
    do{
    do i++; while (l[i]<l[left]);
    do j--; while (l[j]>l[left]);
    if (i<j) Swap(i,j);
    }while (i<j);
    Swap(left,j);
    return j;
    }
    //划分
    int Ceil(int x,int y) {
        return x%y==0?x/y:x/y+1;
    }
};

int main()
{
    int num;
    int m;
    cout << "请输入待排序的数组个数:";
    cin >> num;
    SortableList List(20,num);
    List.Input();
    cout << "请输入所需要查找的第几个最小元:";
    cin >> m;
    int index=List.Select(m);
    List.Output(m,index);
    return 0;
}

实验结果:

南京邮电大学算法实验报告,实验报告:算法与设计,算法,动态规划,Powered by 金山文档
南京邮电大学算法实验报告,实验报告:算法与设计,算法,动态规划,Powered by 金山文档

由实验结果可得知寻找第k个最小元算法成功文章来源地址https://www.toymoban.com/news/detail-854718.html

到了这里,关于南京邮电大学算法与设计实验一:分治策略(最全最新,与题目要求一致)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 南京邮电大学数学实验最新版

    1.1(1) 1.1(2) 1.2 1.3 1.4 1.5 1.6 1.7(1) f.m g.m main 1.7(2) f1.m g1.m main 1.8(1) 1.8(2) 1.9 1.10 1.11 1.12(1) 1.12(2) fun.m Main.m 2.1(1) dd.m main 2.2 2.3 Martin.m 2.4 2.5(1) 2.5(2) 3.1 结果 3.2 结果 3.3(1) 3.3(3) 3.4 4.1 4.3 4.4 4.5(1) 4.5(2) 4.6 4.7 4.8 4.9 实验一 //散点图 //模型建立 //数据预测

    2024年02月11日
    浏览(48)
  • 2023南京邮电大学通达学院《数学实验》MATLAB实验答案

    四月维夏,六月徂暑。 勤将励勉,勿望再晨。 ——赠nmy 南京邮电大学通达学院《数学实验》MATLAB实验答案 答案更新时间:2023.04.28,修改了4.2的存疑部分。已更新完成,如无错误不在更新 为了方便核算,我在代码中单独将 m 定义为自变量运算或者直接以m=117代入,作业中可以

    2023年04月20日
    浏览(117)
  • 南京邮电大学数据库实验一(SQL语言)

    (1) 通过上机实践,熟悉Oracle的SQL * Plus环境及使用方法 (2) 掌握SQL语言,能熟练运用SQL语言进行数据定义和数据操纵 (3) 加深对关系数据模型的数据结构和约束的理解 硬件:微型计算机 软件:Windows 操作系统、ORACLE 10G 实验原理基于第二、三、五章的相关内容。 实验内容如下:

    2024年04月27日
    浏览(47)
  • 南京邮电大学电工电子(数电)实验报告——组合逻辑电路 & 时序逻辑电路

    5、使用ISE软件完成组合逻辑设计的输入并仿真 6、掌握Testbech中组合逻辑测试文件的写法 7、下载并测试实现的逻辑功能 ①4选1数据选择器 RTL代码 仿真测试模块代码 ②3-8译码器 RTL代码 仿真测试模块代码 ③8-3优先编码器 RTL代码 仿真测试模块代码 ④十六进制七段LED显示译码器

    2024年02月04日
    浏览(69)
  • 南京邮电大学Web技术双语实验一(客户端HTML脚本编写)

    实验目的: (1) 通过上机实践,熟悉 HTML 和 JavaScript 脚本实现技术。 (2) 加深对 Web 编程的认识 实验要求: 1 编写个人主页,要求包含如下信息。 (1) 标题“欢迎访问×××的主页” (2) 个人简介,包含照片。 (3) 个人经历简介,以有序列表形式显示。 (4) 个人最

    2024年02月05日
    浏览(65)
  • 南京邮电大学电工电子(数电)实验报告——计数器 & 移位寄存器

    1、掌握计数器的逻辑功能及应用方法 2、掌握任意进制计数器的设计方法 3、掌握数字电路多个输出波形相位关系的正确测试方法 4、了解非均匀周期信号波形的测试方法 设计一个分频比N=5的整数分频电路,观察并记录时钟脉冲和输出波形。 选用cb4cle二进制计数器模块,采用

    2024年02月03日
    浏览(89)
  • 南京邮电大学电工电子基础B实验四(戴维南与诺顿定理)

    一、 实验目的 1、学习几种常用的等效电源的测量方法 2、比较几种测量方法所适用的情况 3、分析各种方法的误差大小及其产生的原因 二、 主要仪器设备及软件 硬件:交流电源、电容、电感、电阻、波特图仪。 软件:Multisim14.0 三、 75页实验表格 四、 仿真电路 五、 测量方

    2023年04月15日
    浏览(57)
  • 南京邮电大学电工电子(数电)实验报告——数字电路与模拟电路的综合应用

    1、了解D/A转换器的基本工作原理和基本结构 2、了解大规模集成D/A转换器的功能及其典型应用方法 3、掌握综合性电路的调测方法 实验内容∶设计一个可编程波形发生器技术指标∶ ① 输出信号波形受K2和K1控制 开关K2K1=01时,输出信号波形为正斜率锯齿波。开关K2K1=10时,输出

    2024年02月06日
    浏览(57)
  • 南京邮电大学数据结构实验一(线性表的基本运算及多项式的算术运算)(代码篇)

    小伙伴们要多多体会,不要全部借鉴哦!

    2024年02月08日
    浏览(51)
  • 南京邮电大学程序设计类教辅平台c++第三章作业编程题答案

    南京邮电大学程序设计类教辅平台c++第三章作业编程题答案 1.5.1构建一个类,含有三个数据成员,分别表示立方体的三条边长;含有构造函数(默认边长为3,2,1)和一个用来计算立方体体积的成员函数Compute()。 main()函数如下,请复制使用 代码: 2.设计一个Car类,它的数

    2023年04月20日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包