Example of Coding on haXe – Part 1

In this example, your will see: Trace, enum, variables (integer, boolean, void, string, float, dynamic), null, array iterable, for loop, if/else.

NOTIFICATION: These examples are provided for educational purposes. Using this code is under your own responsibility and risk. The code is given ‘as is’. I do not take responsibilities of how they are used.

Actual Example:
Sorry, either Adobe flash is not installed or you do not have it enabled

Code Example: Example_1.hx

// enum go outside the class
enum Enum_Colors {
	blue;
	red;
	yellow;
}

class Example_1 {

	static function main(){

		// Integers
		var variable_integer : Int;
		variable_integer = 0;
		trace('1) variable_integer = ' + variable_integer);
		variable_integer = -134;
		trace('2) variable_integer = ' + variable_integer);
  	variable_integer = 0xFF00;
		trace('3) variable_integer = ' + variable_integer);

		// Float
		var variable_float : Float;
	  variable_float = 123.0;
		trace('4) variable_float = ' + variable_float);
	  variable_float = .14179;
		trace('5) variable_float = ' + variable_float);
	  variable_float = 13e50;
		trace('6) variable_float = ' + variable_float);
	  variable_float = -1e-99;
		trace('7) variable_float = ' + variable_float);

		// String
		var variable_string : String;
	  variable_string = 'hello';
		trace('8) variable_string = ' + variable_string);
    variable_string = 'hello \'world\' !';
    trace('9) variable_string = ' + variable_string);
	  variable_string = 'hello 'world' !';
	  trace('10) variable_string = ' + variable_string);

		// Boolean
		var variable_bool : Bool;
	  variable_bool = true;
	  trace('11) variable_bool = ' + variable_bool);
  	variable_bool = false;
		trace('12) variable_bool = ' + variable_bool);

	  // Dynamic
	  var variable_dynamic : Dynamic;
	  variable_dynamic = 7;
	  trace('13) variable_dynamic = ' + variable_dynamic);
	  variable_dynamic = 'Now, variable_dynamic holds a string';
	  trace('14) variable_dynamic = ' + variable_dynamic);

	  // Assigning null
	  var variable;
	  variable = null;
	  trace('15) variable = ' + variable);

		// Using enum constants
		var variable_colors : Enum_Colors;
		variable_colors = blue;
		if (variable_colors == blue){
			trace('16) variable_colors = blue');
		}else{
			trace('16) variable_colors is not blue');
		}

		variable_colors = yellow;
		if (variable_colors == blue){
			trace('17) variable_colors = blue');
		}else{
			trace('17) variable_colors is not blue');
		}

		// Using Arrays (in haxe, arrays are iterable)
		var integer_array : Array<Int> = [1,2,3,4];

		// You can loop through integer_array's members directly with a for..in loop
		var count : Int = 0;
		for (i in integer_array){
			trace('18) integer_array[' + count++ + ']: ' + i);
		}

		var num : Int = 4;
		for (i in 0...num)
			trace('19) integer_array[' + i + ']: ' + integer_array[i]);

		for (i in 0...4)
			trace('20) integer_array[' + i + ']: ' + integer_array[i]);

		// This would not work: for (i in 3...0)
		var i : Int = 3;
		while (i >= 0){
			trace('21) integer_array[' + i + ']: ' + integer_array[i]);
			--i;
		}

  }

}

If you encounter any problems or errors, please let me know by providing an example of the code, input, output, and an explanation. Thanks.

Share
Leave a comment

Example of Vertex Cover Algorithm using Heap

NOTIFICATION: These examples are provided for educational purposes. The use of this code and/or information is under your own responsibility and risk. The information and/or code is given ‘as is’. I do not take responsibilities of how they are used.

Example of Vertex Cover algorithm using heap.

vertex_cover.c:

