Προς το περιεχόμενο

huffman σε C


takis_tz

Προτεινόμενες αναρτήσεις

 

PS: To να φτιάξεις αυτό το πρόγραμμα είναι αρκετά επίπονη διαδικασία, θέλει υψηλή προγραμματιστική ικανότητα και να υλοποιήσεις βασικές δομές όπως τα δυαδικά δέντρα, συναρτήσεις που να δημιουργούν, να καταστρέφουν, να κάνουν ευθύ και αντίστροφο traverse στο δέντρο, εισαγωγή κόμβου, κτλ, επίσης θα πρέπει να παίξουμε με τα bits δηλαδή να φτιάξουμε συναρτήσεις που να παίζουν με bits, πχ XOR, και ίσως και ουρές προτεραιότητας για τις συγχωνεύσεις. Δύσκολα τα πράγματα, σίγουρα δεν σας έχει δώσει κάποια άλλη πορεία;

Επειδή το θέμα ενδιαφέρει κι εμένα θα ήθελα κάποιες κατευθύνσεις

 

Εχω ένα αλφάβητο 7 χαρακτήρων και τους αντίστοιχους κωδικούς huffman όπως φαίνεται στον παρακάτω πίνακα.

 

Χαρακτήρας Κωδικός Huffman

a 00

b 0100

c 0101

d 011

e 10

f 110

g 111

 

Σύμφωνα με τους κωδικούς αυτούς, η λέξη bag κωδικοποιείται ως 010000111 (υποτίθεται οτι είναι ακολουθία από bits). Μια ιδέα που μου περνά από το μυαλό είναι να θεωρήσω οτι είναι ακολουθία χαρακτήρων (δηλαδή έχω 9 χαρακτήρες, δηλ 72bits) και από κάθε χαρακτήρα θέλω να "κρατήσω" μόνο ένα bit.

 

Η βασική μου ερώτηση είναι, πως θα χειριστούμε την παραπάνω ακολουθία;

Θεωρούμε οτι η ακολουθία αυτή είναι αποθηκευμένη σε αρχείο. Σε βιβλία έχω διαβάσει για masks , τελεστές bit κλπ, αλλά επειδή 1η φορά ασχολούμαι με χειρισμό bits, δεν ξέρω τι απ'ολα αυτά χρειάζομαι.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Απαντ. 37
  • Δημ.
  • Τελ. απάντηση

Να συμπληρώσω πως δεν θέλω "έτοιμο φαϊ", αλλά οδηγίες για να φτιάξω δικό μου κώδικα. Δεν θέλω να "σπαταλήσω" τον χρόνο που διαθέτω ώστε να κατανοήσω τον κώδικα που έγραψε κάποιος άλλος, θέλω να φτιάξω κάτι δικό μου. Ευχαριστώ.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αυτό που λες αφορά την συνάρτηση uncompress που αποσυμπιέζει τον κώδικα με τα bits στα αντίστοιχα γράμματα, αυτό γίνεται ως εξής:

 

Κατασκεύαζοντας το huffman tree με τα γράμματα σύμβολα μαζί με τις συχνότητες τους να βρίσκονται πάντα σαν κόμβοι φύλλα στο δέντρο, τότε με βάση τον κανόνα που λέει ότι όποτε πάμε αριστερά βάζουμε μηδέν και όποτε πάμε δεξιά βάζουμε 1, παίρνουμε την ακολουθία μας και ξεκινόντας από το πρώτο bit συνεχίζουμε μέχρι να σταματήσουμε σε κόμβο φύλλο. Αν λοιπόν σταματήσουμε επιστρέφουμε το γράμμα που υπάρχει στον κόμβο φύλλο. Έτσι σχηματίζουμε την λέξη που παριστάνουν τα bits. Τώρα τι ακριβώς θέλεις γίνε λίγο περισσότερο ακριβής.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αυτό που λες αφορά την συνάρτηση uncompress που αποσυμπιέζει τον κώδικα με τα bits στα αντίστοιχα γράμματα, αυτό γίνεται ως εξής:

 

