Added queue and updated README file.
This commit is contained in:
parent
46ca0a2b4b
commit
9ba3b79962
49
README.md
49
README.md
|
@ -26,12 +26,12 @@ int is_empty(Stack s);
|
|||
```
|
||||
|
||||
### Description
|
||||
The stack is probably the most basic storage structure, using the 'first-in, first-out' approach. To define a stack, the user must first know what type the stack is, either a primitive type, or a **struct**. To define a stack, you must first define the **STACK_TYPE** to *int*, *float*, *char*, or whatever type you wish. Then, include the *handystack* header file.
|
||||
The stack is probably the most basic storage structure, using the 'first-in, first-out' approach. To define a stack, the user must first know what type the stack is, either a primitive type, or a `struct`. To define a stack, you must first define the `STACK_TYPE` to *int*, *float*, *char*, or whatever type you wish. Then, include the *handystack* header file.
|
||||
```c
|
||||
#define STACK_TYPE int
|
||||
#include "handystack.h"
|
||||
```
|
||||
To define more than one stack, **STACK_TYPE** must first be undefined.
|
||||
To define more than one stack, `STACK_TYPE` must first be undefined.
|
||||
` #undef STACK_TYPE `
|
||||
Then you simply define the type, and include the header again. Do not try to define two of the same type, however, as that will give all sorts of nasty errors.
|
||||
|
||||
|
@ -44,7 +44,7 @@ double_stack myStack = new_double_stack();
|
|||
push_double_stack(45.000, &myStack);
|
||||
print_double_stack(myStack);
|
||||
```
|
||||
Notice that the function names are characteristic of the **STACK_TYPE** you've defined earlier? The functions have the following basic format:
|
||||
Notice that the function names are characteristic of the `STACK_TYPE` you've defined earlier? The functions have the following basic format:
|
||||
``` FUNCTION_ + STACK_TYPE + _stack ```
|
||||
Where `FUNCTION` is the name of the function.
|
||||
|
||||
|
@ -52,6 +52,49 @@ Where `FUNCTION` is the name of the function.
|
|||
|
||||
## Queue
|
||||
|
||||
### Functions
|
||||
|
||||
```c
|
||||
//Creates a new queue.
|
||||
queue* new();
|
||||
//Frees the queue.
|
||||
void free(Queue queue);
|
||||
//Returns the number of elements in the queue.
|
||||
int size(Queue queue);
|
||||
//Returns true if the queue is empty.
|
||||
int empty(Queue queue);
|
||||
//Adds an item to the queue.
|
||||
void enqueue(Queue *queue, QUEUE_TYPE item);
|
||||
//Dequeues an item from the queue.
|
||||
QUEUE_TYPE dequeue(Queue *queue);
|
||||
//Prints some information about the queue.
|
||||
void print(Queue queue);
|
||||
```
|
||||
|
||||
### Description
|
||||
The queue is a data structure in which items follow a *first-in, first out* pattern, so that the order in which an item is added is remembered. Items are added via `enqueue` and removed via `dequeue`. To define a queue, you must first define the `QUEUE_TYPE` to *int, float, char,* or whatever you wish. Then, include the *handyqueue* header file.
|
||||
```c
|
||||
#define QUEUE_TYPE int
|
||||
#include "handyqueue.h"
|
||||
```
|
||||
To define more than one queue, `QUEUE_TYPE` must first be undefined.
|
||||
`#undef QUEUE_TYPE`
|
||||
Then you can simply re-define the type, and include the header again.
|
||||
|
||||
### Example
|
||||
The following example creates a queue of integers, and queues many powers of two onto it, and then prints the characteristics of the queue, and outputs the first element in the queue.
|
||||
```c
|
||||
#define QUEUE_TYPE int
|
||||
#include "handyqueue.h"
|
||||
int_queue q = new_int_queue();
|
||||
for (int i = 2; i < 20000000; i *= 2){
|
||||
enqueue_int_queue(&q, i);
|
||||
}
|
||||
print_int_queue(q);
|
||||
printf("First Item in queue: %d\n", dequeue_int_queue(&q));
|
||||
free_int_queue(q);
|
||||
```
|
||||
|
||||
[Back to Top](#table-of-contents)
|
||||
|
||||
## Linked List
|
||||
|
|
|
@ -14,22 +14,116 @@ Please contact the author regarding bugs and/or feature requests.
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
Queue:
|
||||
A storage data structure which follows the rule 'first-in, first-out', and has special functions 'enqueue' and 'dequeue' to manipulate the queue.
|
||||
*/
|
||||
|
||||
/*
|
||||
Queue constants:
|
||||
*/
|
||||
#ifndef QUEUE_SIZE_DEFAULT
|
||||
#define QUEUE_SIZE_DEFAULT 64
|
||||
#endif
|
||||
|
||||
/*
|
||||
QUEUE: the queue type for a specific queue.
|
||||
*/
|
||||
#define QUEUE TEMPLATE(QUEUE_TYPE,queue)
|
||||
|
||||
/*
|
||||
Queue Structure:
|
||||
Each queue will contain an array of data, as well as a front, back, and size integer.
|
||||
*/
|
||||
typedef struct {
|
||||
QUEUE_TYPE* data;
|
||||
int back;
|
||||
int front;
|
||||
int size;
|
||||
int back;//The index after the last element of the queue.
|
||||
int front;//The index of the first element.
|
||||
int size;//The size of the data array.
|
||||
} QUEUE;
|
||||
|
||||
/*
|
||||
Queue Creation:
|
||||
Creates a new queue with a default size defined above.
|
||||
*/
|
||||
QUEUE TEMPLATE(new,QUEUE)(){
|
||||
QUEUE queue;
|
||||
queue.front = 0;
|
||||
queue.back = 0;
|
||||
queue.size = QUEUE_SIZE_DEFAULT;
|
||||
queue.data = malloc(queue.size*sizeof(QUEUE_TYPE));
|
||||
assert(queue.data != NULL);
|
||||
return queue;
|
||||
}
|
||||
|
||||
/*
|
||||
Queue deallocation:
|
||||
Safely deallocates memory assigned to the queue.
|
||||
*/
|
||||
void TEMPLATE(free,QUEUE)(QUEUE queue){
|
||||
free(queue.data);
|
||||
}
|
||||
|
||||
/*
|
||||
Size of the queue:
|
||||
returns the size of the queue. (Number of elements in the queue.)
|
||||
*/
|
||||
int TEMPLATE(size,QUEUE)(QUEUE queue){
|
||||
return queue.back-queue.front;
|
||||
}
|
||||
|
||||
/*
|
||||
Enqueue:
|
||||
Enqueues an item into the queue.
|
||||
*/
|
||||
void TEMPLATE(enqueue,QUEUE)(QUEUE *queue, QUEUE_TYPE item){
|
||||
//Ensure that enough memory is available.
|
||||
if (queue->back == queue->size){
|
||||
queue->data = realloc(queue->data, (queue->size*2)*sizeof(QUEUE_TYPE));
|
||||
assert(queue->data != NULL);
|
||||
}
|
||||
queue->data[queue->back] = item;
|
||||
queue->back++;
|
||||
}
|
||||
|
||||
/*
|
||||
Dequeue:
|
||||
Dequeues an item from the queue.
|
||||
*/
|
||||
QUEUE_TYPE TEMPLATE(dequeue,QUEUE)(QUEUE *queue){
|
||||
QUEUE_TYPE item = queue->data[queue->front];
|
||||
queue->front++;
|
||||
//Check to see if it is possible to shrink the array.
|
||||
if (queue->back - queue->front < queue->size/2){
|
||||
QUEUE_TYPE* newData = malloc((queue->size/2)*sizeof(QUEUE_TYPE));
|
||||
int size = queue->back - queue->front;
|
||||
assert(newData != NULL);
|
||||
memcpy(newData, queue->data + queue->front, size*sizeof(QUEUE_TYPE));
|
||||
free(queue->data);
|
||||
queue->data = newData;
|
||||
queue->size /= 2;
|
||||
queue->front = 0;
|
||||
queue->back = size;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/*
|
||||
Empty:
|
||||
Returns true if the queue is empty.
|
||||
*/
|
||||
int TEMPLATE(empty,QUEUE)(QUEUE queue){
|
||||
return (queue.back == queue.front);
|
||||
}
|
||||
|
||||
/*
|
||||
Print:
|
||||
Prints info about the queue, in well formatted fashion.
|
||||
*/
|
||||
void TEMPLATE(print,QUEUE)(QUEUE queue){
|
||||
printf("Queue: (Items: %d), (Size: %d), (Front: %d), (Back: %d)\n", TEMPLATE(size,QUEUE)(queue), queue.size, queue.front, queue.back);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -60,8 +60,8 @@ STACK_CONTAINER TEMPLATE(new,STACK_CONTAINER)(){
|
|||
Stack Deallocation:
|
||||
Safely deallocates memory assigned to the stack's list.
|
||||
*/
|
||||
void TEMPLATE(free,STACK_CONTAINER)(STACK_CONTAINER *s){
|
||||
free(s->items);
|
||||
void TEMPLATE(free,STACK_CONTAINER)(STACK_CONTAINER s){
|
||||
free(s.items);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
22
test.c
22
test.c
|
@ -8,6 +8,9 @@
|
|||
#define LIST_TYPE float
|
||||
#include "source/handylist.h"
|
||||
|
||||
#define QUEUE_TYPE int
|
||||
#include "source/handyqueue.h"
|
||||
|
||||
void printList(float_list* list){
|
||||
int size = size_float_list(list);
|
||||
for (int i = 0; i < size; i++){
|
||||
|
@ -19,19 +22,26 @@ void printList(float_list* list){
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
void printQueue(int_queue q){
|
||||
for (int i = q.front; i < q.back; i++){
|
||||
printf("\t%d. %d\n", i, q.data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]){
|
||||
|
||||
|
||||
double_stack s = new_double_stack();
|
||||
push_double_stack(42.5, &s);
|
||||
print_double_stack(s);
|
||||
free_double_stack(s);
|
||||
|
||||
float_list* l = new_float_list(-1, NULL);
|
||||
printf("Start.\n");
|
||||
for (int i = 0; i < 100000000; i++){
|
||||
l = add_float_list(i*i, l);
|
||||
int_queue q = new_int_queue();
|
||||
for (int i = 2; i < 20000000; i *= 2){
|
||||
enqueue_int_queue(&q, i);
|
||||
}
|
||||
printf("End.\n");
|
||||
free_float_list(l);
|
||||
print_int_queue(q);
|
||||
printf("First Item in queue: %d\n", dequeue_int_queue(&q));
|
||||
free_int_queue(q);
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue