算法导论思考题6-3:Young氏矩阵

问题描述:
Young氏矩阵,每一行的数据从左到右递增序,从上到下递增序。
算法实现:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "RANDOMIZE_IN_PLACE.h"

typedef struct youngTableau {
    int rows, cols;
    int *head;
} young_t;

typedef struct {
    int row, col;
} location;

location up(location loc) {
    location l;
    l.row = loc.row - 1;
    l.col = loc.col;
    return l;
}

location down(location loc) {
    location l;
    l.row = loc.row + 1;
    l.col = loc.col;
    return l;
}

location right(location loc) {
    location l;
    l.row = loc.row;
    l.col = loc.col + 1;
    return l;
}

location left(location loc) {
    location l;
    l.row = loc.row;
    l.col = loc.col - 1;
    return l;
}

int is_equal(location loc1, location loc2) {
    return loc1.row == loc2.row && loc1.col == loc2.col;
}

int is_valid(young_t young, location loc) {
    if (loc.row >= 1 && loc.row <= young.rows && loc.col >= 1 && loc.col <= young.cols)
        return 1;
    return 0;
}

int get(young_t young, location loc) {
    if (!is_valid(young, loc)) {
        fprintf(stderr, "error location (%d, %d)\n", loc.row, loc.col);
        return INT_MIN;
    }
    return young.head[young.cols * (loc.row - 1) + loc.col - 1];
}

void set(young_t young, location loc, int key) {
    if (!is_valid(young, loc)) {
        fprintf(stderr, "error location (%d, %d)\n", loc.row, loc.col);
        return;
    }
    young.head[young.cols * (loc.row - 1) + loc.col - 1] = key;
}

void swap(young_t young, location loc1, location loc2) {
    int temp = get(young, loc1);
    set(young, loc1, get(young, loc2));
    set(young, loc2, temp);
}

void printYoung(young_t young) {
    for (int i = 1; i <= young.rows; i++) {
        for (int l = 1; l <= young.cols; l++) {
            location loc = {i, l};
            printf("%10d ", get(young, loc));
        }
        printf("\n");
    }
    printf("---------------------------------------\n");
}

void youngify(young_t young, location loc) {
    location min = loc;
    if (is_valid(young, down(loc)) && get(young, down(loc)) < get(young, min)) {
        min = down(loc);
    }
    if (is_valid(young, right(loc)) && get(young, right(loc)) < get(young, min)) {
        min = right(loc);
    }
    if (is_equal(min, loc))
        return;
    swap(young, loc, min);
    youngify(young, min);
}

void build_young(young_t young) {
    for (int i = young.rows; i > 0; i--) {
        for (int k = young.cols; k > 0; k--) {
            location loc = {i, k};
            youngify(young, loc);
            //printf("%d %d\n", i, k);
            //printYoung(young);
        }
    }
}

void init_young(young_t *young, int row, int col) {
    young->rows = row;
    young->cols = col;
    young->head = (int*)calloc(row * col, sizeof(int));
    for (int i = 0; i < col * row; i++) {
        young->head[i] = INT_MAX;
    }
    build_young(*young);
}

void random_init_young(young_t * young, int row, int col) {
    young->rows = row;
    young->cols = col;
    young->head = (int*)calloc(row * col, sizeof(int));
    for (int i = 0; i < col * row; i++) {
        young->head[i] = i;
    }
    randomize_in_place(young->head, row * col);
    build_young(*young);
}

int extract_min(young_t young) {
    location loc = {1, 1};
    int min = get(young, loc);
    set(young, loc, INT_MAX);
    youngify(young, loc);
    return min;
}

void young_sort(young_t young, int ** result) {
    build_young(young);
    *result = (int*)calloc(young.rows * young.cols, sizeof(int));
    for (int i = 0; i < young.rows * young.cols; ++i) {
        (*result)[i] = extract_min(young);
    }
}

void insert(young_t young, int key) {
    location loc;
    int empty = 0;
    for (int i = young.rows; i > 0 && !empty; i--) {
        for (int k = young.cols; k > 0 && !empty; k--) {
            loc.row = i;
            loc.col = k;
            if (get(young, loc) == INT_MAX)
                empty = 1;
        }
    }
    if (!empty) {
        fprintf(stderr, "young tableau is full\n");
        return;
    }
    set(young, loc, key);
    location max = loc;
    while (loc.col != 0 || loc.row != 0) {
        if (is_valid(young, up(loc)) && get(young, up(loc)) > get(young, max)) {
            max = up(loc);
        }
        if (is_valid(young, left(loc)) && get(young, left(loc)) > get(young, max)) {
            max = left(loc);
        }
        if (is_equal(max, loc))
            return;
        swap(young, max, loc);
        loc = max;
    }
}

location find(young_t young, int key) {
    location loc = {young.rows, 1};
    while (is_valid(young, loc)) {
        if (get(young, loc) < key) {
            loc = right(loc);
        } else if (get(young, loc) == key) {
            return loc;
        } else if (get(young, loc) > key) {
            loc = up(loc);
        }
    }
    fprintf(stderr, "no such key %d in this young tableau\n", key);
    return loc;
}


int main(int argc, char const *argv[])
{
    young_t young;
    random_init_young(&young, 3, 4);
    printYoung(young);
    int key = 9;
    location loc = find(young, key);
    printf("key %d is at location (%d, %d)\n", key, loc.row, loc.col);
    /*int * result;
    young_sort(young, &result);
    for (int i = 0; i < 12; i++) {
        printf("%d ", result[i]);
    }
    printf("\n");
    printYoung(young);*/

    /*int min = extract_min(young);
    printYoung(young);
    printf("min:%d\n", min);
    min = extract_min(young);
    printYoung(young);
    printf("min:%d\n", min);

    insert(young, 9);
    printYoung(young);*/
    return 0;
}

详细说明见:算法导论思考题6-3答案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值