C++编程练习(15)----“排序算法 之 归并排序“
归并排序
归并排序(Merging Sort)的原理:
假设初始序列含有 n 个记录,则可以看成是 n 个有序的子序列,每个子序列的长度为1,然后两两归并,得到 [n/2] ([ x ] 表示不小于 x 的最小整数)个长度为 2 或 1 的有序子序列;再两两归并,·······,如此重复,直至得到一个长度为 n 的有序序列为止,这种排序方法称为 2 路归并排序。
归并排序是一种较占用内存,效率高,稳定的算法。
整个排序过程如下图所示:
算法描述:
归并操作的工作原理如下:
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
具体代码如下:
1、排序前的一些准备工作,建立合适的排序需要的结构。
/********* 排序用到的结构 头文件sort_struct.h ************/
#include <ctime>
#include <cstdlib>
#define MAXSIZE 100 //要排序数组个数最大值 class SqList{
public:
int r[MAXSIZE+1];
int length;
}; /* 交换L中数组r下标为i和j的值 */
void swap(SqList *L, int i, int j)
{
int temp = L->r[i];
L->r[i] = L->r[j];
L->r[j] = temp;
} /* 显示数组内容 */
void showSqList(SqList *L)
{
for(int i=1;i<=L->length;i++)
std::cout<<L->r[i]<<" ";
std::cout<<std::endl;
} /* 为数组随机产生一串数字 */
double random(double start, double end)
{
return start+(end-start)*rand()/(RAND_MAX + 1.0);
}
void RandomCreat(SqList *L,int len)
{
double random(double,double);
srand(unsigned(time(0)));
for(int i=1;i<=len;i++)
{
L->r[i] = int(random(0,100));
}
}
2、编写主文件,实现排序与测试。
/********* C++堆排序算法 ************/
#include<iostream>
#include<time.h>
#include<Windows.h>
#include"sort_struct.h"
using namespace std; /* 将有序的SR[i...m]和SR[m+1...n]归并为有序的TR[1...n] */
void Merge(int SR[],int TR[],int i,int m,int n)
{
int j,k,l;
for(j=m+1,k=i;i<=m && j<=n;k++) //将SR中记录由小到大归并入TR
{
if(SR[i]<SR[j])
TR[k] = SR[i++];
else
TR[k] = SR[j++];
}
if(i<=m)
{
for(l=0;l<=m-i;l++)
TR[k+l] = SR[i+l]; //将剩余的SR[i...m]复制到TR
}
if(j<=n)
{
for(l=0;l<=n-j;l++)
TR[k+l] = SR[j+l]; //将剩余的SR[j...n]复制到TR
} } /* 将SR[]中相邻长度为s的子序列两两归并到TR[] */
void MergePass(int SR[],int TR[],int s,int n)
{
int i = 1;
int j;
while(i<=n-2*s+1)
{
Merge(SR,TR,i,i+s-1,i+2*s-1); //两两归并
i = i+2*s;
}
if(i<n-s+1) //归并最后两个序列
Merge(SR,TR,i,i+s-1,n);
else //若最后只剩下单个子序列
for(j=i;j<=n;j++)
TR[j] = SR[j];
} /* 对顺序表L作归并非递归排序 */
void MergeSort(SqList *L)
{
int *TR = new int[L->length+1]; //申请额外空间
int k = 1;
while (k<L->length)
{
MergePass(L->r,TR,k,L->length);
k = 2 * k; //子序列长度加倍
MergePass(TR,L->r,k,L->length);
k = 2 * k; //子序列长度加倍
}
delete[] TR;
} int main()
{
SqList *L = new SqList;
L->length = 10;
RandomCreat(L,L->length);
cout<<"排序前:";
showSqList(L); MergeSort(L);
cout<<"归并排序后:";
showSqList(L); return 0;
}
运行结果如下:
C++编程练习(15)----“排序算法 之 归并排序“的更多相关文章
- Java常见排序算法之归并排序
在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...
- 【排序算法】归并排序算法 Java实现
归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 基本思想 可以将一组数组分成A,B两组 依次类推,当分出来的小组只有一 ...
- 【DS】排序算法之归并排序(Merge Sort)
一.算法思想 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法的一个非常典型的应用,指的是将两个已经排序的序列合并成一个序列的操作.其归并思想如下: 1)申请空间,使其大小为两个已经 ...
- 排序算法之归并排序(Mergesort)解析
转自:http://www.cnblogs.com/ayqy/p/4050452.html 一.归并排序的优缺点(pros and cons) 耗费心思来理解它,总要有个理由吧: 归并排序的效率达 ...
- 我的Java开发学习之旅------>Java经典排序算法之归并排序
一.归并排序 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个子序列 ...
- 我的Java开发学习之旅------>Java经典排序算法之归并排序
一.归并排序 归并排序是建立在归并操作上的一种有效的排序算法,该算法是採用分治法(Divide and Conquer)的一个很典型的应用.将已有序的子序列合并,得到全然有序的序列.即先使每一个子序列 ...
- C++编程练习(16)----“排序算法 之 快速排序“
快速排序 基本思想: 通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的. 算法介绍: 设要排序的 ...
- Java排序算法之归并排序
基本思想: 归并排序利用分治法,先将一个序列分成一个个子序列,然后对子序列进行排序,再把有序子序列合并为整体有序序列. 图片来自于http://www.cnblogs.com/shudonghe/p/ ...
- 数据结构与算法之PHP排序算法(归并排序)
一.基本思想 归并排序算法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,使每个子序列有序,再将已有序的子序列合并,得到完全有序的序列.该算法是采用分治法(Divid ...
随机推荐
- Laravel Eloquent get获取空的数据问题
在用laravel框架来获取数据,若数据不存在时,以为会返回空,其实不是的,其实是一个 collection 值,会返回如下: object(Illuminate\Database\Eloquent\ ...
- Codeforces#362
A题 题意:给定一串数列,t,t+s,t+s+1,t+2s,t+2s+1......问某一个数是否是数列当中的 题意:只需判断(x-t)与(x-t-1)能否整除s即可,注意起始时的判断 #includ ...
- 8、手把手教你Extjs5(八)自定义菜单2
这一节来定义另外三种类型的菜单类.首先定义菜单按钮类.文件放于app/view/main/region目录下面,文件名为ButtonMainMenu.js. /** * 显示在顶部的按钮菜单,可以切换 ...
- pyhton字符编码问题--decode和encode方法
1 decode和encode方法 字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成uni ...
- 必须熟悉的vim快捷键操作
转载请表明出处http://www.dabu.info/?p=801 Vim/Vi 没有菜单,只有命令 Vim/Vi 工作模式介绍:插入模式 和 命令模式 是vi的两个基本模式.——插入模式 ,是用 ...
- 【转】国外程序员整理的 C++ 资源大全
内容包括:标准库.Web应用框架.人工智能.数据库.图片处理.机器学习.日志.代码分析等. 标准库 C++标准库,包括了STL容器,算法和函数等. C++ Standard Library:是一系列类 ...
- Java链表的一些操作:
[还有一些其他的算法提]http://blog.csdn.net/WalkingInTheWind/article/category/906980 [转]http://blog.csdn.net/lu ...
- 解析xml的问题未解决
工作上需要解析xml,目前的逻辑是:解析xml到对象中,然后对象再插入数据库.但这存在内存溢出的风险. 今天做的另外一件事是将循环用到工作上,暂时还没有测试,是否能保证程序的重启.有待观察 ##### ...
- Robocopy 轉帖
实例一:文件,想怎么复制就怎么复制 [实现效果] 随时将源文件夹中的纯文本(TXT).Word文档(DOC)还有BMP.TIF图像文件复制到目标文件夹中 ,这是在"资源管理器"中直 ...
- JAVA中用于处理字符串的“三兄弟”
JAVA中用于处理字符串常用的有三个类:java.lang.String.java.lang.StringBuffer.java.lang.StringBuilder,这三者的共同之处都是final类 ...