Κατασκεύαζοντας το huffman tree με τα γράμματα σύμβολα μαζί με τις συχνότητες τους να βρίσκονται πάντα σαν κόμβοι φύλλα στο δέντρο, τότε με βάση τον κανόνα που λέει ότι όποτε πάμε αριστερά βάζουμε μηδέν και όποτε πάμε δεξιά βάζουμε 1, παίρνουμε την ακολουθία μας και ξεκινόντας από το πρώτο bit συνεχίζουμε μέχρι να σταματήσουμε σε κόμβο φύλλο. Αν λοιπόν σταματήσουμε επιστρέφουμε το γράμμα που υπάρχει στον κόμβο φύλλο. Έτσι σχηματίζουμε την λέξη που παριστάνουν τα bits.

Τον αλγόριθμο (σε αυτό το θεωρητικό επίπεδο) τον κατανοώ, στην υλοποίηση του κολλάω.

 

Τώρα τι ακριβώς θέλεις γίνε λίγο περισσότερο ακριβής.

Επισυνάπτω τα δεδομένα (προδιαγραφές) που έχω στη διάθεση μου.

Εχω "τελειώσει" τα 2 πρώτα θέματα και έχω τα άλλα 2. Αυτά αφορούν την συμπίεση και την αποσυμπίεση ενός αρχείου. Αντιλαμβάνομαι οτι πρέπει να κάνω bit manipulation και μάλιστα με χαρακτήρες μεταβλητού μήκους (το μέγιστο είναι περιπου 25 bits-γισ χαρακτήρες με μικρή συχνότητα εμφάνισης ).

 

Σημειώνω οτι 1η φορά βρίσκομαι μπροστά σε "χειρισμό bits", και θα ήθελα λίγη καθοδήγηση (όχι έτοιμο κώδικα, επαναλαμβάνω).

Υ.Γ. Εχω φτιάξει δένδρο huffman, άπό αυτό έχω φτιάξει τους κωδικούς για κάθε χαρακτήρα. Τις συχνότητες εμφάνισης του κάθε χαρακτήρα τις έχω αποθηκευμένες σε απλό μονοδιάστατο πίνακα.

Υ.Γ2 το αρχείο sample.txt που αναφέρεται στην εκφώνηση είναι πολύ μεγάλο και δεν "ανεβαίνει".

huffman.zip

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Με το

>#define GET_BIT(byte,at) (byte&(1<<at)?1:0)

διαβάζεις το bit στη θέση at του byte

ενώ με το

>#define SET_BIT(byte,at) (byte|=(1<<at))

το βάζεις ίσο με 1.

Αφού είπες ότι δεν θέλεις κώδικα, μην διαβάσεις τα παρακάτω

>
int encode(USER_STREAM* s_in, USER_STREAM* s_out, MAP* map)
{
BYTE r, w;
BYTE* src;
int cb_src, cw, i;
cw = 0; w = 0;	
while (!UserStreamEOS(s_in)) {
	UserStreamReadByte(s_in, &r);
	src = MapGetPattern(map, r);
	cb_src = MapGetPatternCount(map, r);
	for (i = 0; i < cb_src ; ++i) {	
		if (src[i]) SET_BIT(w,cw);		
		if (++cw == 8) { UserStreamWriteByte(s_out, w); cw = 0; w = 0; }
	}
}
if (cw) UserStreamWriteByte(s_out, w); else cw = 8;
return cw;
}