/*
 * Program: 10
 * Author: Alejandro G. Carlstein
 * Description: Applying Vertex Cover Algorithm
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>

#define MAX_EDGES 100001
#define MAX_VERTICES  50001
#define LEFT(i) ((i << 1) + 1)
#define RIGHT(i) ((i << 1) + 2)
#define DIV_BY_2(i) (i >> 1)
#define FALSE 0
#define TRUE 1

#define DBG_LV0 0
#define DBG_LV1 0
#define DBG_LV2 0
#define DBG_LV3 0

struct Edge{
	int id;
  int uVertex;
  int vVertex;
  short enabled;
} edges[MAX_EDGES];

struct Vertex{
	int id;
	int numEdges;
}vertices[MAX_VERTICES];

struct VertexCover{
	struct Vertex *vertexPointer;
	struct VertexCover *next;
};

struct AdjList{
	struct Edge *edgePointer;
	struct AdjList *next;
} *adjList[MAX_EDGES], *headAdj, *newAdj;

void readLimits(void);
void setVerticesDefault(void);
void readEdges(void);
void printEdges(void);
void printVertices(void);
struct VertexCover *vertexCover(void);
void makeMaxPriorityQueue(int heapArray[], int *length);
void printArray(int array[], int length);
void buildMaxHeap(int heapArray[], int length);
void maxHeapify(int heapArray[], int index, int heapSize);
int getMaxHeap(int heapArray[], int heapSize);
int heapExtractMax(int heapArray[], int *heapSize);
void exchange(int *a, int *b);
void buildAdjacentEdgesList(void);
void insertAdjEdgesOf(int edgeIndex);
void insertAdjEdge(int edgeIndex, int adjEdgeIndex);
void printAdjList(int edgeIndex);
void addVerticesOfEdgeToVertexCover(struct VertexCover *vertexCover, int vertexIndex);
void printvertexCover(struct VertexCover *vertexCover);
void debug(int debugLevel, char *fmt, ...);
void errorDoExit(char *fmt, ...);

int numVertices, numEdges;
int main(int argc, char *argv[]){
	readLimits();
	setVerticesDefault();
	readEdges();
	printvertexCover(vertexCover());
	return 0;
}

void readLimits(void){
	debug(DBG_LV0, 'readLimits()');	

	scanf('%d %d', &numVertices, &numEdges);
	debug(DBG_LV1, '# of vertices: %d, # of edges: %d', numVertices, numEdges);
}

void setVerticesDefault(void){
	debug(DBG_LV0, 'setVerticesDefault()');	

	int i;
	for (i = 0; i < numVertices; ++i){
		vertices[i].id = i;
		vertices[i].numEdges = 0;
	}
}

void readEdges(void){
	debug(DBG_LV0, 'readEdges()');	

	int i, uVertex, vVertex;
	for(i = 0; i < numEdges; ++i){
		int length;
		scanf('%d %d %d', &uVertex, &vVertex, &length);
		if (uVertex >= numVertices || vVertex >= numVertices)
			errorDoExit('Edge [%d](%d <> %d) have vertices id > %d', i, uVertex, vVertex, numVertices);
		edges[i].id = i;
		edges[i].uVertex = uVertex;
		edges[i].vVertex = vVertex;
		edges[i].enabled = TRUE;
		++vertices[uVertex].numEdges;
		++vertices[vVertex].numEdges;
	}	

	if (DBG_LV1) printEdges();
	if (DBG_LV1) printVertices();
}

void printEdges(){
	debug(DBG_LV0, 'printEdges()');

	int i;
	for(i = 0; i < numEdges; ++i)
		if (edges[i].enabled){
			printf('(%d<[%d]>%d)\n', edges[i].uVertex, i,edges[i].vVertex);
		}else{
			printf('(%d|[%d]|%d)\n', edges[i].uVertex, i,edges[i].vVertex);
		}
}

void printVertices(void){
	debug(DBG_LV0, 'printVertices()');

	printf('[  ]');
	int i;
	for (i = 0; i < numVertices; ++i)
		printf('[%d]', i);

	printf('\n[NE]');
	for (i = 0; i < numVertices; ++i)
		printf(' %d ' , vertices[i].numEdges);
	printf('\n');
}

struct VertexCover *vertexCover(void){
	debug(DBG_LV0, 'vertexCover()');

	// Build list of vertices that have the most number of edges
	int heapLength = numEdges + 1;
	int heapArray[heapLength];
	makeMaxPriorityQueue(heapArray, &heapLength);
	if (DBG_LV1) printArray(heapArray, heapLength);

	// Build Adjacent Vertices List
	buildAdjacentEdgesList();

	// Vertex cover to being constructed
	struct VertexCover *vertexCover = NULL;

	int edgeIndex;
	while(heapLength > 0){
		// Pick the edge in which vertices have the highest number of edges
		edgeIndex = heapExtractMax(heapArray, &heapLength);
		//Keep looping until you find an edge that is enabled or your count all the edges
		if (edges[edgeIndex].enabled){
			debug(DBG_LV1, 'EDGE FOUND: (%d<[%d]>%d)', edges[edgeIndex].uVertex, edgeIndex, edges[edgeIndex].vVertex);
		}else{
			debug(DBG_LV1, 'EDGE FOUND: (%d<|%d|>%d)', edges[edgeIndex].uVertex, edgeIndex, edges[edgeIndex].vVertex);
		}

		if (edges[edgeIndex].enabled){

			int uVertex = edges[edgeIndex].uVertex;
			int vVertex = edges[edgeIndex].vVertex;
			int uVertexNumEdges = vertices[uVertex].numEdges;
			int vVertexNumEdges = vertices[vVertex].numEdges;
			debug(DBG_LV1,'uVertex: %d, NumEdges: %d', uVertex, uVertexNumEdges);
			debug(DBG_LV1,'vVertex: %d, NumEdges: %d', vVertex, vVertexNumEdges);

			// Add this vertices of this edge to the list of edges
			struct VertexCover *newVertexCover = (struct VertexCover *) malloc(sizeof(struct VertexCover));
			newVertexCover->vertexPointer = &vertices[uVertex];
			if (vertexCover == NULL){
				debug(DBG_LV1, 'vertexCover is empty');
				newVertexCover->next = vertexCover;
				vertexCover = newVertexCover;
			}else{
				debug(DBG_LV1, 'vertexCover is NOT empty');
				struct VertexCover *currentVertexCover = vertexCover;
				while (currentVertexCover->next != NULL){
					currentVertexCover = currentVertexCover->next;
				}
				newVertexCover->next = currentVertexCover->next;
				currentVertexCover->next = newVertexCover;
			}
			debug(DBG_LV1, 'adding %d to vertexCover', newVertexCover->vertexPointer->id);			

			// Add this vertices of this edge to the list of edges
			newVertexCover = (struct VertexCover *) malloc(sizeof(struct VertexCover));
			newVertexCover->vertexPointer = &vertices[vVertex];
			if (vertexCover == NULL){
				debug(DBG_LV1, 'vertexCover is empty');
				newVertexCover->next = vertexCover;
				vertexCover = newVertexCover;
			}else{
				debug(DBG_LV1, 'vertexCover is NOT empty');
				struct VertexCover *currentVertexCover = vertexCover;
				while (currentVertexCover->next != NULL){
					currentVertexCover = currentVertexCover->next;
				}
				newVertexCover->next = currentVertexCover->next;
				currentVertexCover->next = newVertexCover;
			}
			debug(DBG_LV1, 'adding %d to vertexCover', newVertexCover->vertexPointer->id);			

			// Search thought all the adjacent edges to this edge and disable them
			struct AdjList *tempAdj;
			tempAdj = adjList[edgeIndex];
			while(tempAdj != NULL){
					debug(DBG_LV1, 'Disable Edge (%d<|%d|>%d)',
								tempAdj->edgePointer->uVertex, tempAdj->edgePointer->id, tempAdj->edgePointer->vVertex);
					tempAdj->edgePointer->enabled = FALSE;
					vertices[tempAdj->edgePointer->uVertex].numEdges--;
					vertices[tempAdj->edgePointer->vVertex].numEdges--;
				tempAdj = tempAdj->next;
			}
			edges[edgeIndex].enabled = FALSE;
			vertices[edges[edgeIndex].uVertex].numEdges--;
			vertices[edges[edgeIndex].vVertex].numEdges--;

		}
	}
	if(DBG_LV1) printEdges();

	return vertexCover;
}

void makeMaxPriorityQueue(int heapArray[], int *length){
	debug(DBG_LV0, 'makePriorityQueue(length: %d)', *length);

	int i;
	for (i = 0; i < numEdges; ++i)
		heapArray[i] = i;

	*length = numEdges;
	if (DBG_LV1) printArray(heapArray, *length);
	buildMaxHeap(heapArray, *length);
	if (DBG_LV1) printArray(heapArray, *length);
	if (DBG_LV1) printEdges();
}

void printArray(int array[], int length){
	debug(DBG_LV0, 'printArray(length: %d)', length);

	int i;
	for (i = 0; i < length; ++i)
		printf('[%d]', i);

	printf('\n');
	for (i = 0; i < length; ++i)
		printf(' %d ', array[i]);
	printf('\n');
}

void buildMaxHeap(int heapArray[], int length){
	debug(DBG_LV0, 'buildMaxHeap(length: %d)', length);

	int heapSize = length;

	int index;
	for (index = DIV_BY_2(length); index > -1; --index)
		maxHeapify(heapArray, index, heapSize);
}

void maxHeapify(int heapArray[], int index, int heapSize){
	debug(DBG_LV2, 'maxHeapify(index: %d, heapSize: %d)', index, heapSize);

	int largestIndex = index;
	int leftIndex = LEFT(index);
	int rightIndex = RIGHT(index);
	debug(DBG_LV2, '-LargestIndex: %d, leftIndex: %d, rightIndex: %d', largestIndex, leftIndex, rightIndex);

	if (leftIndex <= heapSize && rightIndex <= heapSize){

		unsigned int indexValue = vertices[edges[heapArray[index]].uVertex].numEdges +
															vertices[edges[heapArray[index]].vVertex].numEdges;

		unsigned long int leftValue = vertices[edges[heapArray[leftIndex]].uVertex].numEdges +
														 vertices[edges[heapArray[leftIndex]].vVertex].numEdges;

		if ((leftIndex < heapSize) && (leftValue > indexValue))
			largestIndex = leftIndex;
		debug(DBG_LV2, '(left) largestIndex: %d', largestIndex);

		debug(DBG_LV2, 'rightIndex: %d', rightIndex);
		debug(DBG_LV2, 'edges[%d].uVertex: %d, edges[%d].vVertex: %d',
										edges[heapArray[rightIndex]].uVertex,
										edges[heapArray[rightIndex]].vVertex);
		debug(DBG_LV2, 'uVertexNum: %d, vVertexNum: %d',
									vertices[edges[heapArray[rightIndex]].uVertex].numEdges,
								 vertices[edges[heapArray[rightIndex]].vVertex].numEdges);
		unsigned int rightValue = vertices[edges[heapArray[rightIndex]].uVertex].numEdges +
															vertices[edges[heapArray[rightIndex]].vVertex].numEdges;	

		if ((rightIndex < heapSize) && (rightValue > indexValue))
			largestIndex = rightIndex;
		debug(DBG_LV2, '(right) largestIndex: %d', largestIndex);

		if (largestIndex != index){
			debug(DBG_LV2, 'largestIndex != index');
			exchange(&heapArray[index], &heapArray[largestIndex]);
			maxHeapify(heapArray, largestIndex, heapSize);
		}
	}
}

int getMaxHeap(int heapArray[], int heapSize){
	debug(DBG_LV0, 'getMaxHeap(heapSize: %d)', heapSize);

	if (heapSize < 1)
		errorDoExit('Heap Underflow');
	int max = heapArray[0];
	return max;
}

int heapExtractMax(int heapArray[], int *heapSize){
	debug(DBG_LV0, 'heapExtractMax(heapSize: %d)', *heapSize);

	if (*heapSize < 1)
		errorDoExit('Heap Underflow');

	buildMaxHeap(heapArray, *heapSize);

	int max = heapArray[0];
	--*heapSize;
	heapArray[0] = heapArray[*heapSize];
	maxHeapify(heapArray, 1, *heapSize);

	return max;
}

void exchange(int *a, int *b){
	debug(DBG_LV3, 'exchange(a: %d, b: %d)', *a, *b);

		int temp;
		temp = *a;
		*a = *b;
		*b = temp;
}

void buildAdjacentEdgesList(void){
	debug(DBG_LV0, 'buildAdjacentEdgesList()');

	int edgeIndex;
	for (edgeIndex = 0; edgeIndex < numEdges; ++edgeIndex){
		insertAdjEdgesOf(edgeIndex);
	}

	if (DBG_LV1)
		for (edgeIndex = 0; edgeIndex < numEdges; ++edgeIndex)
			printAdjList(edgeIndex);
}

void insertAdjEdgesOf(int edgeIndex){
	debug(DBG_LV0, 'insertAdjEdgesOf(edgeIndex: %d)', edgeIndex);	

	debug(DBG_LV1, ' Searching for adjacent Edges');
	int adjEdgeIndex;
	for (adjEdgeIndex = 0; adjEdgeIndex < numEdges; ++adjEdgeIndex){
		if (edgeIndex != adjEdgeIndex){
			int uVertex = edges[edgeIndex].uVertex;
			int vVertex = edges[edgeIndex].vVertex;
			int adjUVertex = edges[adjEdgeIndex].uVertex;
			int adjVVertex = edges[adjEdgeIndex].vVertex;
			debug(DBG_LV1, '  (%d <[%d]> %d) <=?=> A(%d <[%d]> %d)', uVertex, edgeIndex, vVertex, adjUVertex, adjEdgeIndex, adjVVertex);
			if (uVertex == adjUVertex || vVertex == adjVVertex ||
					uVertex == adjVVertex || vVertex == adjUVertex){
				debug(DBG_LV1, '   YES');
				insertAdjEdge(edgeIndex, adjEdgeIndex);
			}
		}
	}
	if(DBG_LV1) printAdjList(edgeIndex);
}

void insertAdjEdge(int edgeIndex, int adjEdgeIndex){

	struct AdjList *headAdj;
	headAdj = adjList[edgeIndex];	

	struct AdjList *newAdj = (struct AdjList *) malloc(sizeof(struct AdjList));
	newAdj->edgePointer = &edges[adjEdgeIndex];
	newAdj->next = NULL;

	if (headAdj == NULL){
		newAdj->next = adjList[edgeIndex];
		adjList[edgeIndex] = newAdj;
	}else{
		struct AdjList *currentAdj = adjList[edgeIndex];
		while (currentAdj->next != NULL)
			currentAdj = currentAdj->next;
		newAdj->next = currentAdj->next;
		currentAdj->next = newAdj;
	}
}

void printAdjList(int edgeIndex){
	debug(DBG_LV0, '**printAdjList(edgeIndex: %d)', edgeIndex);	

	struct AdjList *tempAdj;
	tempAdj = adjList[edgeIndex];	

	if (tempAdj == NULL){
		debug(DBG_LV1, ' tempAdj is empty');
	}else{		

		printf('[%d]', edgeIndex);
		int i = 0;
		while(tempAdj != NULL){
			printf('|%d|', i++);
			tempAdj = tempAdj->next;
		}

		printf('\n i:');
		tempAdj = adjList[edgeIndex];
		while(tempAdj != NULL){
			printf('[%d]', tempAdj->edgePointer->id);
			tempAdj = tempAdj->next;
		}

		printf('\n u:');
		tempAdj = adjList[edgeIndex];
		while(tempAdj != NULL){
				printf(' %d ' , tempAdj->edgePointer->uVertex);
				tempAdj = tempAdj->next;
		}

		printf('\n v:');
		tempAdj = adjList[edgeIndex];
		while(tempAdj != NULL){
				printf(' %d ' , tempAdj->edgePointer->vVertex);
				tempAdj = tempAdj->next;
		}

		printf('\n');
	}
}

void addVerticesOfEdgeToVertexCover(struct VertexCover *vertexCover, int vertexIndex){
	debug(DBG_LV0, 'addVerticesOfEdgeToVertexCover(vertexIndex: %d)', vertexIndex);	

	struct VertexCover *newVertexCover = (struct VertexCover *) malloc(sizeof(struct VertexCover));
	newVertexCover->vertexPointer = &vertices[vertexIndex];
	if (vertexCover == NULL){
		debug(DBG_LV1, 'vertexCover is empty');
		newVertexCover->next = vertexCover;
		vertexCover = newVertexCover;
		debug(DBG_LV1, 'adding %d to vertexCover', newVertexCover->vertexPointer->id);
	}else{
		struct VertexCover *currentVertexCover = vertexCover;
		debug(DBG_LV1, 'adding %d to vertexCover', currentVertexCover->vertexPointer->id);
		while (currentVertexCover->next != NULL){
			debug(DBG_LV1, 'vertexId: %d', currentVertexCover->vertexPointer->id);
			currentVertexCover = currentVertexCover->next;
		}
		newVertexCover->next = currentVertexCover->next;
		currentVertexCover->next = newVertexCover;
	}	

}

void printvertexCover(struct VertexCover *vertexCover){
	debug(DBG_LV0, 'printvertexCover');	

	struct VertexCover *tempAdj;
	tempAdj = vertexCover;	

	if (tempAdj == NULL){
		debug(DBG_LV1, ' tempAdj is empty');
	}else{		

		while(tempAdj != NULL){
			printf('%d ', tempAdj->vertexPointer->id);
			tempAdj = tempAdj->next;
		}

		printf('\n');
	}
}

void debug(int debugLevel, char *fmt, ...){
	if (debugLevel == 1){
		va_list argp;
		fprintf(stdout, '[DBG] ');
		va_start(argp, fmt);
		vfprintf(stdout, fmt, argp);
		va_end(argp);
		fprintf(stdout, '\n');
	}
}

void errorDoExit(char *fmt, ...){
	va_list argp;
	fprintf(stderr, '[Error] ');
	va_start(argp, fmt);
	vfprintf(stderr, fmt, argp);
	va_end(argp);
	if (errno){
		fprintf(stderr, '=> %s\n', strerror(errno));
	}else{
		fprintf(stderr, '\n');
	}
	exit(1);
}

input.txt:

4 7

0 1 5

0 2 4

1 3 3

2 3 2

3 0 1

2 1 10

0 3 20

If you encounter any problems or errors, please let me know by providing an example of the code, input, output, and an explanation. Thanks.

Share
Leave a comment

Example of Disjktra Algorithm using Heap

NOTIFICATION: These examples are provided for educational purposes. The use of this code and/or information is under your own responsibility and risk. The information and/or code is given ‘as is’. I do not take responsibilities of how they are used.

Example of Disjktra algorithm using heap.

disjktra_heap.c:

/*
 * Program: 09
 * Author: Alejandro G. Carlstein
 * Description: Disjktra Algorithm using heap
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <malloc.h>
#include <limits.h>

#define MAX_EDGES 100001
#define MAX_VERTICES  500001
#define LEFT(i) ((i << 1) + 1)
#define RIGHT(i) ((i << 1) + 2)
#define DIV_BY_2(i) (i >> 1)
#define FALSE 0
#define TRUE 1

#define DBG_LV0 0
#define DBG_LV1 0
#define DBG_LV2 0
#define DBG_LV3 0

struct Edge{
  int startVertex;
  int endVertex;
  unsigned int length;
} edges[MAX_EDGES];

struct Vertex{
	unsigned int id;
	unsigned int weight;
	struct Vertex *predecessor;
	short visited;
} vertices[MAX_VERTICES];

struct AdjList{
	struct Vertex *vertexPointer;
	int edgeIndex;
	struct AdjList *next;
} *adjList[MAX_VERTICES], *headAdj, *newAdj;

void init(void);
void readStandardInput(void);
void printEdges(void);
void disjktraAlgorithm(void);
void initializeSingleSource(void);
void printVertices(void);
void buildAdjacentVertexList(void);
void insertAdjVerticesOf(int vertexIndex);
void insertAdjVertex(int vertexIndex, int adjVertexIndex, int edgeIndex);
void printAdjList(int vertexIndex);
void makePriorityQueue(int heapArray[], int *length);
void printArray(int array[], int length);
void buildMinHeap(int heapArray[], int length);
void minHeapify(int heapArray[], int index, int heapSize);
int heapExtractMin(int heapArray[], int *heapSize);
void exchange(int *a, int *b);
void addVertexToList(struct AdjList *vertexList, struct Vertex *vertex);
void relax(int startVertex, int endVertex, int edge);
void printRoute(void);
void debug(int debugLevel, char *fmt, ...);
void errorDoExit(char *fmt, ...);

int numVertices, numEdges;
int main(int argc, char *argv[]){

	init();
	disjktraAlgorithm();
	printVertices();
	return 0;
}

void init(void){
	debug(DBG_LV0, 'init()');
	readStandardInput();
}

void readStandardInput(void){
	debug(DBG_LV0, 'readStandardInput()');	

	scanf('%d %d', &numVertices, &numEdges);
	debug(DBG_LV1, '# of vertices: %d, # of edges: %d', numVertices, numEdges);
	printEdges();
}

void printEdges(void){
	debug(DBG_LV0, 'printEdges()');	

	int i;
	for(i = 0; i < numEdges; ++i){
		scanf('%d %d %d', &edges[i].startVertex, &edges[i].endVertex, &edges[i].length);
		debug(DBG_LV1, '[%d](%d <%d> %d)', i, edges[i].startVertex, edges[i].length, edges[i].endVertex);
	}
}

// Disjktra(G, w, s)	//s is source vertex - w is weight
void disjktraAlgorithm(void){
	debug(DBG_LV0, 'disjktraAlgorithm()');	

	// InitializeSingleSource(G, s);
	initializeSingleSource();

	//	S <- 0    // It will hold vertices
	struct AdjList *vertexList = NULL;

	//	Q <- V[G] // Make a priority Queue for the vertices
	int heapArray[numVertices];
	int heapLength = 0;
	makePriorityQueue(heapArray, &heapLength);

	//	while Q != 0
	while(heapLength > 0){	

		//		do u <- extractMin(Q)
		if (DBG_LV1) printArray(heapArray, heapLength);
		int vertexIndex = heapExtractMin(heapArray, &heapLength);
		debug(DBG_LV1, '[!]vertex[%d] Weight: %d\n', vertexIndex, vertices[vertexIndex].weight);
		if (DBG_LV1) printArray(heapArray, heapLength);		

		//S <- S U {u}
		addVertexToList(vertexList, &vertices[vertexIndex]);

		//		for each vertex v e Adj[u]
		struct AdjList *tempAdj;
		tempAdj = adjList[vertexIndex];
		while(tempAdj != NULL){
			//			do relax(u, v, w);
			relax(vertexIndex, tempAdj->vertexPointer->id, tempAdj->edgeIndex);
			tempAdj = tempAdj->next;
		}
		vertices[vertexIndex].visited = TRUE;
	}

}	

void initializeSingleSource(void){
	debug(DBG_LV0, 'initializeSingleSource()');	

	int i;
	for(i = 0; i < numVertices; ++i){
		vertices[i].id = i;
		vertices[i].weight = INT_MAX;
		vertices[i].predecessor = NULL;	// p[v] predecessor that is either another vertex or NULL
		vertices[i].visited = FALSE;
	}
	vertices[0].weight = 0;

	if (DBG_LV1) printVertices();

	buildAdjacentVertexList();	

	if (DBG_LV1){
		debug(DBG_LV1, '*List of all adj. vertices*');
		for (i = 0; i < numVertices; ++i)
			printAdjList(i);
	}

}

void printVertices(void){
	debug(DBG_LV0, 'printVertices()');  

	printf('[ ]');
	int i;
	for (i = 0; i < numVertices; ++i)
		printf('[%d]', i);

	if (DBG_LV1){
		printf('\n[i]');
		for (i = 0; i < numVertices; ++i)
			printf(' %d ' , vertices[i].id);
	}

	printf('\n[W]');
	for (i = 0; i < numVertices; ++i)
		if (vertices[i].weight == INT_MAX){
			printf(' ! ');
		}else{
			printf(' %d ' , vertices[i].weight);
		}

	if(DBG_LV1){
		printf('\n[*]');
		for (i = 0; i < numVertices; ++i)
			if (vertices[i].predecessor == NULL){
				printf(' N ');
			}else{
				printf(' %d ' , (int)vertices[i].predecessor->id);
			}
	}

	if(DBG_LV1){
		printf('\n[V]');
		for (i = 0; i < numVertices; ++i)
			if (vertices[i].visited == TRUE){
				printf(' Y ');
			}else{
				printf(' N ');
			}
	}

	printf('\n');
}

void buildAdjacentVertexList(void){
	debug(DBG_LV0, 'buildAdjacentVertexList()');

	int vertexIndex;
	for (vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex){
		insertAdjVerticesOf(vertexIndex);
	}
}

void insertAdjVerticesOf(int vertexIndex){
	debug(DBG_LV0, 'insertAdjVerticesOf(vertexIndex: %d)', vertexIndex);	

	debug(DBG_LV1, ' Searching for adjacent Vertices');
	int edgeIndex;
	for (edgeIndex = 0; edgeIndex < numEdges; ++edgeIndex){

		int startVertex = edges[edgeIndex].startVertex;
		int endVertex = edges[edgeIndex].endVertex;
		debug(DBG_LV1, '  Edge[%d](%d <%d> %d)', edgeIndex, startVertex, edges[edgeIndex].length, endVertex);

		debug(DBG_LV1, '  (startVertex (%d) == (%d) vertexIndex)?', startVertex, vertexIndex);
		if (startVertex == vertexIndex){
			debug(DBG_LV1, '   YES');
			insertAdjVertex(vertexIndex, endVertex, edgeIndex);
			insertAdjVertex(endVertex, vertexIndex, edgeIndex);
		}
	}
	if(DBG_LV1) printAdjList(vertexIndex);
}

void insertAdjVertex(int vertexIndex, int adjVertexIndex, int edgeIndex){

	struct AdjList *headAdj;
	headAdj = adjList[vertexIndex];	

	struct AdjList *newAdj = (struct AdjList *) malloc(sizeof(struct AdjList));
	newAdj->vertexPointer = &vertices[adjVertexIndex];
	newAdj->edgeIndex = edgeIndex;
	newAdj->next = NULL;

	if (headAdj == NULL){
		newAdj->next = adjList[vertexIndex];
		adjList[vertexIndex] = newAdj;
	}else{
		struct AdjList *currentAdj = adjList[vertexIndex];
		while (currentAdj->next != NULL)
			currentAdj = currentAdj->next;
		newAdj->next = currentAdj->next;
		currentAdj->next = newAdj;
	}
}

void printAdjList(int vertexIndex){
	debug(DBG_LV0, '**printAdjList(vertexIndex: %d)', vertexIndex);	

	debug(DBG_LV1, 'Adjacent Vertices of Vertex: %d', vertexIndex);

	struct AdjList *tempAdj;
	tempAdj = adjList[vertexIndex];	

	if (tempAdj == NULL){
		debug(DBG_LV1, ' tempAdj is empty');
	}else{		

		printf('[%d]', vertexIndex);
		int i = 0;
		while(tempAdj != NULL){
			printf('[%d]', i++);
			tempAdj = tempAdj->next;
		}

		printf('\n[i]');
		tempAdj = adjList[vertexIndex];
		while(tempAdj != NULL){
			printf(' %d ', tempAdj->vertexPointer->id);
			tempAdj = tempAdj->next;
		}

		printf('\n[W]');
		tempAdj = adjList[vertexIndex];
		while(tempAdj != NULL){
			if (tempAdj->vertexPointer->weight == INT_MAX){
				printf(' ! ');
			}else{
				printf(' %d ' , tempAdj->vertexPointer->weight);
			}
			tempAdj = tempAdj->next;
		}

		printf('\n[*]');
		tempAdj = adjList[vertexIndex];
		while(tempAdj != NULL){
			if (tempAdj->vertexPointer->predecessor == NULL){
				printf(' N ');
			}else{
				printf(' %d ' , tempAdj->vertexPointer->predecessor->id);
			}
			tempAdj = tempAdj->next;
		}

		printf('\n[V]');
		tempAdj = adjList[vertexIndex];
		while(tempAdj != NULL){
			if (tempAdj->vertexPointer->visited == TRUE){
				printf(' Y ');
			}else{
				printf(' N ');
			}
			tempAdj = tempAdj->next;
		}

		printf('\n');
	}
}

void makePriorityQueue(int heapArray[], int *length){
	debug(DBG_LV0, 'makePriorityQueue(length: %d)', *length);

	int i;
	for (i = 0; i < numVertices; ++i)
		heapArray[i] = i;

	*length = numVertices;
	if (DBG_LV1) printArray(heapArray, *length);
	buildMinHeap(heapArray, *length);
	if (DBG_LV1) printArray(heapArray, *length);
	if (DBG_LV1) printVertices();
}

void printArray(int array[], int length){
	debug(DBG_LV0, 'printArray(length: %d)', length);

	int i;
	for (i = 0; i < length; ++i)
		printf('[%d]', i);

	printf('\n');
	for (i = 0; i < length; ++i)
		printf(' %d ', array[i]);
	printf('\n');
}

void buildMinHeap(int heapArray[], int length){
	debug(DBG_LV0, 'buildMinHeap(length: %d)', length);

	int heapSize = length;

	int index;
	for (index = DIV_BY_2(length); index > -1; --index)
		minHeapify(heapArray, index, heapSize);
}

void minHeapify(int heapArray[], int index, int heapSize){
	debug(DBG_LV2, 'minHeapify(index: %d, heapSize: %d)', index, heapSize);

	int smallestIndex = index;
	int leftIndex = LEFT(index);
	int rightIndex = RIGHT(index);
	debug(DBG_LV1, '-SmallestIndex: %d, leftIndex: %d, rightIndex: %d', smallestIndex, leftIndex, rightIndex);

	if (leftIndex <= heapSize && rightIndex <= heapSize){

		unsigned int indexValue = vertices[heapArray[index]].weight;
		debug(DBG_LV1,
					'INDEX: vertices[heapArray[%d]: %d].id: %d, .weight: %d',
					index, heapArray[index], vertices[heapArray[index]].id,
					indexValue);

		unsigned int leftValue = vertices[heapArray[leftIndex]].weight;
		debug(DBG_LV1,
					'LEFT VALUE: vertices[heapArray[%d]: %d].id: %d, .weight: %d',
					leftIndex, heapArray[leftIndex], vertices[heapArray[leftIndex]].id,
					leftValue);

		if ((leftIndex < heapSize) && (leftValue < indexValue))
			smallestIndex = leftIndex;

		debug(DBG_LV1, 'smallestIndex: %d', smallestIndex);

		unsigned int rightValue = vertices[heapArray[rightIndex]].weight;

		debug(DBG_LV1,
					'LEFT VALUE: vertices[heapArray[%d]: %d].id: %d, .weight: %d',
					rightIndex, heapArray[rightIndex], vertices[heapArray[rightIndex]].id,
					rightValue);

		if ((rightIndex < heapSize) && (rightValue < indexValue))
			smallestIndex = rightIndex;

		debug(DBG_LV1, 'smallestIndex: %d', smallestIndex);

		if (smallestIndex != index){
			exchange(&heapArray[index], &heapArray[smallestIndex]);
			minHeapify(heapArray, smallestIndex, heapSize);
		}
	}
}

int heapExtractMin(int heapArray[], int *heapSize){
	debug(DBG_LV0, 'heapExtractMin(heapSize: %d)', *heapSize);

	if (*heapSize < 1)
		errorDoExit('Heap Underflow');

	buildMinHeap(heapArray, *heapSize);

	int min = heapArray[0];
	--*heapSize;
	heapArray[0] = heapArray[*heapSize];
	minHeapify(heapArray, 1, *heapSize);

	return min;
}

void exchange(int *a, int *b){
	debug(DBG_LV3, 'exchange(a: %d, b: %d)', *a, *b);

		int temp;
		temp = *a;
		*a = *b;
		*b = temp;
}

void addVertexToList(struct AdjList *vertexList, struct Vertex *vertex){
	debug(DBG_LV0, 'addVertexToList()');	

	struct AdjList *newAdj = (struct AdjList *) malloc(sizeof(struct AdjList));
	newAdj->vertexPointer = vertex;
	if (vertexList == NULL){
		newAdj->next = vertexList;
		vertexList = newAdj;
	}else{
		struct AdjList *currentAdj = vertexList;
		while (currentAdj->next != NULL)
			currentAdj = currentAdj->next;
		newAdj->next = currentAdj->next;
		currentAdj->next = newAdj;
	}
}

void relax(int startVertex, int endVertex, int edgeIndex){
	debug(DBG_LV0, 'relax(startVertex: %d, endVerted: %d, edgeIndex: %d)', startVertex, endVertex, edgeIndex);	

	unsigned int weight = vertices[startVertex].weight + edges[edgeIndex].length;

	debug (DBG_LV1, 'vertices[%d].weight(%d) > (%d)weight', endVertex, vertices[endVertex].weight, weight);
	if (vertices[endVertex].weight > weight){
		vertices[endVertex].weight = weight;
		vertices[endVertex].predecessor = &vertices[startVertex];
	}
}	

void debug(int debugLevel, char *fmt, ...){
	if (debugLevel){
		va_list argp;
		fprintf(stdout, '[DBG] ');
		va_start(argp, fmt);
		vfprintf(stdout, fmt, argp);
		va_end(argp);
		fprintf(stdout, '\n');
	}
}

void errorDoExit(char *fmt, ...){
	va_list argp;
	fprintf(stderr, '[Error] ');
	va_start(argp, fmt);
	vfprintf(stderr, fmt, argp);
	va_end(argp);
	if (errno){
		fprintf(stderr, '=> %s\n', strerror(errno));
	}else{
		fprintf(stderr, '\n');
	}
	exit(1);
}

input.txt:

8 11
0 1 1
4 5 1
1 5 2
2 5 2
5 6 2
0 3 2
3 4 3
5 7 3
4 2 4
4 6 4
1 2 5

If you encounter any problems or errors, please let me know by providing an example of the code, input, output, and an explanation. Thanks.

Share
Leave a comment

Example of Kurskay’s Algorithm using Disjoint Sets and Heap

NOTIFICATION: These examples are provided for educational purposes. The use of this code and/or information is under your own responsibility and risk. The information and/or code is given ‘as is’. I do not take responsibilities of how they are used.

Example of Kurskay’s algorithm using disjoint sets and heap.

kurskay_djoinset_heap.c:

/*
 * Program: 08
 * Author: Alejandro G. Carlstein
 * Description: Applying Kurskay's Algorithm using Disjoint Sets
 */

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <malloc.h>

