简单的归并排序算法例子

合集下载

mergesort用法

mergesort用法

mergesort用法归并排序(Mergesort)是一种经典的排序算法,它基于分治法的思想。

与其他排序算法不同,归并排序的时间复杂度始终保持在 O(nlogn) 的级别,因此在处理大规模数据集时表现出色。

归并排序的用法非常简单,只需将待排序的数组作为输入参数传入归并排序函数即可。

下面是一个示例代码:```pythondef mergesort(arr):# 递归终止条件,数组长度为1时if len(arr) <= 1:return arr# 分割数组为两半mid = len(arr) // 2left = arr[:mid]right = arr[mid:]# 递归调用归并排序函数left = mergesort(left)right = mergesort(right)# 合并左右两个有序数组return merge(left, right)def merge(left, right):result = []l, r = 0, 0# 比较并合并两个数组while l < len(left) and r < len(right):if left[l] < right[r]:result.append(left[l])l += 1else:result.append(right[r])r += 1# 处理剩余的元素result.extend(left[l:])result.extend(right[r:])return result```以上代码展示了一个基于Python的归并排序实现。

使用时,只需调用`mergesort`函数并将待排序数组作为参数传入即可。

该函数会返回一个排序好的新数组,而不会修改原始数组。

归并排序的核心思想是将数组逐步分割为较小的子数组,直至每个子数组的长度为1。

然后,逐个合并这些子数组,直到得到一个完全有序的数组。

这种分而治之的策略保证了归并排序的稳定性和高效性。

常用算法举例范文

常用算法举例范文

常用算法举例范文在计算机科学中,算法是解决问题的一系列有序步骤,它能够帮助我们解决各种各样的问题。

以下是一些常用的算法及其举例:1.排序算法:-冒泡排序:通过比较相邻元素并交换位置来将最大的元素逐渐移动到数组的末尾。

-快速排序:选择一个基准元素,将数组分为两部分,左边的元素小于基准,右边的元素大于基准,然后递归地对两部分进行快速排序。

-归并排序:将数组划分为两个子数组,对每个子数组分别进行归并排序,然后将两个有序子数组合并成一个有序数组。

2.查找算法:-二分查找:对于有序数组,通过与中间元素进行比较,将查找范围缩小一半,直到找到目标元素或确定不存在。

-哈希查找:通过将关键字映射到数组的索引位置来进行查找,可以在常数时间内找到目标元素。

3.图算法:-广度优先(BFS):从起始节点开始,逐层遍历图中的节点,直到找到目标节点。

-深度优先(DFS):从起始节点开始,沿着一条路径一直向下,直到找到目标节点或无法继续为止。

4.动态规划算法:-背包问题:给定一组物品和一个容量限制,选择一些物品放入背包中,使得总价值最大。

-最长公共子序列(LCS):给定两个字符串,找到它们的最长公共子序列的长度。

5.数学算法:-欧几里得算法:计算两个整数的最大公约数。

-快速幂算法:计算一个数的幂运算,通过将指数进行二进制拆分来减少计算次数。

6.字符串处理算法:-KMP算法:通过利用已匹配字符的信息来避免不必要的回溯,实现高效的字符串匹配。

- Boyer-Moore算法:利用模式串中的信息来进行快速的字符串匹配。

7.图像处理算法:-图像平滑算法:通过对图像进行滤波处理,去除图像中的噪声,使其更加平滑。

-图像边缘检测算法:通过检测图像中的边缘信息,突出物体的轮廓。

8.机器学习算法:-K均值聚类算法:将数据集划分为K个簇,使得同一个簇内的数据点之间的距离最小化。

-支持向量机(SVM):将数据集映射到高维空间,并通过找到最优的超平面来实现分类。

自顶向下的二路归并排序算法

自顶向下的二路归并排序算法

自顶向下的二路归并排序算法说到二路归并排序,可能有人会觉得这听起来挺复杂,实际上嘛,它就像是我们做家务时那种“大扫除”模式。

怎么说呢?你把一堆乱七八糟的东西分成两堆,一堆一堆收拾,最后再慢慢合成一个干干净净的地方。

是不是感觉有点意思?嗯,就是这么回事。

那我们就一起看看这个自顶向下的二路归并排序是怎么回事,怎么能让你的数据井井有条,像整理房间一样。

二路归并排序就是把一大堆无序的数据,像是刚刚从抽屉里翻出来的各种物品,一点点给它整理成有序的。

你知道,排序的过程其实就像是找整理房间的顺序,别说,虽然每次都得从上往下整理,但是最后那效果可不就是一目了然嘛!在二路归并排序里,它其实是通过“分而治之”的方式,先把数据分成两半,两半再继续分,一直到每一份数据就只剩下一个元素,觉得“这不就好了嘛”!但这个时候也别高兴得太早,因为后面就是要把这些小部分合并起来了。

