归并排序

归并排序

时间算法度 Θ ( n l g n ) Θ\left(nlgn\right) Θ(nlgn)


该算法主旨
归并排序算法完全遵照分治模式得三个步骤:

  • 分解:分解待排序得 n n n个元素的序列,使其成为各具 n / 2 n/2 n/2个元素的两个子序列。
  • 解决:使用归并排序递归地排序两个子序列。
  • 合并:合并两个已排序的子序列以产生已排序的答案。

当待排序的序列长度为 1 1 1时,递归"开始回升",因为长度为 1 1 1的序列都已排好序(或者说时不需要排序)


伪代码

/* —————————————————————————————————————————————————— 
 * 首先,我们需要一个合并两个序列的函数。 
 * 它将按照顺序合并两个子序列中的元素。 
 * 
 * 这里我们假设这两个需要合并的序列一定是已经排好序的。 
 * —————————————————————————————————————————————————— */
MERGE(A, front, middle, back)
1   Number_1 = middle - front + 1
2   Number_2 = back - middle
3   声明一个动态数组B,分配内存数量为Number_1
4   声明一个动态数组C,分配内存数量为Number_2
5   for i = 1 to Number_1
6       B[i] = A[i + Front - 1]
7   for i = 1 to Number_2
8       C[i] = A[middle + i]
9   i = 1
10  j = 1
11  for k = front to back
12      if j > Number_2 or i <= Number_1 and B[i] < C[j]
13          A[k] = B[i]
14          i = i + 1
15      else
16          A[k] = C[j]
17          j = j + 1


/* —————————————————————————————————————————————————— 
 * 我们按照分治法来递归分解序列 
 * —————————————————————————————————————————————————— */
MERGE-SORT(A, front, back)
1   if back - front == 0
2       return
3   MERGE-SORT(A, front, (back + front) / 2)
4   MERGE-SORT(A, (back + front) / 2 + 1, back)
5   MERGE(A, front, (back + front) / 2, back)

C++代码

void MERGE(int* A, int front, int middle, int back)
{    
    int Number_1 = middle - front + 1;    
    int Number_2 = back - middle;
    
    int* B = new int[Number_1];    
    int* C = new int[Number_2];
    
    for (int i = 0; i < Number_1; i++)        
        B[i] = A[front + i];    
        
    for (int i = 0; i < Number_2; i++)        
        C[i] = A[middle + i + 1];
        
    for (int i = 0, j = 0, k = front; k <= back; k++)    
    {        
        if (j >= Number_2 || (i < Number_1 && B[i] < C[j]))        
        {            
            A[k] = B[i];            
            i++;        
        }        
        else        
        {            
            A[k] = C[j];            
            j++;        
        }    
    }
    
    delete[] B, C;
}

void MERGE_SORT(int* A, int front, int back)
{    
    if (back - front == 0)
        return;
        
    MERGE_SORT(A, front, (back + front) / 2);    
    MERGE_SORT(A, (back + front) / 2 + 1, back);    
    MERGE(A, front, (back + front) / 2, back);
}

测试代码

#include <iostream>

constexpr std::size_t N = 10;

// 声明合并函数
void MERGE(int* A, int front, int middle, int back);

// 声明归并算法函数
void MERGE_SORT(int* A, int front, int back);

int main(void)
{   
    int A[N]{ 3, 2, 5, 3, 7, 1, 8, 0, 9, 4 };
    
    MERGE_SORT(A, 0, N - 1);
    
    for (int a : A)        
    	std::cout << a << " ";    
    std::cout << std::endl;
    
    return 0;
}

// 定义合并函数
void MERGE(int* A, int front, int middle, int back)
{    
    int Number_1 = middle - front + 1;    
    int Number_2 = back - middle;
    
    int* B = new int[Number_1];    
    int* C = new int[Number_2];
    
    for (int i = 0; i < Number_1; i++)        
        B[i] = A[front + i];    
        
    for (int i = 0; i < Number_2; i++)        
        C[i] = A[middle + i + 1];
        
    for (int i = 0, j = 0, k = front; k <= back; k++)    
    {    
        if (j >= Number_2 || (i < Number_1 && B[i] < C[j]))        
        {            
            A[k] = B[i];            
            i++;        
        }        
        else        
        {            
            A[k] = C[j];            
            j++;        
        }    
    }
    
    delete[] B, C;
}

// 定义归并算法函数
void MERGE_SORT(int* A, int front, int back)
{        
    if (back - front == 0)        
        return;            
    MERGE_SORT(A, front, (back + front) / 2);        
    MERGE_SORT(A, (back + front) / 2 + 1, back);        
    MERGE(A, front, (back + front) / 2, back);
}

/* ————————————————————————————————————————————————————— 
 * 输出结果: 
 * 0 1 2 3 3 4 5 7 8 9 
 * —————————————————————————————————————————————————————— */
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值