#define MAX_EDGES 100001
#define MAX_VERTICES  500001
#define MAX_HEAP 100001
#define LEFT(i) ((i << 1) + 1)
#define RIGHT(i) ((i << 1) + 2)
#define PARENT(i) (((i + 1) >> 1) - 1)
#define DIV_BY_2(i) (i >> 1)
#define ROOT_INDEX 0

#define DBG_LV0 0
#define DBG_LV1 0
#define DBG_LV2 0
#define DBG_LV3 0

struct Vertex{
	int id;
	int rank;
	struct Vertex *parent;
};

struct Edge{
  struct Vertex *startVertex;
  struct Vertex *endVertex;
  int length;
};

struct Edge edges[MAX_EDGES];
struct Vertex vertices[MAX_VERTICES];
int heap[MAX_EDGES];

void scanEdges(void);
void debug(const char *message, int isDebugging);
void printEdges(struct Edge edges[], int length);
void initHeap(void);
int *mstKruskal(int *numEdges);
void printVertices(struct Vertex vertices[]);
void heapSort(int array[], int length);
void buildMinHeap(int array[], int heapSize);
void minHeapify(int array[], int index, int heapSize);
void exchange(int *a, int *b);
void printArray(int array[], int length);
void makeSet(struct Vertex *vertex);
struct Vertex* findSet(struct Vertex *vertex);
void unionTrees(struct Vertex *vertexX, struct Vertex *vertexY);
void link(struct Vertex *vertexX, struct Vertex *vertexY);
void printEdgesUsingHeapArray(int heapArray[], int length);
void printWeightOfTree(int heapArray[], int length);

