C语言 实现归并排序算法_C 语言

C语言 实现归并排序算法

归并排序(Merge sort)是创建在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

一个归并排序的例子:对一个随机点的链表进行排序

算法描述

归并操作的过程如下:

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
  4. 重复步骤3直到某一指针到达序列尾
  5. 将另一序列剩下的所有元素直接复制到合并序列尾

特点:归并排序是稳定的排序.即相等的元素的顺序不会改变,  速度仅次于快速排序,但较稳定。

归并操作

归并操作(merge),也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。

如:设有数列 [6,202,100,301,38,8,1]

初始状态:6, 202, 100, 301, 38, 8, 1

第一次归并后:[6, 202], [100, 301], [8, 38], [1],比较次数:3;

第二次归并后:[6, 100, 202, 301],[1, 8, 38],比较次数:4;

第三次归并后:[1, 6, 8, 38, 100, 202, 301],比较次数:4;

总的比较次数为:3+4+4=11,;

逆序数为14;

算法实现

// Completed on 2014.10.11 17:20
// Language: C99
//
// 版权所有(C)codingwu  (mail: oskernel@126.com)
// 博客地址:http://www.cnblogs.com/archimedes/
#include<stdio.h>
#include<stdlib.h>void merge_sort(int *list, const int first, const int last)
{
  int len= last-first+1;
  int left_min,left_max;  //左半区域边界
  int right_min,right_max; //右半区域边界
  int index;
  int i;
  int *tmp;
  tmp = (int *)malloc(sizeof(int)*len);
  if( tmp == NULL || len <= 0 )
    return;

  for( i = 1; i < len; i *= 2 )
  {
    for( left_min = 0; left_min < len - i; left_min = right_max)
    {
      int j;
      right_min = left_max = left_min + i;
      right_max = left_max + i;
      j = left_min;
      if ( right_max > len )
        right_max = len;
      index = 0;
      while( left_min < left_max && right_min < right_max )
      {
        tmp[index++] = (list[left_min] > list[right_min] ? list[right_min++] : list[left_min++]);
      }
      while( left_min < left_max )
      {
        list[--right_min] = list[--left_max];
      }
      while( index > 0 )
      {
        list[--right_min] = tmp[--index];
      }
    }
  }
  free(tmp);
}
int main()
{
  int a[] = {288, 52, 123, 30, 212, 23, 10, 233};
  int n, mid;
  n = sizeof(a) / sizeof(a[0]);
  mid = n / 2;
  merge_sort(a, 0, n - 1);
  for(int k = 0; k < n; k++)
    printf("%d ", a[k]);
  printf("\n");
  return 0;
}

使用递归实现:

