数据结构与算法---复习:直接选择排序 堆排序

数据结构与算法—复习:直接选择排序 堆排序

/**
 * 程序说明:复习 直接选择排序
 */
#include <stdio.h>
#include <malloc.h>


struct RecordNode {
    int key;    //排序关键码
    char info;  //记录信息
};    //“记录”类型
typedef struct RecordNode* PRecordNode;

struct SortObject{
    int n;  //“记录”的总数
    PRecordNode record; //记录表类型
};    //排序目标
typedef struct SortObject* PSortObject;

/**
 * 插入排序 创建记录表
 * @param m
 * @return
 */
PSortObject createEmptySortObject(int m){
    PSortObject pvector = (PSortObject)malloc(sizeof(struct SortObject));
    if(pvector != NULL){
        pvector->record = (PRecordNode)malloc(sizeof(PRecordNode) * m);
        if(pvector->record){
            pvector->n = m;
            return pvector;
        }
        printf("分配记录表时出错\n");
        return pvector;
    }
    printf("分配排序目标时出错\n");
    return pvector;
}


/**
 * 插入排序 初始化数据
 * @param pvector
 * @param info
 * @param key
 * @param n
 */
void init(PSortObject pvector,char* info,int* key,int n){
    pvector->n = n;
    for (int i = 0; i < n; ++i) {
        pvector->record[i].info = info[i];
        pvector->record[i].key = key[i];
    }
}

/**
 * 插入排序 规格化打印
 * @param pvector
 */
void printRecord(PSortObject pvector){
    for (int i = 0; i < pvector->n; ++i) {
        printf("[%d,%c] ",pvector->record[i].key,pvector->record[i].info);
        if(i + 1 == pvector->n){
            printf("\n");
        }
    }
}

/**
 * 直接选择排序5
 * @param pvector
 */
void selectSort(PSortObject pvector){
    int i,j,    //两个游标
        min;    //最小值下标
    struct RecordNode temp; //暂存器
    for (i = 0; i < pvector->n - 1; ++i) {  //对于n个元素,选择排序要选择 n-1个
        min = i;    //首先让最小下标指向“仍未排序”的第一个元素
        for (j = i; j < pvector->n; ++j) {  //从这个元素开始,寻找一个key小于该元素的结点
            if(pvector->record[j].key < pvector->record[min].key){
                min = j;    //迭代更新最小下标
            }
        }
        if(i != min){   //i != min 证明最小的元素不是“仍未排序”的第一个元素 所以需要交换
            temp = pvector->record[i];
            pvector->record[i] = pvector->record[min];
            pvector->record[min] = temp;
        }
    }
}

/**
 * 将一颗二叉树 变为 大根堆
 * @param pvector
 * @param size  调整树的大小
 * @param p 待调整结点
 */
void sift(PSortObject pvector,int size,int p){
    int ch = 2 * p + 1; //确定待调整结点的左孩子
    struct RecordNode temp = pvector->record[p];    //缓存
    while (ch < size){  //当孩子下标 小于 树大小的时候,持续调整,保证结果正确
        if(ch < (size - 1) && pvector->record[ch].key < pvector->record[ch+1].key){
            ch++;   //选出两个孩子中较大的孩子
        }
        if(temp.key < pvector->record[ch].key){ //如果父亲结点key 小于 孩子结点key 交换
            pvector->record[p] = pvector->record[ch];   //孩子结点上浮
            p = ch; ch = (2 * p) + 1;   //继续向下探索是否仍可以调整
        } else break;   //如果未执行调整,则没有继续探索的必要
    }
    pvector->record[p] = temp;  //temp点到达合适位置,插入
}

/**
 * 堆排序
 * @param pvector 
 */
void heapSort(PSortObject pvector){
    int i,  //游标
        n = pvector->n; //树的大小
    struct RecordNode temp; //暂存
    for (i = n/2-1; i>=0 ; i--) {   //从最后结点的父亲开始调整,得到大根堆
        sift(pvector,n,i);  //调用调整函数,传入要调整的父亲结点
    }
    for (i = pvector->n - 1; i > 0; --i) {
        //堆顶元素 与 最后元素交换
        temp = pvector->record[0];
        pvector->record[0] = pvector->record[i];
        pvector->record[i] = temp;  //最大元素放在了堆最后
        sift(pvector,n,0);  //对堆顶进行调整
    }
}

int main() {
    PSortObject pvector = createEmptySortObject(8);
    char info[] = {'i','q','c','v','h','k','p','t'};
    int key[] = {49,38,65,97,76,13,27,49};
    int size = sizeof(key) / sizeof(int);
    init(pvector,info,key,size);
    printRecord(pvector);
    heapSort(pvector);
    //selectSort(pvector);
    printRecord(pvector);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值