int numVertices;
int numEdges;

int main(int argc, char* argv[]){

	scanEdges();
	initHeap();
	int length = numEdges;
 	int *arrayHeapEdges;
 	arrayHeapEdges = mstKruskal(&length);

 	if (DBG_LV1) printArray(arrayHeapEdges, length);

 	if(DBG_LV1) printVertices(vertices);

	if (DBG_LV1) printEdgesUsingHeapArray(arrayHeapEdges, length);		

	printWeightOfTree(arrayHeapEdges, length);

	free(arrayHeapEdges);

	return 0;

}

void scanEdges(void){
	debug('scanEdges()', DBG_LV0);

	scanf('%d %d', &numVertices, &numEdges);

	if (DBG_LV1) printf('numVertices: %d, numEdges: %d\n', numVertices, numEdges);

	int i;
	int startVertexId = -1;
	int endVertexId = -1;
	for (i = 0;
			 scanf('%d %d %d', &startVertexId, &endVertexId, &edges[i].length) == 1 ||
			 			 i < numEdges;
			 ++i){

		if (DBG_LV2)
			printf('startVertexId: %d, endVertexId: %d\n', startVertexId, endVertexId);

		if (startVertexId >= numVertices ||
				endVertexId >= numVertices){
			fprintf(stderr, 'Error: Vertex id is outside the maximum range of vertices\n');
			exit(1);
		}

		vertices[startVertexId].id = startVertexId;
		edges[i].startVertex = &vertices[startVertexId];

		vertices[endVertexId].id = endVertexId;
		edges[i].endVertex = &vertices[endVertexId];

		if(DBG_LV2)
			printf('edges[%d].startVertex->id: %d, edges[%d].endVertex->id: %d\n',
						 i, edges[i].startVertex->id, i, edges[i].endVertex->id);

	}

	if (DBG_LV1)
		printEdges(edges, numEdges);

}