// Completed on 2014.10.11 18:20
// Language: C99
//
// 版权所有(C)codingwu  (mail: oskernel@126.com)
// 博客地址:http://www.cnblogs.com/archimedes/
#include<stdio.h>
#include<stdlib.h>
void merge(int *array,const int first, const int mid, const int last)
{
  int i,index;
  int first1,last1;
  int first2,last2;
  int *tmp;
  tmp = (int *)malloc((last-first+1)*sizeof(int));
  if( tmp == NULL )
    return;
  first1 = first;
  last1 = mid;
  first2 = mid+1;
  last2 = last;
  index = 0;
  while( (first1 <= last1) && (first2 <= last2) )
  {
    if( array[first1] < array[first2] )
    {
      tmp[index++] = array[first1];
      first1++;
    }
    else{
      tmp[index++] = array[first2];
      first2++;
    }
  }
  while( first1 <= last1 )
  {
    tmp[index++] = array[first1++];
  }
  while( first2 <= last2 )
  {
    tmp[index++] = array[first2++];
  }
  for( i=0; i<(last-first+1); i++)
  {
    array[first+i] = tmp[i];
  }
  free(tmp);
}
void merge_sort(int *array, const int first, const int last)
{
  int mid = 0;
  if(first < last)
  {
    mid = (first + last) / 2;
    merge_sort(array, first, mid);
    merge_sort(array, mid + 1, last);
    merge(array, first, mid, last);
  }
}
int main()
{
  int a[] = {288, 52, 123, 30, 212, 23, 10, 233};
  int n, mid;
  n = sizeof(a) / sizeof(a[0]);
  mid = n / 2;
  merge_sort(a, 0, n - 1);
  for(int k = 0; k < n; k++)
    printf("%d ", a[k]);
  printf("\n");
  return 0;
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索归并排序算法
c语言归并排序算法、归并排序 c语言、c语言归并排序详解、归并排序c语言实现、归并排序c语言代码,以便于您获取更多的相关知识。

时间: 2024-07-31 16:43:48

C语言 实现归并排序算法_C 语言的相关文章

C++实现自顶向下的归并排序算法_C 语言

本文实例讲述了C++实现自顶向下的归并排序算法.分享给大家供大家参考,具体如下: 一. 算法描述 自顶向下的归并排序:采用分治法进行自顶向下的程序设计方式,分治法的核心思想就是分解.求解.合并. 1. 先将长度为N的无序序列分割平均分割为两段 2. 然后分别对前半段进行归并排序.后半段进行归并排序 3. 最后再将排序好的前半段和后半段归并 过程(2)中进行递归求解,最终下图详细的分解了自顶向下的合并算法的实现过程: 二. 算法实现 /*==============================

C++实现自底向上的归并排序算法_C 语言

本文实例讲述了C++实现自底向上的归并排序算法.分享给大家供大家参考,具体如下: 一. 算法描述 自底向上的归并排序:归并排序主要是完成将若干个有序子序列合并成一个完整的有序子序列:自底向上的排序是归并排序的一种实现方式,将一个无序的N长数组切个成N个有序子序列,然后再两两合并,然后再将合并后的N/2(或者N/2 + 1)个子序列继续进行两两合并,以此类推得到一个完整的有序数组.下图详细的分解了自底向上的合并算法的实现过程: 二. 算法实现 /*=========================

C语言实现冒泡排序算法_C 语言

BubblSort.c #include<stdio.h> void BubbleSort(int a[],int len) { int i; int j; int h; int temp; for(i=0;i<len-1;++i) { for(j=len-1;j>i;--j) { if(a[j]<a[j-1]) { temp=a[j]; a[j]=a[j-1]; a[j-1]=temp; } } for(h=0;h<len;h++) { printf(" %

C语言实现斗地主的核心算法_C 语言

数据结构只选择了顺序表,没有选择链表,灵活性和抽象性不足,不能普适. head.h #ifndef __HEAD_H__ #define __HEAD_H__ #define MAXLEVEL 15 typedef struct CARD{ int number; int level; char *flower; char point; }card;//卡 typedef struct DECK{ int top; int arr[55]; }deck;//牌堆 typedef struct P

C++实现N个骰子的点数算法_C 语言

本文实例讲述了C++实现N个骰子的点数算法,分享给大家供大家参考之用.具体方法如下: 题目要求:把n个骰子仍在地上,所有点数 实现代码如下: #include <iostream> using namespace std; const int g_maxValue = 6; const int number = 6; int array[(number - 1) * g_maxValue + 1]; void probility(int original, int current, int s

C语言实现字符串匹配KMP算法_C 语言

字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"? 下面的的KMP算法的解释步骤 1. 首先,字符串"BBC ABCDAB ABCDABCDABDE"的第一个字符与搜索词"ABCDABD"的第一个字符,进行比较.因为B与A不匹配,所以搜索词后移一位. 2. 因为B与A不匹配,搜索词再往后移. 3. 就这样,直到字符

字典树的基本知识及使用C语言的相关实现_C 语言

概念      如果我们有and,as,at,cn,com这些关键词,那么trie树(字典树)是这样的:      从上面的图中,我们或多或少的可以发现一些好玩的特性.       第一:根节点不包含字符,除根节点外的每一个子节点都包含一个字符.       第二:从根节点到某一节点,路径上经过的字符连接起来,就是该节点对应的字符串.       第三:每个单词的公共前缀作为一个字符节点保存.   使用范围      既然学Trie树,我们肯定要知道这玩意是用来干嘛的.      第一:词频统计

举例讲解C语言对归并排序算法的基础使用_C 语言

基础概念百度百科是这么描述归并排序的: 归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作. 设有数列 {6,202,100,301,38,8,1} 初始状态: [6] [202] [100] [301] [38] [8] [1] 比较次数  i=1 [6 202 ] [ 100 301] [ 8 38] [ 1 ] 3 i=2 [ 6 100 202 301 ] [ 1 8 38 ] 4 i=3 [ 1 6 8 38 100 202 301 ] 4 总计: 1

c++中八大排序算法_C 语言

概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序.堆排序或归并排序序. 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短:  1.插入排序-直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入