归并排序(merge sort)

这篇博客介绍了一种使用C++实现的归并排序算法,通过AMergesort类展示了如何将两个有序数组合并成一个有序数组。代码包括了初始化随机数组、检查数组排序、归并操作以及整个排序过程。博主通过打印数组来验证排序前后的顺序,从而展示算法的正确性。
摘要由CSDN通过智能技术生成

将两个有序表合并成一个有序表,称为二路归并。

.h:

UCLASS()
class ALGORITHM_API AMergesort : public AActor
{
    GENERATED_BODY()
    
public:    
    // Sets default values for this actor's properties
    AMergesort();
    // Called every frame
    virtual void Tick(float DeltaTime) override;
    //生成数组
    void InitArray(int N);
    //检测这部分的数组是否有序
    void IsSorted(int MinIndex, int MaxIndex);
    //归并排序(MergeSort),输入辅助数组及此部分数组的最小id、中间Id、最大id
    void Merge(TArray<int> AuArray, int lo, int mid, int hi);
    //开始排序
    void Sort();
    void Sort(TArray<int> AuArray, int lo, int hi);

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:    
    //目标数组
    TArray<int> MyIntArray;
};

.cpp:

// Sets default values
AMergesort::AMergesort()
{
     // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void AMergesort::BeginPlay()
{
    Super::BeginPlay();
    //测试
    //生成数组
    InitArray(10000);
    UKismetSystemLibrary::PrintString(this, "Before Sort: ");
    for (int i = 0; i < MyIntArray.Num(); i++)
    {
        UKismetSystemLibrary::PrintString(this, FString::FromInt(i) + " : " + FString::FromInt(MyIntArray[i]));
    }
    //开始排序
    Sort();
    UKismetSystemLibrary::PrintString(this, "After Sort: ");
    for (int i = 0; i < MyIntArray.Num(); i++)
    {
        UKismetSystemLibrary::PrintString(this, FString::FromInt(i) + " : " + FString::FromInt(MyIntArray[i]));
    }
}

// Called every frame
void AMergesort::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

}
//生成随机数组
void AMergesort::InitArray(int N)
{
    FRandomStream Stream;
    Stream.GenerateNewSeed();
    for (int i = 0; i < N; i++)
    {
        MyIntArray.Add(Stream.RandRange(0, 100));
    }
}

void AMergesort::IsSorted(int MinIndex, int MaxIndex)
{
    //这部分数组应该在整个数组之内
    if (MaxIndex > MyIntArray.Num() || MinIndex > MyIntArray.Num()) return;
    //检测数组
    for (int i = MinIndex; i < MaxIndex - 2; i++)
    {
        //如果有序,前一项应该小于等于后一项
        if (MyIntArray[i] > MyIntArray[i + 1])
        {
            UKismetSystemLibrary::PrintString(this, " Error: UnOrder");
            return;
        }
    }
}
//合并部分数组
void AMergesort::Merge(TArray<int> AuArray, int lo, int mid, int hi)
{
    //先检测前半段和后半段是否都是有序的
    IsSorted(lo, mid);
    IsSorted(mid + 1, hi);
    //把这一部分数组拷贝给辅助数组
    for (int k = lo; k <= hi; k++)
    {
        AuArray[k] = MyIntArray[k];
    }
    //前半段和后半段的起始序号
    int i = lo; 
    int j = mid + 1;
    for (int k = lo; k <= hi; k++)
    {
        //如果前半段已经没有了,则把后半段直接加上去
        //PS:MyIntArray[k] = AuArray[j++]等效于MyIntArray[k] = AuArray[j]; j++;
        if (i > mid) MyIntArray[k] = AuArray[j++];
        //如果后半段已经没有了,则把前半段直接加上去
        else if (j > hi) MyIntArray[k] = AuArray[i++];
        //如果i项元素比j项元素大,则取j项元素
        else if (AuArray[i] > AuArray[j]) MyIntArray[k] = AuArray[j++];
        //否则取i项元素
        else MyIntArray[k] = AuArray[i++];
    }
    //检查数组排序有没问题
    IsSorted(lo, hi);
}
//开始排序
void AMergesort::Sort()
{
    //创造一个与目标数组同等大小的辅助数组
    TArray<int> AuArray;
    AuArray.Init(0, MyIntArray.Num());
    Sort(AuArray, 0, MyIntArray.Num() - 1);
}

void AMergesort::Sort(TArray<int> AuArray, int lo, int hi)
{
    if (hi <= lo) return;
    //处于中间的元素的ID
    int mid = lo + (hi - lo) / 2;
    //把前半段不停地分割成两部分,然后从最小的部分开始合并,最后得到有序的前半部分
    Sort(AuArray, lo, mid);
    //把后半段不停地分割成两部分,然后从最小的部分开始合并,最后得到有序的后半部分
    Sort(AuArray, mid + 1, hi);
    //最后把前半部分和后半部分合并,得到有序的数组,排序完成
    Merge(AuArray, lo, mid, hi);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梖梖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值