void debug(const char *message, int isDebugging){
	if (isDebugging) printf('%s\n', message);
}

void printEdges(struct Edge edges[], int length){
	debug('printEdges()', DBG_LV0);

	printf('Edges: \n');
	int i;
	for (i = 0; i < length; ++i)
		printf('%d(%d <%d> %d) ',
					 i, edges[i].startVertex->id, edges[i].length, edges[i].endVertex->id);

		printf('\n');
}

void initHeap(void){
	debug('initHeap()', DBG_LV0);

	int i;

	for (i = 0; i < numEdges; ++i)
		heap[i] = i;
}

int *mstKruskal(int *numEdges){
	debug('mstKruskal()', DBG_LV0);	

	// A <- 0
	int *arrayEdgesIndex = (int*) malloc(*numEdges * sizeof(int));

	int vertexIndex;
	for (vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex)
		makeSet(&vertices[vertexIndex]);

	if (DBG_LV1) printVertices(vertices);

	// Sort edges into nondecreasing order by weight
	heapSort(heap, *numEdges);

	int index = 0;
	int edgeIndex;
	for (edgeIndex = 0; edgeIndex < *numEdges; ++edgeIndex){

		if (DBG_LV2)
			printf('V: %d\n', (int)findSet(edges[heap[edgeIndex]].startVertex));

		if ((int)findSet(edges[heap[edgeIndex]].startVertex) !=
				(int)findSet(edges[heap[edgeIndex]].endVertex)  ){

			if (DBG_LV2)
				printf('findset(edges[%d]) = findset(edges[%d])\n',
							 heap[edgeIndex], heap[edgeIndex]);

			// A <- A U {(u,v)}
			arrayEdgesIndex[index++] = heap[edgeIndex];	

			unionTrees(edges[heap[edgeIndex]].startVertex,
								 edges[heap[edgeIndex]].endVertex);
		}

	}

	*numEdges = index;

	if (DBG_LV1) printArray(arrayEdgesIndex, index);

	return (arrayEdgesIndex);
}

