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

来源:互联网 发布:淘宝美工字体库百度云 编辑:程序博客网 时间:2024/05/24 00:46

问题描述:
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答案