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