void printVertices(struct Vertex vertices[]){
	debug('printVertices()', DBG_LV0);

	int i;
	for (i = 0; i < numVertices; ++i)
		printf('(%d)[%d] Id: %d, Rank: %d, *Parent:%d \n',
					 (int)&vertices[i], i, vertices[i].id, vertices[i].rank, (int)vertices[i].parent);

	printf('\n');
}

void heapSort(int array[], int length){
	if (DBG_LV0) printf('heapSort(length: %d)\n', length);

	buildMinHeap(array, length);

	int i;
	int	heap_size = length;
	for (i = length - 1 ; i >= 0; --i){
		exchange(&array[0], &array[i]);
		heap_size--;
		minHeapify(array, 0, heap_size);
	}

}

void buildMinHeap(int array[], int heapSize){
	debug('buildMinHeap', DBG_LV0);

	int index;
	for (index = DIV_BY_2(heapSize); index >= ROOT_INDEX; --index)
		minHeapify(array, index, heapSize);
}

void minHeapify(int array[], int index, int heapSize){
	debug('minHeapify()', DBG_LV0);

	int left, right, smallest;

	smallest = index;
	left = LEFT(index);
	right = RIGHT(index);	

	if (left < heapSize &&
		  edges[array[left]].length > edges[array[index]].length)
		smallest = left;	

	if (right < heapSize &&
		  edges[array[right]].length > edges[array[smallest]].length)
		smallest = right;

	if (smallest != index){
		exchange(&array[index], &array[smallest]);
		minHeapify(array, smallest, heapSize);
	}

}

