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