void decode(USER_STREAM* s_in, USER_STREAM* s_out, TREE* tree, int last_byte_bits)
{
BYTE r, w;  
int i;
while (1) {
	UserStreamReadByte(s_in, &r);
	if (UserStreamEOS(s_in)) break;
	for (i = 0; i < 8; ++i) 
		if (TreeGetByte(tree, GET_BIT(r,i), &w)
			UserStreamWriteByte(s_out, w);
}
for (i = 0; i < last_byte_bits; ++i)
	if (TreeGetByte(tree, GET_BIT(r,i), &w)
		UserStreamWriteByte(s_out, w);
}

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Με το

>#define GET_BIT(byte,at) (byte&(1<<at)?1:0)

διαβάζεις το bit στη θέση at του byte

ενώ με το

>#define SET_BIT(byte,at) (byte|=(1<<at))

το βάζεις ίσο με 1.

Αφού είπες ότι δεν θέλεις κώδικα, μην διαβάσεις τα παρακάτω

>
int encode(USER_STREAM* s_in, USER_STREAM* s_out, MAP* map)
{
BYTE r, w;
BYTE* src;
int cb_src, cw, i;
cw = 0; w = 0;	
while (!UserStreamEOS(s_in)) {
	UserStreamReadByte(s_in, &r);
	src = MapGetPattern(map, r);
	cb_src = MapGetPatternCount(map, r);
	for (i = 0; i < cb_src ; ++i) {	
		if (src[i]) SET_BIT(w,cw);		
		if (++cw == 8) { UserStreamWriteByte(s_out, w); cw = 0; w = 0; }
	}
}
if (cw) UserStreamWriteByte(s_out, w); else cw = 8;
return cw;
}

void decode(USER_STREAM* s_in, USER_STREAM* s_out, TREE* tree, int last_byte_bits)
{
BYTE r, w;  
int i;
while (1) {
	UserStreamReadByte(s_in, &r);
	if (UserStreamEOS(s_in)) break;
	for (i = 0; i < 8; ++i) 
		if (TreeGetByte(tree, GET_BIT(r,i), &w)
			UserStreamWriteByte(s_out, w);
}
for (i = 0; i < last_byte_bits; ++i)
	if (TreeGetByte(tree, GET_BIT(r,i), &w)
		UserStreamWriteByte(s_out, w);
}

 

 

Ναι φίλε μου και τώρα πιστεύεις ότι κατάλαβε;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ναι φίλε μου και τώρα πιστεύεις ότι κατάλαβε;

Τον κώδικα το έχει "ταράξει τα typedef. Αντί να βάλει char, βάζει BYTE, αντι για FILE* βάζει USER_STREAM*. Μόνο το int του ¨ξέφυγε" και το άφησε το ίδιο.

 

UserStreamReadByte είναι η fgetc

MapGetPattern είναι πίνακας χαρακτήρων που περιέχει τους κωδικούς huffman

MapGetPatternCount είναι το μήκος του κάθε κωδικού (χάθηκε η strlen?)

UserStreamEOS είναι EOF.

 

Τι απέδειξα? Τιποτα

Τι απέδειξε ο bilco? Τίποτα?

Τι κέρδισα? Τίποτα, γιατί τον κώδικα τον καταλαβαίνω, αλλά την φιλοσοφία του όχι. Εχω κάπου 15 εκδόσεις του huffman σε C, αλλά δεν μπορώ να μπω στο νόημα. Μπορώ να κάνω μια "προσαρμογή" γα να φτιάξω τον κώδικα που χρειάζομαι αλλά αυτό δεν μου αρκει. Θέλω να καταλαβαίνω τι κάνω.

 

 

 

Τέλος πάντων, για να μην φανώ και αχάριστος, να ευχαριστήσω τον bilco.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Τον κώδικα το έχει "ταράξει τα typedef. Αντί να βάλει char, βάζει BYTE, αντι για FILE* βάζει USER_STREAM*. Μόνο το int του ¨ξέφυγε" και το άφησε το ίδιο.

 

UserStreamReadByte είναι η fgetc

MapGetPattern είναι πίνακας χαρακτήρων που περιέχει τους κωδικούς huffman

MapGetPatternCount είναι το μήκος του κάθε κωδικού (χάθηκε η strlen?)

UserStreamEOS είναι EOF.

 

Τι απέδειξα? Τιποτα

Τι απέδειξε ο bilco? Τίποτα?

Τι κέρδισα? Τίποτα, γιατί τον κώδικα τον καταλαβαίνω, αλλά την φιλοσοφία του όχι. Εχω κάπου 15 εκδόσεις του huffman σε C, αλλά δεν μπορώ να μπω στο νόημα. Μπορώ να κάνω μια "προσαρμογή" γα να φτιάξω τον κώδικα που χρειάζομαι αλλά αυτό δεν μου αρκει. Θέλω να καταλαβαίνω τι κάνω.

 

Τέλος πάντων, για να μην φανώ και αχάριστος, να ευχαριστήσω τον bilco.

 

Καταρχήν BYTE είναι ο unsigned char. Το USER_STREAM είναι ένα ρεύμα γενικά και αόριστα. Ακόμα και στην περίπτωση που είναι ρεύμα σε αρχείο, δεν είναι το ίδιο το FILE αλλά ένα ενδιάμεσο που δεν γράφει και διαβάζει ένα byte τη φορά στο αρχείο, αλλά μεγαλύτερα chunks. Η strlen χάθηκε γιατί έχει κόστος. Καλύτερα να κρατάς το μέγεθος για το pattern χωρίς να χρειάζεται να το υπολογίζεις με την strlen κάθε φορά (και γλυτώνεις και το χαρακτήρα τερματισμού).

Όσον αφορά τη συνάρτηση encode, έβαλα τη μη optimal version που γράφει ένα bit τη φορά (μπορούμε και καλύτερα) επειδή είναι πιο εύκολο να καταλάβεις τι κάνει.

Πιο αναλυτικά λοιπόν:

Ο w είναι ο χαρακτήρας που γεμίζουμε με bits. Ο cw μετράει πόσα bits έχουμε γράψει στον w. Όταν ο w γεμίσει (if (++cw == 8)) τον γράφουμε στο ρεύμα εξόδου και 'αδειάζουμε' τον w (w = 0; cw = 0). Είναι απαραίτητο εδώ να μηδενίσουμε τον w και αυτό εξηγείται από τον τρόπο που γράφουμε τα bits:

if (src) SET_BIT(w,cw)

γράφω το i bit του κώδικα του χαρακτήρα r αν αυτό είναι 1. Αν είναι μηδέν δεν χρειάζεται να γράψω τίποτα στον w αφού το επόμενο κενό bit του (στη θέση cw) είναι ήδη 0.

Αν αφού διαβάσουμε όλο το stream o cw δεν είναι μηδεν σημαίνει ότι περιέχει bits που δεν έχουν γραφτεί στην έξοδο γιαυτό γράφω τον w τώρα. Αν είναι μηδέν τον βάζω ίσο με 8 γιατί η συνάρτηση encode επιστρέφει τον αριθμό των έγκυρων bits στο τελευταίο byte (κάτι που θα μου χρειαστεί στην decode)

Στην decode τώρα και μέσα στο loop διαβάζω πρώτα τον χαρακτήρα και μετά ελέγχω για το τέλος του ρεύματος, ώστε αν αυτό είναι το τελευταίο byte να μην αποκωδικοποιήσω και τα 8 bit αλλά μόνο τα έγκυρα. H TreeGetByte επιστρέφει ένα όταν φτάσει σε φύλλο του δέντρου και γράφει τον χαρακτήρα στον w, αλλιώς επιστρέφει 0. Μια πιθανή υλοποίηση είναι να κρατάμε στο tree ένα link στον τρέχοντα κόμβο ξεκινώντας από τη ρίζα. Ανάλογα με το τι έιναι το bit μετακινεί τον τρέχοντα κόμβο στο δεξιό ή αριστερό παιδί του. Αν φτάσει σε φύλλο επαναφέρει τον τρέχοντα κόμβο στη ρίζα.

 

Αυτά, α και εξήγησέ μου και εμένα σε παρακαλώ, κάτι που δεν κατάλαβα?

Τι απέδειξε ο bilco? Τίποτα?

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αυτά, α και εξήγησέ μου και εμένα σε παρακαλώ, κάτι που δεν κατάλαβα?

Τι απέδειξε ο bilco? Τίποτα?

 

Μάλλον παρερμήνευσα (κακώς) τις προθέσεις σου, πάντως αυτά που δημοσίευσες ήταν πολύ περισσότερο απο αυτο που περιμενα (δηλαδή μια καθοδήγηση). Θα περίμενα κάτι σαν "πάρε την GET_BIT και την SET_BIT και πορεύσου", και μετά να σε "βομβάρδιζα" με ερωτήσεις (όχι ότι τώρα θα "γλυτώσεις" τις ερωτήσεις!).

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Και πριν αρχίσω τις ερωτήσεις (στις οποίες μπορει να απαντα .οποιος νομίζει οτι εχει να πει κάτι χρήσιμο), να σας πω οτι είμαι ενας μεταπτυχιακός φοιτητής πληροφορικής που το πτυχιο του δεν εχει σχέση με πληροφορική. Ετσι κάνω (όπως καταλαβαίνετε από τη φύση της εργασίας) Προγραμματισμό με C, και Δομές Δεδομένων, ταυτόχρονα και χωρίς κάποια προηγούμενη εμπειρία.

 

Αρχίζω "απαλά".

Γιατί χρησιμοποιούμε unsigned char και όχι char;

Και με ένα παράδειγμα: Ποιά είναι διαφορά του int i = 1; με το unsigned int = 1; ( το 1 είναι τυχαιος αριθμός).

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Και πριν αρχίσω τις ερωτήσεις (στις οποίες μπορει να απαντα .οποιος νομίζει οτι εχει να πει κάτι χρήσιμο), να σας πω οτι είμαι ενας μεταπτυχιακός φοιτητής πληροφορικής που το πτυχιο του δεν εχει σχέση με πληροφορική. Ετσι κάνω (όπως καταλαβαίνετε από τη φύση της εργασίας) Προγραμματισμό με C, και Δομές Δεδομένων, ταυτόχρονα και χωρίς κάποια προηγούμενη εμπειρία.

 

Αρχίζω "απαλά".

Γιατί χρησιμοποιούμε unsigned char και όχι char;

Και με ένα παράδειγμα: Ποιά είναι διαφορά του int i = 1; με το unsigned int = 1; ( το 1 είναι τυχαιος αριθμός).

 

Το πρώτο αφορά έναν ακέραιο με τιμή 1 σε γκάμα -32768 έως +32768 ενώ το δεύτερο αφορά ένα θετικό ακέραιο αριθμό δηλαδή από 0 έως 32768.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Το πρώτο αφορά έναν ακέραιο με τιμή 1 σε γκάμα -32768 έως +32768 ενώ το δεύτερο αφορά ένα θετικό ακέραιο αριθμό δηλαδή από 0 έως 32768.

Μήπως εννοείς από 0 έως 65536 ?

 

Δηλαδή, αν καταλαβαίνω, αν θεωρήσουμε οτι ο τύπος int είναι 4 byte (δηλαδή 32 bits), τότε οι 32άδες για το int i = 1; και unsigned int i = 1; είναι διαφορετικές?

 

Επίσης, εννοείς οτι δεν μπορούμε να γράψουμε unsigned int i = -1; σωστά?

 

Επόμενη ερώτηση:

 

#define GET_BIT(byte,at) (byte&(1<<at)?1:0)

 

#define SET_BIT(byte,at) (byte|=(1<<at))

 

Στα παραπάνω, τα byte και at τι τύπο έχουν, int, char ή δεν έχει σημασία? Μήπως ο τυπος οριζεται αργότερα στον κώδικα? Τι παιζει?

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μήπως εννοείς από 0 έως 65536 ?

 

Δηλαδή, αν καταλαβαίνω, αν θεωρήσουμε οτι ο τύπος int είναι 4 byte (δηλαδή 32 bits), τότε οι 32άδες για το int i = 1; και unsigned int i = 1; είναι διαφορετικές?

 

Επίσης, εννοείς οτι δεν μπορούμε να γράψουμε unsigned int i = -1; σωστά?

 

Επόμενη ερώτηση:

 

 

 

 

 

Στα παραπάνω, τα byte και at τι τύπο έχουν, int, char ή δεν έχει σημασία? Μήπως ο τυπος οριζεται αργότερα στον κώδικα? Τι παιζει?

 

 

Αφού τα ξέρεις ή μπορείς να τα βρεις γιατί μας ρωτάς;

Ναι λοιπόν έκανα λάθος ένας ακέραιος μπορεί να έχει μέγεθος 2 ή 4 byte και ανάλογα με τον επεξεργαστή και τον compiler μπορεί να είναι 16 ή 32 bit.

O unsigned int(16) bit: 0-65535 -> 2 bytes

O unsigned int(32) bit: 0 to 4,294,967,295 -> 4 bytes

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μήπως εννοείς από 0 έως 65536 ?

Δηλαδή, αν καταλαβαίνω, αν θεωρήσουμε οτι ο τύπος int είναι 4 byte (δηλαδή 32 bits), τότε οι 32άδες για το int i = 1; και unsigned int i = 1; είναι διαφορετικές?

για το 1 είναι ακριβώς το ίδιο, 31 μηδενικούρες και ένας άσσος στο μπιτ 0. Η διαφορά είναι στους αρνητικούς (ή στους unsigned > 2147483647). Για παράδειγμα ο unsigned 4294967295 που έχει και τα 32 μπιτ άσσους σαν int είναι ο -1.

Επίσης, εννοείς οτι δεν μπορούμε να γράψουμε unsigned int i = -1; σωστά?

Οπότε φυσικά και μπορούμε αφού ο προσημασμένος -1 θα μετατραπεί στον απρόσημο 4294967295.

Γενικά όλοι οι προσημασμένοι τύποι έχουν στις αρνητικές τιμές τους το πρώτο μπιτ τους ένα (πρώτο εννοούμε στην μεγαλύτερη θέση aka πιο σημαντικό μπιτ) . Η αναπαράστασή τους τώρα γίνεται μέσω αυτού που ονομάζουμε 2-complement. Για να βρώ τον αντίθετο ενός αριθμού, αντιστρέφω τα μπιτ (βαζω όπου 1-0 και όπου 0-1) και προσθέτω το 1.

 

Στα παραπάνω, τα byte και at τι τύπο έχουν, int, char ή δεν έχει σημασία? Μήπως ο τυπος οριζεται αργότερα στον κώδικα? Τι παιζει?

Αυτά είναι μάκρο και δεν ορίζεται κάποιος τύπος. Αν γράψω μέσα στον κώδικά μου SET_BIT("Γκόγκο","Μπόγκο") o προεπεξεργαστής θα το αντικαταστήσει με το

"Γκόγκο"|=(1<<"Μπόγκο") και φυσικά μετά ο compiler θα χτυπήσει.

Για το τι μπορούμε να βάλουμε τώρα: για το byte και απρόσημους και προσημασμένους ακέραιους ανεξαρτήτως μεγέθους. Και για το at το ίδιο ισχύει αλλά αν βάλουμε έναν αρνητικό ακέραιο τότε αυτός θα μετατραπεί (implicity) σε απρόσημο που σημαίνει ότι το 1<<-1 θα γίνει 1<<4294967295.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

ΚΑΛΗΣΠΕΡΑ ΚΑΙ ΚΑΛΗ ΧΡΟΝΙΑ ΣΕ ΟΛΟΥΣ ΣΑΣ.

 

ΕΧΩ ΚΑΙ ΕΓΩ ΤΙ ΙΔΙΑ ΑΣΚΗΣΗ ΚΑΙ ΑΝΤΙΜΕΤΩΠΙΖΩ ΕΝΑ ΠΡΟΒΛΗΜΑ ΚΑΤΑ ΤΙ ΔΗΜΙΟΥΡΓΙΑ ΤΟΥ ΔΕΝΔΡΟΥ HUFFMAN.ΕΧΩ ΚΑΝΕΙ ΤΟ ΠΙΟ ΚΑΤΩ ΚΩΔΙΚΑ.ΔΕΝ ΕΙΝΑΙ ΟΜΩΣ ΚΑΙ ΤΟΣΟ ΚΑΛΟΣ ΚΑΙ ΘΑ ΗΘΕΛΑ ΤΗΝ ΒΟΗΘΕΙΑ ΣΑΣ.ΤΟ ΔΕΝΤΡΟ ΠΟΥ ΘΕΛΩ ΝΑ ΔΗΜΙΟΥΡΓΗΣΩ ΘΕΛΩ ΝΑ ΕΙΝΑΙ ΜΕ ΒΑΣΗ ΤΟ probfile.txt ΠΟΥ ΣΑΣ ΠΑΡΑΘΕΤΩ ΠΙΟ ΚΑΤΩ.

typedef struct _treenode treenode;

 

struct _treenode{

int freq; /* frequency is the priority for heap */

unsigned char ch; /* character,if any */

treenode *left; /* left child of huffman tree */

treenode *right; /* right child of huffman tree */

};

 

/* this is a priority queue implemented as a binary heap */

typedef struct _pq{

int heap_size;

treenode *A[TABLE_SIZE];

}PQ;

 

/* create an empty queue */

 

void create_pq(PQ *p){

p->heap_size=0;

};

 

/* this heap node's parent */

 

int parent(int i){

return (i-1)/2;

}

 

/* this heap node's left kid */

 

int letf(int i){

return i*2+1;

}

 

/* this heap node's right kid */

 

int right(int i){

return i*2+2;

}

 

ΣΑΣ ΕΥΧΑΡΙΣΤΩ ΕΚ ΤΩΝ ΠΡΟΤΕΡΩΝ!!

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.


  • Δημιουργία νέου...