void exchange(int *a, int *b){
	debug('exchange()', DBG_LV3);

	int temp;
	temp = *a;
	*a = *b;
	*b = temp;
}

void makeSet(struct Vertex *vertex){
	debug('makeSet()', DBG_LV0);

	vertex->parent = vertex;
	vertex->rank = 0;
}

struct Vertex* findSet(struct Vertex *vertex){
	debug('findSet()', DBG_LV0);

	if (vertex == NULL)
		debug('Vertex is NULL', DBG_LV1);

	if (vertex != vertex->parent){
		vertex->parent = findSet(vertex->parent);
	}	

	return (vertex->parent);
}

void unionTrees(struct Vertex *vertexX, struct Vertex *vertexY){
	debug('unionTrees()', DBG_LV0);

	link(findSet(vertexX), findSet(vertexY));
}

void link(struct Vertex *vertexX, struct Vertex *vertexY){
	debug('link()', DBG_LV0);

	if (vertexX->rank > vertexY->rank){
		vertexY->parent = vertexX;
	}else{
		vertexX->parent = vertexY;
		if (vertexX->rank == vertexY->rank)
			++vertexY->rank;
	}

}

void printArray(int array[], int length){
	debug('printArray()', DBG_LV0);

	int i;

	for (i = 0; i < length; ++i)
		printf('[%d]', i);

	printf('\n');

	for (i = 0; i < length; ++i)
		printf(' %d ', array[i]);

	if (DBG_LV1) printf('\n\n');
}

void printEdgesUsingHeapArray(int heapArray[], int length){
	debug('printEdgesUsingHeapArray()', DBG_LV0);

	int i;
	for (i = 0; i < length; ++i)
		printf('%d-%d(%d) ',
					 edges[heapArray[i]].startVertex->id, edges[heapArray[i]].endVertex->id, (i + 1));
}

void printWeightOfTree(int heapArray[], int length){
	debug('printWeightOfTree()', DBG_LV0);

	int result = 0;
	int i;
	for (i = 0; i < length; ++i)
		result += edges[heapArray[i]].length;

	printf('%d\n', result);

}

input.txt:

4 7

0 1 5

0 2 4

1 3 3

2 3 2

3 0 1

2 1 10

0 3 20

If you encounter any problems or errors, please let me know by providing an example of the code, input, output, and an explanation. Thanks.

Share
Leave a comment

Example of Huffman Algorithm by using Heap

Example of Huffman algorithm by using heap.

NOTIFICATION: These examples are provided for educational purposes. Using this code is under your own responsibility and risk. The code is given ‘as is’. I do not take responsibilities of how they are used.

huffman.c:

/* 
 * Program: Huffman using heap
 * Author: Alejandro G. Carlstein
 */

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#define MAX_CODE 1000000
#define MAX_LETTERS 4
#define MAX_HEAP 10
#define LEFT(i) ((i << 1) + 1)
#define RIGHT(i) ((i << 1) + 2)
#define PARENT(i) (((i + 1) >> 1) - 1)
#define DIV_BY_2(i) (i >> 1)
#define DBG_LV0 1
#define DBG_LV1 1
#define DBG_LV2 1
#define DBG_LV3 0
#define LETTER_A 65
#define DIR_LEFT '0'
#define DIR_RIGHT '1'

#define ROOT_INDEX 0

struct Data{
  int letter;
  int frequency;
  int left;
  int right;
  int parent;
}Data;

struct Data data[MAX_LETTERS];
int code[MAX_CODE][MAX_LETTERS];
int heap[MAX_HEAP];

void readInputLetters(void);
void readInputCode(void);
void printCodes(int *codes, int numCodes);
void printStructArray(struct Data array[], int length);
int huffman(void);
void buildMinHeap(int array[], int heapSize);
void minHeapify(int array[], int index, int heapSize);
int heapMin(int array[]);
int heapExtractMin(int array[], int *length);
void insertMinHeap(int array[], int value, int *length);
void exchange(int *a, int *b);
void printArray(int array[], int length);
int isLeft(struct Data array[], int indexLeft, int indexRight);
void test1();
void test2();

int num_letters;
int numCodes = 0;

int main(int argc, char* argv[]){

	readInputLetters();		

	readInputCode();

	if (DBG_LV3) printStructArray(data, num_letters);

	int i;
	for (i = 0; i < num_letters; ++i)
		heap[i] = i;

  printf('ROOT(huffman): %d \n', huffman());

	if (DBG_LV1) printStructArray(data, num_letters);

  //decodeMessage(data, num_letters, &code[0][0], numCodes);

	if (DBG_LV2) printf('\n');

	return 0;

}

void readInputLetters(void){
	if (DBG_LV0) printf('\nreadInputLetters()\n');

  for (num_letters = 0; num_letters < MAX_LETTERS; ++num_letters){       
    scanf('%d', &data[num_letters].frequency);
    data[num_letters].letter = LETTER_A + num_letters;
    data[num_letters].left = -1;
    data[num_letters].right = -1;
		data[num_letters].parent = -1;

    heap[num_letters] = -1;
  }

}