嘿嘿,听着好像很简单,其实别小看了这一步。

你把一堆小的部分慢慢合并成大的,过程中就得保持它们之间的有序。

就好像你买了一堆书,每一本书放在不同的堆里,最后要是一本一本拿到一起,你总不能乱七八糟地堆吧,得按照书的顺序,从小到大,一本接着一本地放进去。

你要是从大堆的中间开始,分成两堆,这两堆里又可以继续再分,直到每堆只剩下一个元素,然后再开始按照“从小到大”的顺序合并回来。

合并的时候,别着急,慢慢来,谁小谁先放。

要是你直接乱堆,最后结果肯定不对,试想一下,书堆堆错了,哪还有办法看下去?哎呀,这样说起来,倒有点像是我们小时候做作业分组。

每个人都有自己的任务,先分配工作,每个人拿一小部分,最后再把大家的成果合并成一个完整的答案。

可有趣的是,每一部分拿到手时,我们是可以不用管它是否有序的,反正每个小部分都已经是最简单的状态,至于合并,它只要保持顺序就行。

说白了,这就像是把乱成一锅粥的书本,整理成一排排整整齐齐的书架,最后结果出来那一刻,心里顿时觉得:这下舒服了。

有意思的是,这个过程就是自顶向下的,什么意思呢?从大到小,从整体到局部。

分治算法举例范文

分治算法举例范文

分治算法举例范文分治算法是一种很重要的算法思想,它将一个大的问题划分成较小的子问题,然后分别求解这些子问题,最后将子问题的解合并起来得到原问题的解。

下面我将详细介绍分治算法的几个经典例子。

1. 快速排序(Quick Sort)快速排序是一种经典的使用分治算法的排序算法。

它首先选择一个基准元素,然后将数组划分成两个子数组:小于基准元素的和大于基准元素的。

然后对这两个子数组分别递归地进行快速排序,最后将两个子数组合并起来即可得到有序的数组。

快速排序的时间复杂度为O(nlogn)。

2. 归并排序(Merge Sort)归并排序也是一种利用分治思想的排序算法。

它将待排序的数组划分成两个子数组,然后分别对这两个子数组进行归并排序,最后将两个有序的子数组合并成一个有序的数组。

归并排序的时间复杂度也是O(nlogn)。

3. 汉诺塔问题(Tower of Hanoi)汉诺塔问题是数学领域中一个经典的问题,也可以通过分治算法来解决。

问题的规模是将n个圆盘从一个柱子移动到另一个柱子上,移动时需要遵守以下规则:每次只能移动一个盘子,移动过程中不能将较大的盘子放在较小的盘子上。

可以将问题划分成三个子问题:将前n-1个盘子从起始柱子移动到中间柱子上,将最后一个盘子从起始柱子移动到目标柱子上,最后将前n-1个盘子从中间柱子移动到目标柱子上。

这样就可以递归地求解子问题,最后合并起来得到原问题的解。

4. 最大子数组和问题(Maximum Subarray)最大子数组和问题是求解给定数组中连续子数组的最大和的问题。

可以使用分治算法来解决这个问题。

首先将数组划分成两个子数组,然后分别求解这两个子数组中的最大子数组和。

接下来,需要考虑跨越中点的情况,即包含中点的子数组的最大和。

最后,将这三种情况中的最大值作为最终的结果。

最大子数组和问题的时间复杂度为O(nlogn)。

5. 矩阵乘法(Matrix Multiplication)矩阵乘法也可以通过分治算法来实现。

数字的大小排序

数字的大小排序

数字的大小排序数字的大小排序在我们的日常生活中经常会用到,不论是在数学领域,还是在实际应用中,都需要对数字按照大小进行排序。

本文将介绍几种常用的数字排序方法,以帮助读者更好地理解和应用数字排序算法。

一、冒泡排序冒泡排序是一种简单直观的排序算法,基本思想是通过比较相邻的两个数字,如果前一个数字大于后一个数字,则交换它们的位置,这样一轮比较下来,最大的数字会“冒泡”到数组的末尾。

重复这个过程,直到所有数字按照从小到大的顺序排列。

举个例子来说明冒泡排序的过程,假设我们有一个包含6个数字的数组:[5, 2, 8, 3, 1, 9]。

经过一轮冒泡比较后,数组变为[2, 5, 3, 1, 8, 9]。

接着再进行一轮冒泡比较,数组变为[2, 3, 1, 5, 8, 9]。

继续进行比较和交换,最终得到按照从小到大排序的数组:[1, 2, 3, 5, 8, 9]。

二、选择排序选择排序是一种简单但不稳定的排序算法,它的基本思想是每次从待排序的数字中选出最小的数字,放到已排序数字的末尾,直到所有数字按照从小到大的顺序排列。

