TP8
This commit is contained in:
parent
45f6092d0d
commit
04bb2bec3a
4
TP8/.gitignore
vendored
Normal file
4
TP8/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
*.a
|
||||
*.o
|
||||
main
|
||||
part2
|
27
TP8/Makefile
Normal file
27
TP8/Makefile
Normal file
|
@ -0,0 +1,27 @@
|
|||
all: main pdfs dots
|
||||
|
||||
main: main.c libtrees.a
|
||||
gcc $^ -o $@
|
||||
|
||||
part2: part2.c libtrees.a
|
||||
gcc $^ -o $@
|
||||
|
||||
%.o: %.c
|
||||
gcc -c $^ -o $@
|
||||
|
||||
lib%.a: %.o
|
||||
ar rcs $@ $^
|
||||
|
||||
pdfs: $(patsubst %.txt,%.pdf,$(shell ls samples/*.txt))
|
||||
dots: $(patsubst %.txt,%.dot,$(shell ls samples/*.txt))
|
||||
|
||||
samples/%.pdf: samples/%.dot
|
||||
dot -Tpdf $< -o $@
|
||||
|
||||
samples/%.dot: samples/%.txt part2
|
||||
./part2 $<
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -r lib*.a *.o samples/*.dot samples/*.pdf
|
35
TP8/main.c
Executable file
35
TP8/main.c
Executable file
|
@ -0,0 +1,35 @@
|
|||
/*Source Code From Laure Gonnord*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "trees.h"
|
||||
|
||||
|
||||
int main(){
|
||||
Tree mt1,mt2,mt3;
|
||||
mt1 = mkEmptyTree();
|
||||
mt2 = mkEmptyTree();
|
||||
|
||||
if (isEmpty(mt1)) printf("mt1 empty\n");
|
||||
mt3 = cons(42,mt1,mt2);
|
||||
print_lvr(mt3);
|
||||
|
||||
printf("\n -- \n");
|
||||
FILE* fp = fopen("samples/balanced.txt","r");
|
||||
/* FILE* fp = fopen("samples/unspecified.txt","r"); */
|
||||
/* FILE* fp = fopen("samples/degenerated.txt","r"); */
|
||||
|
||||
Tree abr1= mkEmptyTree();
|
||||
|
||||
load_tree(fp, &abr1);
|
||||
|
||||
//Only values
|
||||
print_lvr(abr1);
|
||||
printf("\n -- \n");
|
||||
//father->son
|
||||
print_rec_edges(abr1);
|
||||
printf("\n -- \n");
|
||||
|
||||
return 0;
|
||||
}
|
78
TP8/part2.c
Executable file
78
TP8/part2.c
Executable file
|
@ -0,0 +1,78 @@
|
|||
/*Source Code From Bernard Carré and Laure Gonnord */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "trees.h"
|
||||
|
||||
#define MAX_STRING 255
|
||||
|
||||
// Main -- Do not modify !
|
||||
|
||||
// iterate the process: load, print (Part 1) and then generate_dot (Part 2) on the n files_names
|
||||
void handle(int n, char *file_names[]);
|
||||
|
||||
// main - usage: main <file_name_1> <file_name_2> <file_name_3>...
|
||||
int main (int argc, char *argv[]) {
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: main <file_names (.txt files)>\n");
|
||||
} else {
|
||||
handle(argc-1, &argv[1]); // handle the files
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// utility: build a new file name dest from src whose extension is replaced by the parameter ext
|
||||
// for example : file.txt -> file.dot
|
||||
void build_name(char *src, char *dest, char *ext);
|
||||
|
||||
// iterate the process: load, print (Part 1) and then generate_dot (Part 2) on the n files_names
|
||||
void handle(int n, char *file_names[]) {
|
||||
Tree t;
|
||||
FILE *fp;
|
||||
int i;
|
||||
for (i=0; i<n; i++) {
|
||||
fp=fopen(file_names[i], "r");
|
||||
if (fp==NULL) {
|
||||
fprintf(stderr, "no such file, or unreachable: %s\n", file_names[i]);
|
||||
} else {
|
||||
// Part 1
|
||||
t=NULL;
|
||||
load_tree(fp, &t);
|
||||
fclose(fp);
|
||||
printf("---------------\n%s:\n", file_names[i]);
|
||||
print_lvr(t); // on std output
|
||||
printf("\n");
|
||||
|
||||
//Part 2
|
||||
|
||||
char dot_file_name[MAX_STRING], pdf_file_name[MAX_STRING], command[MAX_STRING];
|
||||
|
||||
// new name for he dot file = file_name in which ".txt" is replaced by ".dot"
|
||||
build_name(file_names[i], dot_file_name, ".dot");
|
||||
fp=fopen(dot_file_name, "w");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "unreachable: %s\n", dot_file_name);
|
||||
} else {
|
||||
generate_dot(t,fp); // Call to the printing function
|
||||
printf("dot file %s has been generated\n",dot_file_name);
|
||||
fclose(fp);
|
||||
// new name for the pdf file = file_name in which ".txt" is replaced by ".pdf"
|
||||
build_name(file_names[i], pdf_file_name, ".pdf");
|
||||
// transform to .pdf with the dot system command
|
||||
sprintf(command, "dot -Tpdf %s -o %s", dot_file_name, pdf_file_name);
|
||||
system(command);
|
||||
printf("pdf file %s has been generated\n", pdf_file_name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// utility: build a new file name dest from src whose extension is replaced by the parameter ext
|
||||
// for example : file.txt -> file.dot
|
||||
void build_name(char *src, char *dest, char *ext) {
|
||||
strcpy(dest, src);
|
||||
strcpy(&dest[strlen(src)-4], ext);
|
||||
}
|
2
TP8/samples/.gitignore
vendored
Normal file
2
TP8/samples/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*.pdf
|
||||
*.dot
|
2
TP8/samples/balanced.txt
Executable file
2
TP8/samples/balanced.txt
Executable file
|
@ -0,0 +1,2 @@
|
|||
8 4 2 1 3 6 5 7 12 10 9 11 14 13 15
|
||||
|
2
TP8/samples/degenerated.txt
Executable file
2
TP8/samples/degenerated.txt
Executable file
|
@ -0,0 +1,2 @@
|
|||
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
|
1
TP8/samples/empty.txt
Executable file
1
TP8/samples/empty.txt
Executable file
|
@ -0,0 +1 @@
|
|||
|
1
TP8/samples/leaf.txt
Executable file
1
TP8/samples/leaf.txt
Executable file
|
@ -0,0 +1 @@
|
|||
1
|
2
TP8/samples/unspecified.txt
Executable file
2
TP8/samples/unspecified.txt
Executable file
|
@ -0,0 +1,2 @@
|
|||
9 4 2 11 3 6 5 15 12 10 8 1 14 13 7
|
||||
|
112
TP8/trees.c
Executable file
112
TP8/trees.c
Executable file
|
@ -0,0 +1,112 @@
|
|||
/*Source Code From Laure Gonnord and Bernard Carré*/
|
||||
|
||||
#include "trees.h"
|
||||
|
||||
// construction of a tree
|
||||
Tree cons(int val, Tree left, Tree right) {
|
||||
PtNode new = (PtNode)malloc(sizeof(Node));
|
||||
new->val=val;
|
||||
new->left=left;
|
||||
new->right=right;
|
||||
return new;
|
||||
}
|
||||
|
||||
// create an empty tree
|
||||
Tree mkEmptyTree(){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// t is empty?
|
||||
bool isEmpty (Tree t) {
|
||||
return t==NULL;
|
||||
}
|
||||
|
||||
// t is a leaf?
|
||||
bool isLeaf (Tree t) {
|
||||
return (!isEmpty(t) && isEmpty(t->left) && isEmpty(t->right));
|
||||
}
|
||||
|
||||
// add x in a bst wtr its value.
|
||||
void add(Tree *p_t, int x) {
|
||||
if (*p_t == NULL) {
|
||||
*p_t = cons(x, NULL, NULL);
|
||||
} else if (x <= (*p_t)->val) {
|
||||
add(&(*p_t)->left, x);
|
||||
} else {
|
||||
add(&(*p_t)->right, x);
|
||||
}
|
||||
}
|
||||
|
||||
// build a tree "add"ing values of the file fp
|
||||
void load_tree(FILE *fp, Tree *p_t) {
|
||||
int val;
|
||||
while (!feof(fp)) {
|
||||
fscanf(fp, "%d ", &val);
|
||||
add(p_t, val);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// print values of t in ascendant order (left-value-right)
|
||||
void print_lvr (Tree t) {
|
||||
if (t != NULL) {
|
||||
print_lvr(t->left);
|
||||
printf("%d ", t->val);
|
||||
print_lvr(t->right);
|
||||
}
|
||||
}
|
||||
|
||||
//Section 1.5
|
||||
void print_rec_edges(Tree t){
|
||||
if (t != NULL) {
|
||||
if (t->left != NULL) {
|
||||
printf("%d %d\n", t->val, t->left->val);
|
||||
print_rec_edges(t->left);
|
||||
}
|
||||
if (t->right != NULL) {
|
||||
printf("%d %d\n", t->val, t->right->val);
|
||||
print_rec_edges(t->right);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//PART II
|
||||
|
||||
// pre: !isEmpty(t) & !isLeaf(t)
|
||||
// recursively prints arcs of the tree <value,left,right> into the file fp:
|
||||
// "value -> left;" if exist
|
||||
// "value -> right;" if exist
|
||||
// to do...
|
||||
void recursive_dot(Tree t, FILE *fp) {
|
||||
if (t != NULL) {
|
||||
if (t->left != NULL) {
|
||||
fprintf(fp, " %d -> %d;\n", t->val, t->left->val);
|
||||
recursive_dot(t->left, fp);
|
||||
}
|
||||
if (t->right != NULL) {
|
||||
fprintf(fp, " %d -> %d;\n", t->val, t->right->val);
|
||||
recursive_dot(t->right, fp);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// generate a .dot file for the tree
|
||||
// limits (no arcs) :
|
||||
// isEmpty(t) => "empty" digraph
|
||||
// isLeaf(t) => only one node
|
||||
// general case :
|
||||
// calls recursive_dot which prints arcs
|
||||
void generate_dot (Tree t, FILE *fp) {
|
||||
fprintf (fp, "digraph G {\n");
|
||||
if (!isEmpty(t)) {
|
||||
if (isLeaf(t)) {
|
||||
fprintf(fp, "\t%d", t->val);
|
||||
} else {
|
||||
recursive_dot(t,fp);
|
||||
}
|
||||
}
|
||||
fprintf (fp, "}\n");
|
||||
}
|
47
TP8/trees.h
Executable file
47
TP8/trees.h
Executable file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* trees.h
|
||||
*
|
||||
*
|
||||
* From a code of Bernard Carre
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
typedef struct node {
|
||||
int val;
|
||||
struct node *left;
|
||||
struct node *right;
|
||||
}Node, *PtNode, *Tree;
|
||||
|
||||
|
||||
/*Construct a new tree from a value for the root node, a given left tree and a given right tree*/
|
||||
Tree cons(int , Tree , Tree );
|
||||
|
||||
// make an empty tree
|
||||
Tree mkEmptyTree();
|
||||
|
||||
/*Is the given tree empty ?*/
|
||||
bool isEmpty (Tree);
|
||||
|
||||
/*Is the given tree a leaf ?*/
|
||||
bool isLeaf (Tree);
|
||||
|
||||
/*Add a given integer in a binary search tree*/
|
||||
// do not verify the presence of x.
|
||||
void add(Tree *, int);
|
||||
|
||||
/*Print the values of the tree in ascendant order*/
|
||||
void print_lvr (Tree);
|
||||
|
||||
/* build a tree adding values of the file */
|
||||
void load_tree(FILE *, Tree *);
|
||||
|
||||
void print_rec_edges(Tree t);
|
||||
|
||||
/*PART 2*/
|
||||
|
||||
void generate_dot (Tree , FILE *);
|
Reference in a new issue