void readInputCode(void){
	if (DBG_LV0) printf('\nreadInputCode()\n');

	int c;
  int indexCode = 0;

  numCodes = 0;

  while ((c = getchar()) != EOF){

    if (c != ' ' && c != '\n'){
      if (DBG_LV3) printf('[%d][%d]%c{%d}\n', numCodes, indexCode, c, c);
      code[numCodes][indexCode] = (int)c;
      ++indexCode;
    }

    if (c == '\n'){
      code[numCodes][indexCode] = -1;
      if (DBG_LV3) printf('{{%d}}\n', code[numCodes][indexCode]);
      ++numCodes;
      indexCode = 0;

    }
  }

	if (DBG_LV3){
	  printf('CODES: \n');
	  printCodes(&code[0][0], numCodes);

  }

}

void printCodes(int *codes, int numCodes){
  if (DBG_LV2) printf('printCodes(numCodes: %d)\n', numCodes);

  int indexCode, index;
	int indexArray;

  for (indexCode = 0; indexCode < numCodes; ++indexCode){

		indexArray = indexCode * sizeof(int);

    for (index = 0; codes[indexArray + index] > -1 ; ++index){

      printf('[%d][%d]: %c(%d) \n', 
             indexArray, index, 
             codes[indexArray + index], codes[indexArray + index]);    

    }

    printf('\n');

  }

}

void printStructArray(struct Data array[], int length){
  if (DBG_LV0) printf('printStructArray()\n');

  int i;
  for (i = 0; i < length; ++i)
	  printf('[%d]%c - %d (L:%d, R:%d, P:%d) \n',
	         i, data[i].letter, data[i].frequency, data[i].left, data[i].right, data[i].parent);
}

int huffman(void){
	if (DBG_LV0) printf('\nHUFFMAN()\n');

	int length = num_letters;
	int i;
	int left;
	int right;
	int parent;
	int n = length;

	length++;

	printf('length: %d\n\n', length);

	if (DBG_LV1) printArray(heap, num_letters);

	for (i = 0; i < n - 1; ++i){

		left = heapExtractMin(heap, &length);

		printf('length: %d\n\n', length);

		right = heapExtractMin(heap, &length);

		parent = left + right;

		data[left].parent = parent;
		data[right].parent = parent;

		printf('length: %d\n\n', length);

		if (DBG_LV2){
			printf('left: %d, ', left);				
			printf('right: %d, ', right);
			printf('parent: %d\n', parent);
			printArray(heap, length);		
		}

		insertMinHeap(heap, parent, &length);

		printf('length: %d\n\n', length);
		//--*length;

	}

	if (DBG_LV1) printArray(heap, num_letters);

	return heapExtractMin(heap, &length);
}

void buildMinHeap(int array[], int heapSize){

	int index;

	for (index = DIV_BY_2(heapSize); index >= ROOT_INDEX; --index){

		minHeapify(array, index, heapSize);

	}

}

void minHeapify(int array[], int index, int heapSize){

	int left, right, smallest;

	smallest = index;
	left = LEFT(index);
	right = RIGHT(index);	

	// Find smallest value
	if (left < heapSize && array[left] < array[index])
		smallest = left;	

	if (right < heapSize && array[right] < array[smallest]) 
		smallest = right;

	if (smallest != index){

		// Exchange 
		exchange(&array[index], &array[smallest]);

		// Rebuild heap region		
		minHeapify(array, smallest, heapSize);	

	}

}

int heapMin(int array[]){
	return array[ROOT_INDEX];
}

int heapExtractMin(int array[], int *length){
	if (DBG_LV0) printf('heapExtractMin()\n');

	if (length < 0){
		printf('[X] Error: heap overflow!\n');
		return -1;
	}

	--*length;

	int heapSize = *length;

	int min = array[ROOT_INDEX];

	--heapSize;

	printf('exchange: array[%d]: %d, array[%d]:%d \n',
				 ROOT_INDEX, array[ROOT_INDEX],
				 heapSize, array[heapSize]);

	exchange(&array[ROOT_INDEX], &array[heapSize]);

	--heapSize;

	minHeapify(array, ROOT_INDEX, heapSize);

	return min;
}

void insertMinHeap(int array[], int value, int *length){

	if (DBG_LV0) printf('insertMinHeap(value: %d, length: %d)\n',
											value, *length);

	int heapSize = *length;

	++*length;

	array[heapSize] = INT_MAX;

	if (value > array[heapSize]){
		printf('[X] Error: new value is bigger than biggest element!\n');
	}else{

		array[heapSize] = value;

		if (DBG_LV2) printArray(array, *length);

		while (heapSize > ROOT_INDEX && 
					 array[PARENT(heapSize)] > array[heapSize]){

			exchange(&array[heapSize], &array[PARENT(heapSize)]);

			heapSize = PARENT(heapSize);

		}

	}

}

void exchange(int *a, int *b){
		if (DBG_LV3) printf('exchange()\n');

		int temp;
		temp = *a;
		*a = *b;
		*b = temp;
}

void printArray(int array[], int length){
	if (DBG_LV0) printf('printArray()\n');

	int i;

	for (i = 0; i < length; ++i)
		printf('[%d]', i);

	printf('\n');

	for (i = 0; i < length; ++i)
		printf(' %d ', array[i]);

	if (DBG_LV1) printf('\n\n');
}

int isLeft(struct Data array[], int indexLeft, int indexRight){
	if (DBG_LV0) printf('isLeft()\n');

	if (array[indexLeft].frequency == array[indexRight].frequency){

		 	if (array[indexLeft].letter < array[indexRight].letter){
		 		return DIR_LEFT;
		 	}else{
		 		return DIR_RIGHT;
		 	}

	}else if (array[indexLeft].frequency < array[indexRight].frequency){
		return DIR_LEFT;	 	
	}else{
		return DIR_RIGHT;
	} 

}

void test1(){
	if (DBG_LV1) printf('test1()\n');

	int i, length = 5;

	if(DBG_LV1)	printf('BUILD HEAP ARRAY:\n');
	for(i = 0; i < length; ++i){
		heap[i] = i * 2;
		printf('heap[%d]: %d \n', i, heap[i]);
	}
	heap[4] = 1;

	buildMinHeap(heap, length);

	printArray(heap, length);

	insertMinHeap(heap, 3, &length);

	printArray(heap, length);
}

void test2(){

	int heapLen = num_letters;

	printf('heapLen: %d\n', heapLen);

	printArray(heap, heapLen);

	int result1, result2;

	printf('TEST HEAPEXTRACTMIN:\n');
	result1 = heapExtractMin(heap, &heapLen);
  printf('result1: %d\n', result1);
	printArray(heap, heapLen);

	printf('heapLen: %d\n', heapLen);

	result2 = heapExtractMin(heap, &heapLen);
  printf('result2: %d\n', result2);
	printArray(heap, heapLen);

	printf('heapLen: %d\n', heapLen);

}

input.txt:

1 
2 
3 
4 
1 0 0 
1 0 1 
1 1 
0

If you encounter any problems or errors, please let me know by providing an example of the code, input, output, and an explanation. Thanks.

Share
Leave a comment