堆排序(非递归)

以下代码经测试,排序5000000(五千万)int型数据没有问题!

第一个参数是数组首地址
第二个参数是数组元素个数
void HeapSort(int * const arr, const DWORD number)//堆排序
{
    int tmp;
    DWORD tmpIndex;
    DWORD i=1;
    DWORD num;
    DWORD indexUp;
    DWORD indexDown;
    if (number < 2)
    {
        return;
    }
    indexUp = number-1;
    if (0 != (indexUp%2))
    {
        tmpIndex = (indexUp - 1) / 2;
        if (arr[indexUp] > arr[tmpIndex])
        {
            tmp = arr[indexUp];
            arr[indexUp] = arr[tmpIndex];
            arr[tmpIndex] = tmp;
        }
        indexUp--;
    }
    for (; indexUp>0; indexUp-=2)
    {
        tmpIndex = (indexUp / 2) - 1;
        if (arr[indexUp-1] >= arr[indexUp])
        {
            if (arr[indexUp-1] > arr[tmpIndex])
            {
                tmp = arr[indexUp-1];
                arr[indexUp-1] = arr[tmpIndex];
                arr[tmpIndex] = tmp;
                indexDown = indexUp-1;
            }
            else
            {
                continue;
            }
        }
        else
        {
            if (arr[indexUp] > arr[tmpIndex])
            {
                tmp = arr[indexUp];
                arr[indexUp] = arr[tmpIndex];
                arr[tmpIndex] = tmp;
                indexDown = indexUp;
            }
            else
            {
                continue;
            }
        }
        while ((2*indexDown) < number)
        {
            tmpIndex = 2*indexDown +1;
            if (arr[tmpIndex] >= arr[tmpIndex+1] || (tmpIndex+1 == number))
            {
                if (arr[tmpIndex] > arr[indexDown])
                {
                    tmp = arr[indexDown];
                    arr[indexDown] = arr[tmpIndex];
                    arr[tmpIndex] = tmp;
                    indexDown = tmpIndex;
                }
                else
                {
                    break;
                }
            }
            else
            {
                if ((arr[tmpIndex+1] > arr[indexDown]) && (tmpIndex < number))
                {
                    tmp = arr[indexDown];
                    arr[indexDown] = arr[tmpIndex+1];
                    arr[tmpIndex+1] = tmp;
                    indexDown = tmpIndex+1;
                }
                else
                {
                    break;
                }
            }
        }
    }
    tmp = arr[0];
    arr[0] = arr[number-1];
    arr[number-1] = tmp;

    for (num=number-1; num>1; num--)
    {
        for (indexDown=0; (2*indexDown +1) < num; )
        {
            tmpIndex = 2*indexDown +1;
            if (arr[tmpIndex] >= arr[tmpIndex+1])
            {
                if (arr[tmpIndex] > arr[indexDown])
                {
                    tmp = arr[indexDown];
                    arr[indexDown] = arr[tmpIndex];
                    arr[tmpIndex] = tmp;
                    indexDown = tmpIndex;
                }
                else
                {
                    break;
                }
            }
            else
            {
                if ((arr[tmpIndex+1] > arr[indexDown]) && (tmpIndex+1 < num))
                {
                    tmp = arr[indexDown];
                    arr[indexDown] = arr[tmpIndex+1];
                    arr[tmpIndex+1] = tmp;
                    indexDown = tmpIndex+1;
                }
                else
                {
                    break;
                }
            }
        }
        tmp = arr[0];
        arr[0] = arr[num-1];
        arr[num-1] = tmp;
    }
}

测试代码:
#include <stdio.h>
#include <conio.h>
#include <windows.h>

void HeapSort(int * const arr, const DWORD number);//堆排序
void ExamineArr(const int * const arr, DWORD number);//检查排序结果

int main(int argc, char *argv[])
{
    DWORD StartTime, EndTime;
    DWORD i;
    DWORD num = 50000000;
    int *arr = NULL;
    arr = (int *)malloc(num * sizeof (int));
    if (NULL == arr)
    {
        free(arr);
        printf("内存分配失败,程序退出!\n");
        getch();
        return -1;
    }

    StartTime = GetTickCount();
    for (i=0; i<num; i++)
    {
        *(arr+i) = rand();
    }
    EndTime = GetTickCount();
    printf("生成%u个随机数耗时:%ums\n", num, EndTime - StartTime);
    
    StartTime = GetTickCount();
    HeapSort(arr, num);
    EndTime = GetTickCount();
    printf("堆排序耗时:%ums\n", EndTime - StartTime);
    ExamineArr(arr, num);//检查排序结果

    free(arr);
    getch();
    return 0;
}

