Page 186, Exercise 7
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 25
typedef enum {head,entry} tagfield;
typedef struct MatrixNode *MatrixPointer;
struct EntryNode {
int row;
int col;
int value;
};
struct MatrixNode {
MatrixPointer down;
MatrixPointer right;
tagfield tag;
union {
MatrixPointer next;
struct EntryNode entry;
} u;
};
MatrixPointer HdNode[MAX_SIZE];
MatrixPointer mread(void);
void mwrite(MatrixPointer);
void merase(MatrixPointer *node);
int main()
{
MatrixPointer a,b,c;
a = mread();
mwrite(a);
merase(&a);
if (!a)
printf("The matrix has been erased.\n");
}
MatrixPointer mread(void)
{/* read in a matrix and set up its linked representation.
An auxilliary global array HdNode is used */
int NumRows, NumCols, NumEntries, NumHeads, i;
int row, col, value, CurrentRow;
MatrixPointer temp,last,node;
printf("Enter the number of rows, columns and entries: ");
scanf("%d,%d,%d",&NumRows, &NumCols, &NumEntries);
NumHeads = (NumCols > NumRows) ? NumCols : NumRows;
/* set up head node for the list of head nodes */
node = (MatrixPointer)malloc(sizeof(struct MatrixNode));
node->tag = entry;
node->u.entry.row = NumRows;
node->u.entry.col = NumCols;
if (!NumHeads)
node->right = node;
else {
/* initialize the head nodes */
for (i = 0; i < NumHeads; i++) {
temp = (MatrixPointer)malloc(sizeof(struct MatrixNode));
HdNode[i] = temp;
HdNode[i]->tag = head;
HdNode[i]->right = temp;
HdNode[i]->u.next = temp;
}
CurrentRow = 0;
last = HdNode[0];
for (i = 0; i < NumEntries; i++) {
printf("Enter row, column and value: ");
scanf("%d,%d,%d",&row,&col,&value);
if (row > CurrentRow) {
last->right = HdNode[CurrentRow];
CurrentRow = row;
last = HdNode[row];
}
temp = (MatrixPointer)malloc(sizeof(struct MatrixNode));
temp->tag = entry;
temp->u.entry.row = row;
temp->u.entry.col = col;
temp->u.entry.value = value;
last->right = temp; /* link into row list */
last = temp;
HdNode[col]->u.next->down = temp; /* link into column list */
HdNode[col]->u.next = temp;
}
/*close last row */
last->right = HdNode[CurrentRow];
/* close all column lists */
for (i = 0; i < NumCols; i++)
HdNode[i]->u.next->down = HdNode[i];
/* link all head nodes together */
for (i = 0; i < NumHeads-1; i++)
HdNode[i]->u.next = HdNode[i+1];
HdNode[NumHeads-1]->u.next = node;
node->right = HdNode[0];
}
return node;
}
void mwrite(MatrixPointer node)
{
/* print out the matrix in row major form */
int i;
MatrixPointer temp;
/* matrix dimensions */
printf("\n\nNumRows = %d, NumCols = %d\n",node->u.entry.row,
node->u.entry.col);
printf(" The matrix by row, column, and value: \n\n");
for (i = 0; i < node->u.entry.row; i++)
/* print out the entries in each row */
for (temp = HdNode[i]->right; temp != HdNode[i]; temp = temp->right)
printf("%5d%5d%5d\n",temp->u.entry.row,temp->u.entry.col,
temp->u.entry.value);
}
void merase(MatrixPointer *node)
{
/* erase the matrix, return the pointers to the heap */
MatrixPointer x,y;
int i, NumHeads;
/* free the entry pointers by row */
for (i = 0; i < (*node)->u.entry.row; i++) {
y = HdNode[i]->right;
while (y != HdNode[i]) {
x = y;
y = y->right;
free(x);
}
}
/* determine the number of head nodes and free these pointers */
NumHeads = ((*node)->u.entry.row > (*node)->u.entry.col) ?
(*node)->u.entry.row : (*node)->u.entry.col;
for (i = 0; i < NumHeads; i++)
free(HdNode[i]);
*node = NULL;
} |