Commit 4d3a4d79 authored by Dominik Widhalm's avatar Dominik Widhalm
Browse files

Added example solutions for task 6.10

parent 45031af5
/******************************************************************************
* C PROGRAMMING *
* BASIC EXERCISES - EXAMPLE SOLUTIONS *
* *
* Task_6.10: Priority Queue *
* Author: Dominik Widhalm *
* Email: dominik.widhalm@technikum-wien.at *
* Date: 2017-08-23 *
* *
******************************************************************************/
/***** INCLUDES ***************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/***** MACROS *****************************************************************/
// Maximum length of strings
#define STRING_MAX 40
// Maximum queue size
#define QUEUE_MAX 10
/***** TYPEDEFS ***************************************************************/
/* Enumeration type for insert & remove return value */
typedef enum {OK, EMPTY, FULL, OLDREMOVED} retval_t;
/* Struct type for the single linked list */
typedef struct element {
// ID
int id;
// String
char string[STRING_MAX];
// priority
int priority;
// Pointer to next element
struct element *next;
} element_t;
/***** FUNCTION PROTOTYPES ****************************************************/
retval_t queue_insert (element_t **head, char *string, int priority);
retval_t queue_remove (element_t **head, char *string);
void queue_print (element_t *head);
/***** LOCAL FUNCTIONS ********************************************************/
/******************************************************************************
* queue_insert *
* @brief Function to insert a string in the queue. *
* *
* This function first checks if the queue is full. If not, it inserts *
* the given string in the queue (depending on priority). if the queue *
* is already full, the element is only inserted if the new element has *
* a higher priority than one of the elements in the list. In this case *
* the last element is removed. *
* *
* @param head Pointer to pointer to the first queue element *
* @param string Pointer to the desired string *
* @param priority Priority of the new element *
* @retval OK Pushing successful *
* @retval FULL Pushing failed -- stack is full *
* @retval OLDREMOVED Pushing successful, but old element removed *
******************************************************************************/
retval_t queue_insert (element_t **head, char *string, int priority) {
/* Temporary pointer to the current queue element */
element_t *curr = *head;
/* Temporary variable for the queue size */
int size = 0;
/* Allocate memory for the new command */
element_t *new = (element_t*)malloc(sizeof(element_t));
/* Copy the string */
strcpy(new->string,string);
/* Copy the priority */
new->priority = priority;
/* Set the pointers accordingly */
new->next = NULL;
/* Retrieve the current queue size */
while (curr != NULL) {
/* Increase queue size counter */
size++;
/* Go to next element */
curr = curr->next;
}
/* Check if the list is empty */
if (*head == NULL) {
/* Add new element as first and only element */
*head = new;
/* If the list is not empty */
} else {
/* Check if new element will be on first position */
if (new->priority > (*head)->priority) {
/* Next pointer of new element is the current head address */
new->next = *head;
/* Set head to the new element */
*head = new;
} else {
/* Search for the position to add the new entry afterwards */
curr = *head;
while (curr->next != NULL) {
/* Check if the next element has a greater priority */
if (new->priority > curr->next->priority) {
/* Add new element after this position */
break;
}
/* Set curr to next element */
curr = curr->next;
}
/* Check if found position is last position */
if (curr->next == NULL) {
/* Check if list has already reached maximum size */
if (size >= QUEUE_MAX) {
/* Free previously allocated memory */
free(new);
/* Cannot insert, queue already full */
return FULL;
} else {
/* Set next pointer of currently last element to new element */
curr->next = new;
}
/* Otherwise element is somewhere in between */
} else {
/* Set the next pointer of the new element to the next element in list */
new->next = curr->next;
/* Set next pointer of currently last element to new element */
curr->next = new;
/* Check if list was already full */
if (size >= QUEUE_MAX) {
/* Temporary pointer to the 2nd last element */
element_t *last = *head;
/* Go to the currently last element */
curr = *head;
while (curr->next != NULL) {
/* Check if next element is valid element */
if (curr->next != NULL) {
/* Store current address as last one */
last = curr;
}
/* Go to next element */
curr = curr->next;
}
/* Remove last element */
last->next = NULL;
/* Free allocated memory */
free(curr);
/* Return according status */
return OLDREMOVED;
}
}
}
}
/* Inserting successful */
return OK;
}
/******************************************************************************
* queue_remove *
* @brief Function to remove a string from the queue. *
* *
* This function first checks if the queue is empty. If not, it returns *
* and removes the next element from the queue. *
* *
* @param head Pointer to pointer to the first queue element *
* @param string Pointer to the read back string *
* @retval OK Removing successful *
* @retval FULL Removing failed -- queue is empty *
******************************************************************************/
retval_t queue_remove (element_t **head, char *string) {
/* Temporary pointer to the current queue element */
element_t *curr = *head;
/* Check if queue is empty */
if (curr == NULL) {
/* Queue is empty, cannot remove */
return EMPTY;
}
/* Get the string from the current top element */
strcpy(string,curr->string);
/* Remove first element from the queue */
*head = curr->next;
free(curr);
/* Removing successful */
return OK;
}
/******************************************************************************
* queue_print *
* @brief Function to print the current queue. *
* *
* This function prints the current content of the queue (recursively). *
* *
* @param head Pointer to the first stack element *
******************************************************************************/
void queue_print (element_t *head) {
/* Print list recursively */
if (head != NULL) {
/* Print current element */
printf("(%d) -> \"%s\"\n",head->priority,head->string);
/* Call function with next element */
queue_print(head->next);
}
/* A void function has nothing to return */
return;
}
/***** MAIN ROUTINE ***********************************************************/
int main (void) {
/*** Local Variables ***/
element_t *head = NULL;
element_t *next;
retval_t ret;
char select = 'x';
char string[STRING_MAX];
int priority;
/* Do as long as the users wants to do an action */
do {
/* Ask the user to select an action */
printf("\nWant do you want to do?\n");
printf("(i) insert an element\n");
printf("(r) remove next element\n");
printf("(p) print current queue\n");
printf("(x) exit\n");
printf("Input: ");
/* Read in the user's input */
scanf(" %c",&select);
/* Do required action */
switch (select) {
case 'i':
/** Insert a string **/
/* Ask the user to input the command */
printf("Please enter the desired string: ");
/* Read in the user's input */
scanf("%s",string);
/* Ask the user to input the priority */
printf("Please enter the desired priority: ");
/* Read in the user's input */
scanf("%d",&priority);
/* (Try to) add the string to the queue */
ret = queue_insert(&head,string,priority);
if (ret == FULL) {
/* Cannot be added, queue is full */
printf("\nFAILED -- QUEUE is already full!\n");
} else if (ret == OLDREMOVED) {
/* Added, but an old element was removed */
printf("\nINSERTED -- But an old element was removed!\n");
} else {
/* String has been successfully added */
printf("\nINSERTED\n");
}
/** Finished inserting **/
break;
case 'r':
/** Remove next element **/
/* (Try to) remove the next string from the queue */
if (queue_remove(&head,string) == EMPTY) {
/* Cannot remove, queue is empty */
printf("\nFAILED -- Queue is empty!\n");
} else {
/* String has been successfully removed */
printf("\nREMOVED: \"%s\"\n",string);
}
/** Finished removing **/
break;
case 'p':
/** Print the current queue */
if (head == NULL) {
printf("\n... Queue is empty ...\n");
} else {
printf("\n... Current queue ...\n");
queue_print(head);
}
/** Finished printing **/
break;
}
} while (select != 'x');
/* Release the allocated memory (use pointer "next" as helper) */
while (head != NULL) {
/* Save pointer to current element */
next = head;
/* Set head to the next element */
head = next->next;
/* Free memory of current element */
free(next);
}
/* Notify the user about the termination of the program */
printf("\nThe program will now be terminated...\n");
return 0; /* Return with Success (0) */
}
/******************************************************************************/
# Get the current path(s) (relevant directory on last position)
TASKPATH := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
CHPATH := $(dir $(TASKPATH:%/=%))
# Variables for text substitution
empty:=
slash:= /
space:= $(empty) $(empty)
task:= task_
ch:= ch_
# Get TASK number
TASK := $(subst $(slash),$(space),$(TASKPATH))
TASK := $(lastword $(TASK))
TASK := $(subst $(task),$(empty),$(TASK))
# Get CH number
CH := $(subst $(slash),$(space),$(CHPATH))
CH := $(lastword $(CH))
CH := $(subst $(ch),$(empty),$(CH))
# Specify SRD directory
SRCDIR = .
# Call superior makefile
include ../../makefile
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment