手写堆排序和归并排序

1. 堆排序

/*
 * 手动实现堆排序, 使用大根堆实现 从小到大排序
 */

// 完成在数组[low, high]的范围内,对在位置low上的节点向下进行调整
void shift(int nums[], int low, int high) {
    int i = low;
    int j = i*2;
    int tmp = nums[i];
    while(j<=high) {
        // 比较当前节点的左、右儿子
        if(j<high && nums[j]<nums[j+1])
            j++; //如果右儿子较大则让j指向较大的儿子节点的下标
        if(tmp < nums[j]) {
            nums[i] = nums[j];
            i = j;
            j = i*2;
        } else
            break;
    }
    nums[i] = tmp;
}
void heap_sort(int nums[], int n) {
    int tmp;
    // 建立初始化的堆, 从第一个非叶子结点进行调整
    for(int i=n/2; i>=1; i--) {
        shift(nums, i, n);
    }
    // 进行n-1次循环, 完成堆排序, 把堆顶元素放到后面
    for(int i=n; i>=2; i--) {
        tmp = nums[1];
        nums[1] = nums[i];
        nums[i] = tmp;
        shift(nums, 1, i-1);
    }

}

int main()
{
    int n;
    scanf("%d", &n);
    int nums[100];

    // 读入n个数据, 堆一棵完全二叉树,必须从1开始存储
    for(int i=1; i<=n; i++) {
        scanf("%d", &nums[i]);
    }

    // 进行堆排序
    heap_sort(nums, n);
    
    // 打印排序后的数组 
    for(int i=1; i<=n; i++) {
        printf("%d ", nums[i]);
    }
    return 0;
}    

 

2. 归并排序

/*
 * 实现二路归并排序
 */

// 合并函数:原数组、辅助数组、开始下标,中间下标、结束下标 void Merge(int sourceArray[], int tempArray[], int s, int mid, int t) { int i = s; int j = mid+1; int k = s; while(i<=mid && j<=t) { if(sourceArray[i] <= sourceArray[j]) tempArray[k++] = sourceArray[i++]; else tempArray[k++] = sourceArray[j++]; } while(i<=mid) tempArray[k++] = sourceArray[i++]; while(j<=t) tempArray[k++] = sourceArray[j++]; for(i=s; i<=t; i++) sourceArray[i] = tempArray[i]; } // 原数组,辅助数组,开始下标,结束下标 void MergeSort(int sourceArray[],int tempArray[],int s,int t) { if(s<t) { int mid = (s+t)>>1; // 递归排序左边 MergeSort(sourceArray,tempArray,s,mid); // 递归排序右边 MergeSort(sourceArray,tempArray,mid+1,t); // 合并 Merge(sourceArray,tempArray,s,mid,t); } }

 

posted @ 2020-05-09 12:39  我喜欢旅行  阅读(314)  评论(0)    收藏  举报