以同样的例子来说明选择排序的过程,假设我们有一个包含6个数字的数组:[5, 2, 8, 3, 1, 9]。

首先,找到数组中最小的数字1,并将其与数组的第一个数字5交换位置,此时数组变为[1, 2, 8, 3, 5, 9]。

接着,在剩下的数字中,找到最小的数字2,并将其与数组的第二个数字8交换位置,此时数组变为[1, 2, 8, 3, 5, 9]。

继续进行比较和交换,最终得到按照从小到大排序的数组:[1, 2, 3, 5, 8, 9]。

三、插入排序插入排序是一种简单且稳定的排序算法,适用于小规模的数字排序。

它的基本思想是从待排序的数字中逐个取出数字,并将其插入到已排序数字的合适位置,直到所有数字按照从小到大的顺序排列。

继续以同样的例子来说明插入排序的过程,假设我们有一个包含6个数字的数组:[5, 2, 8, 3, 1, 9]。

算法—4.归并排序(自顶向下)

算法—4.归并排序(自顶向下)

算法—4.归并排序(⾃顶向下)1.基本思想将两个有序的数组归并成⼀个更⼤的有序数组,很快⼈们就根据这个操作发明了⼀种简单的递归排序算法:归并排序。

要将⼀个数组排序,可以先(递归地)将它分成两半分别排序,然后将结果归并起来。

你将会看到,归并排序最吸引⼈的性质是它能够保证将任意长度为N的数组排序所需时间和NlogN成正⽐;它的主要缺点则是它所需的额外空间和N成正⽐。

简单的归并排序如下图所⽰:原地归并的抽象⽅法:实现归并的⼀种直截了当的办法是将两个不同的有序数组归并到第三个数组中,实现的⽅法很简单,创建⼀个适当⼤⼩的数组然后将两个输⼊数组中的元素⼀个个从⼩到⼤放⼊这个数组中。