void HeapSort(int * const arr, const DWORD number)//堆排序
{
    int tmp;
    DWORD tmpIndex;
    DWORD i=1;
    DWORD num;
    DWORD indexUp;
    DWORD indexDown;
    if (number < 2)
    {
        return;
    }
    indexUp = number-1;
    if (0 != (indexUp%2))
    {
        tmpIndex = (indexUp - 1) / 2;
        if (arr[indexUp] > arr[tmpIndex])
        {
            tmp = arr[indexUp];
            arr[indexUp] = arr[tmpIndex];
            arr[tmpIndex] = tmp;
        }
        indexUp--;
    }
    for (; indexUp>0; indexUp-=2)
    {
        tmpIndex = (indexUp / 2) - 1;
        if (arr[indexUp-1] >= arr[indexUp])
        {
            if (arr[indexUp-1] > arr[tmpIndex])
            {
                tmp = arr[indexUp-1];
                arr[indexUp-1] = arr[tmpIndex];
                arr[tmpIndex] = tmp;
                indexDown = indexUp-1;
            }
            else
            {
                continue;
            }
        }
        else
        {
            if (arr[indexUp] > arr[tmpIndex])
            {
                tmp = arr[indexUp];
                arr[indexUp] = arr[tmpIndex];
                arr[tmpIndex] = tmp;
                indexDown = indexUp;
            }
            else
            {
                continue;
            }
        }
        while ((2*indexDown) < number)
        {
            tmpIndex = 2*indexDown +1;
            if (arr[tmpIndex] >= arr[tmpIndex+1] || (tmpIndex+1 == number))
            {
                if (arr[tmpIndex] > arr[indexDown])
                {
                    tmp = arr[indexDown];
                    arr[indexDown] = arr[tmpIndex];
                    arr[tmpIndex] = tmp;
                    indexDown = tmpIndex;
                }
                else
                {
                    break;
                }
            }
            else
            {
                if ((arr[tmpIndex+1] > arr[indexDown]) && (tmpIndex < number))
                {
                    tmp = arr[indexDown];
                    arr[indexDown] = arr[tmpIndex+1];
                    arr[tmpIndex+1] = tmp;
                    indexDown = tmpIndex+1;
                }
                else
                {
                    break;
                }
            }
        }
    }
    tmp = arr[0];
    arr[0] = arr[number-1];
    arr[number-1] = tmp;

    for (num=number-1; num>1; num--)
    {
        for (indexDown=0; (2*indexDown +1) < num; )
        {
            tmpIndex = 2*indexDown +1;
            if (arr[tmpIndex] >= arr[tmpIndex+1])
            {
                if (arr[tmpIndex] > arr[indexDown])
                {
                    tmp = arr[indexDown];
                    arr[indexDown] = arr[tmpIndex];
                    arr[tmpIndex] = tmp;
                    indexDown = tmpIndex;
                }
                else
                {
                    break;
                }
            }
            else
            {
                if ((arr[tmpIndex+1] > arr[indexDown]) && (tmpIndex+1 < num))
                {
                    tmp = arr[indexDown];
                    arr[indexDown] = arr[tmpIndex+1];
                    arr[tmpIndex+1] = tmp;
                    indexDown = tmpIndex+1;
                }
                else
                {
                    break;
                }
            }
        }
        tmp = arr[0];
        arr[0] = arr[num-1];
        arr[num-1] = tmp;
    }
}

void ExamineArr(const int * const arr, DWORD number)
{
    DWORD i=0, j=1;
    if (number <2)
    {
        return;
    }
    for (; j<number; i++,j++)
    {
        if (arr[i] > arr[j])
        {
            printf("第%u个数大于第%u个数!\n", i, j);
            return;
        }
    }
}


### Python 实现非递归堆排序 堆排序是一种基于比较的高效排序算法,其核心思想是利用二叉堆数据结构完成数组的最大值提取操作。为了实现非递归版的堆排序,可以按照以下逻辑构建代码。 #### 堆排序的核心思想 堆排序分为两个主要阶段:建堆和调整堆。 1. **建堆**:将输入列表构建成一个最大堆(或最小堆)。在此过程中,父节点始终大于等于子节点。 2. **调整堆**:通过不断移除根节点并重新调整剩余部分为新的堆,逐步得到有序序列。 以下是具体的非递归实现方式: ```python def heapify_non_recursive(arr, n, i): """ 非递归调整堆 """ largest = i # 初始化当前节点为最大的索引 left_child = 2 * i + 1 # 左孩子节点索引 right_child = 2 * i + 2 # 右孩子节点索引 while True: if left_child < n and arr[left_child] > arr[largest]: largest = left_child if right_child < n and arr[right_child] > arr[largest]: largest = right_child if largest != i: # 如果最大值不是当前节点,则交换它们 arr[i], arr[largest] = arr[largest], arr[i] i = largest # 更新左孩子和右孩子的索引 left_child = 2 * i + 1 right_child = 2 * i + 2 else: break def heap_sort_non_recursive(arr): """ 使用非递归方法实现堆排序 """ n = len(arr) # 构建初始最大堆 for i in range(n // 2 - 1, -1, -1): heapify_non_recursive(arr, n, i) # 提取元素并重建堆 for i in range(n - 1, 0, -1): arr[0], arr[i] = arr[i], arr[0] # 将当前最大值移到最后 heapify_non_recursive(arr, i, 0) # 调整剩下的堆 # 测试代码 if __name__ == "__main__": data = [4, 10, 3, 5, 1] print("原始数组:", data) heap_sort_non_recursive(data) print("排序后的数组:", data) ``` #### 关键点解析 上述代码实现了堆排序的关键功能,并采用非递归的方式完成了 `heapify` 过程。具体说明如下: - 函数 `heapify_non_recursive` 是用来维护堆性质的核心函数,在循环中持续检查父子节点的关系并进行必要的交换[^3]。 - 初始堆化过程从最后一个非叶子节点开始向上逐层处理,确保整个树满足最大堆的要求。 - 排序阶段每次都将堆顶元素(最大值)移动到数组末尾,并缩小堆的有效范围,随后再次调用 `heapify_non_recursive` 来恢复堆属性。 此实现的空间复杂度保持在 \(O(1)\),因为所有的操作都在原数组上执行,无需额外分配内存空间。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值