public void merge(Comparable[] a, int lo, int mid, int hi){int i = lo, j = mid+1;//将a[lo..hi]复制到aux[lo..hi]for (int k = lo; k <= hi; k++) {aux[k] = a[k];}//归并回到a[lo..hi]for (int k = lo; k <= hi; k++) {if(i > mid){a[k] = aux[j++];}else if(j > hi){a[k] = aux[i++];}else if(less(aux[j], aux[i])){a[k] = aux[j++];}else{a[k] = aux[i++];}}}以上⽅法会将⼦数组a[lo..mid]和a[mid+1..hi]归并成⼀个有序的数组并将结果存放在a[lo..hi]中。

在归并时(第⼆个for循环)进⾏了4个条件判断:左半边⽤尽(取右半边的元素)、右半边⽤尽(取左半边的元素)、右半边的当前元素⼩于左半边的当前元素(取右半边的元素)以及右半边的当前元素⼤于等于左半边的当前元素(取左半边的元素)。

2.具体算法/*** ⾃顶向下的归并排序* @author huazhou**/public class Merge extends Model{private Comparable[] aux; //归并所需的辅助数组public void sort(Comparable[] a){System.out.println("Merge");aux = new Comparable[a.length]; //⼀次性分配空间sort(a, 0, a.length - 1);}//将数组a[lo..hi]排序private void sort(Comparable[] a, int lo, int hi){if(hi <= lo){return;}int mid = lo + (hi - lo)/2;sort(a, lo, mid); //将左半边排序sort(a, mid+1, hi); //将右半边排序merge(a, lo, mid, hi); //归并结果}} 此算法基于原地归并的抽象实现了另⼀种递归归并,这也是应⽤⾼效算法设计中分治思想的最典型的⼀个例⼦。

归并法求逆序数

归并法求逆序数

归并法求逆序数
归并法是一种高效的排序算法,它可以用来解决很多和排序有关的问题,其中包括求逆序数。

逆序数是指在一个序列中,如果当前的数大于后面的数,则这两个数构成了一个逆序对。

比如,序列{2, 4, 1, 3, 5}中,(2, 1)、(4, 1)和(4, 3)都是逆序对,所以这个序列的逆序数为3。

归并法求逆序数的过程可以简单描述如下:
1. 首先将待排序的序列分成两部分,分别对这两部分进行递归
排序;
2. 然后将这两个有序序列归并起来,同时统计逆序数的个数;
3. 最后将得到的逆序数加上左右两部分的逆序数之和,就是整
个序列的逆序数。

归并法求逆序数的时间复杂度为O(nlogn),是一种非常高效的
算法,可以处理大量的数据。

在实际应用中,归并法求逆序数常常被用来分析社交网络、搜索引擎等大规模数据处理场景中的逆序数问题。

- 1 -。

归并排序PPT课件

归并排序PPT课件

.
12
10.6 基数排序
❖ “花色”优先
先分成4堆; 然后,每堆再按“面值”排; 最后,收成一堆。
扑克牌 “排序” 为例
.
13
10.6 基数排序
❖ “面值”优先
先分成13堆; 每堆再按“花色”排;
扑克牌 “排序” 为例
.
14
10.6 基数排序
❖ 多关键码排序
假设有n个记录……的序列 { R1, R2, …,Rn}
.
24
10.6.2 链式基数排序
分配 算法
.
25
10.6.2 链式基数排序
收集 算法
.
26
10.6.2 链式基数排序
❖ 性能分析
若每个关键码有d 位,需要重复执行d 趟“分配” 与“收集”。而每趟对n 个对象进行“分配”, 对r 个队列进行“收集”。总时间复杂度为O(d (n+r))。
若基数r相同,对于数据个数较多而关键码位数
.
5
初始关键字: [49] [38] [65] [97] [76] [13] [27] 一趟归并后: [38 49] [65 97] [13 76] [27] 二趟归并后: [38 49 65 97] [13 27 76] 三趟归并后: [13 27 38 49 65 76 97]
.
6
10.5 归并排序
每个记录Ri中含有d个关键字(Ki0, Ki1, …,Kid-1)。则 有序是指:对于序列中任意两个记录Ri和Rj(1≤i<j≤n) 都满足下列(词典)有序关系:
(Ki0, Ki1, …,Kid-1)< (Kj0, Kj1, …,Kjd-1) 其中K0被称为“最高”位关键字,Kd-1被称为 “最低” 位关键字。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class GuiBing {
public static void main(String[] args) throws Exception { int datalength=1000000;
GuiBing gui=new GuiBing();
int[] array1=gui.createArray(datalength);
int[] array2=gui.createArray(datalength);
Thread.sleep(20000);
long startTime = System.nanoTime();//纳秒精度
long begin_freeMemory=Runtime.getRuntime().freeMemory(); int[] final_array=gui.guibing(array1,array2);
boolean result=gui.testResult(final_array);
long end_freeMemory=Runtime.getRuntime().freeMemory(); System.out.println("result===="+result);
long estimatedTime = System.nanoTime() - startTime;
System.out.println("elapsed time(纳秒精
度):"+estimatedTime/100000000.0);
System.out.println("allocated
memory:"+(begin_freeMemory-end_freeMemory)/1000.0+" KB"); Thread.sleep(20000);
}
/**
* 显示数组的内容
* @param array
*/
private static void dispalyData(int[] array) {
for(int i=0;i<array.length;i++)
{
System.out.printf("%-6d",array[i]);
}
System.out.println("");
}
/**
* 测试结果
* @param final_array
* @return
*/
private boolean testResult(int[] final_array) {
int length=final_array.length;
for(int i=0;i<length-1;i++){
if(final_array[i]>final_array[i+1]) return false;
}
return true;
}
/**
* 算法的思想是:
* 数组a是有序的,从小到大
* 数组b是有序的,从小到大
* 归并两个数组到一个中
* 1 从两个数组的第一个元素比较,小的放在新数组的第一个位置,小的元素所在的数组索引加1,依此比较
* 直到结束
* 2 将剩余元素直接拷贝到新的数组内
**/
private int[] guibing(int[] a, int[] b) {
int[] temp=new int[a.length*2];
int i=0,j=0,a_length=a.length,b_length=a.length,k=0;
arraySort(a);
arraySort(b);
//dispalyData(a);
//dispalyData(b);
while(i<a_length && j<b_length){
if(a[i]<b[j]){
temp[k]=a[i];
k++;i++;
}else{
temp[k]=b[j];
k++;j++;
}
}
while(i<a_length){
temp[k++]=a[i++];
}
while(j<b_length){
temp[k++]=b[j++];
}
return temp;
}
/**
* 用集合类Collections升序排列
* @param a
*/
@SuppressWarnings({"unchecked","unused"})
private void sort(final int[] a){
List list=new ArrayList();
for(int i=0;i<a.length;i++)
list.add(a[i]);
Collections.sort(list);
Object[] temp=list.toArray();
for(int i=0;i<temp.length;i++){
a[i]=(Integer)temp[i];
}
}
/**
* 使用系统类对数组以升序排序。

* @param a
*/
@SuppressWarnings({"unchecked","unused"})
private void arraySort(final int[] a){
Arrays.sort(a);
}
/**
* 根据参数length创建一个随机的整数数组。

数组中的值的小于length*2 * @param length
* @return
*/
private int[] createArray(int length) {
Random random=new Random();
int[] temp=new int[length];
int j=0;
while(j<length){
temp[j++]=random.nextInt(length<<2);
}
return temp;
} }。

相关文档
最新文档