LO27/LibMatrix/list.c

354 lines
7.2 KiB
C
Raw Permalink Normal View History

2016-12-29 15:09:39 +00:00
/*
* This is a cellular automaton library
*
* Copyright (C) 2016-2017 Antoine BARTUCCIO, Jean POREE DE RIDDER
*
* Licensed under the MIT License,(the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* hhttps://opensource.org/licenses/MIT
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
2016-12-10 01:28:10 +00:00
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
2016-12-10 04:04:13 +00:00
#include <CellElement.h>
2016-12-10 01:28:10 +00:00
#include <list.h>
#define SUCCESS 0
#define FAILURE 1
2017-01-01 15:35:34 +00:00
List * createList() {
2016-12-10 01:28:10 +00:00
List *list = malloc(sizeof(*list));
if(list != NULL){
list->head = NULL;
list->tail = NULL;
list->size = 0;
}
return list;
}
int unshift(List *list, cellElement *data){
int ok = SUCCESS;
/* Create a new element */
ListElement *newElement = malloc(sizeof(*newElement));
2016-12-11 00:25:35 +00:00
if (list != NULL && newElement != NULL){
newElement->data = data;
2016-12-23 13:08:10 +00:00
newElement->pos = -1;
2016-12-10 01:28:10 +00:00
/* Insert the element at the begining of the list */
newElement->previous = NULL;
if (list->head != NULL){
list->head->previous = newElement;
} else {
list->tail = newElement;
}
newElement->next = list->head;
list->head = newElement;
list->size = list->size + 1;
} else {
if (newElement != NULL){
free(newElement);
}
ok = FAILURE;
}
return ok;
}
int push(List *list, cellElement *data){
int ok = SUCCESS;
ListElement *newElement = malloc(sizeof(*newElement));
2016-12-11 00:25:35 +00:00
if(list != NULL && newElement != NULL){
newElement->data = data;
2016-12-23 13:08:10 +00:00
newElement->pos = -1;
2016-12-10 01:28:10 +00:00
newElement->next = NULL;
if (list->tail == NULL){
list->tail = newElement;
list->head = newElement;
newElement->previous = NULL;
} else {
newElement->previous = list->tail;
list->tail->next = newElement;
list->tail = newElement;
}
list->size = list->size + 1;
} else {
if (newElement != NULL){
free(newElement);
}
ok = FAILURE;
}
return ok;
}
2017-01-01 15:35:34 +00:00
ListElement * getElement(List *list, int nb){
2016-12-10 01:28:10 +00:00
ListElement *current = NULL;
int i;
if (list != NULL && (nb < list->size || -nb < list->size)){
if (nb == list->size -1 || nb == -1){
current = list->tail;
} else if (nb == 0){
current = list->head;
} else if (nb <= (list->size - 1)/2 && nb > 0){
i = 0;
current = list->head;
while(i<nb){
current = current->next;
i++;
}
} else {
i = list->size - 1;
if (nb < 0){
nb = list->size + nb -1;
}
while(i>nb){
current = current->previous;
i = i - 1;
}
}
}
return current;
}
2017-01-01 15:35:34 +00:00
int popPtnList(List *list, ListElement *element){
2016-12-10 01:28:10 +00:00
int ok = SUCCESS;
if (list != NULL && element != NULL){
if (list->head == element && list->tail == element){
list->head = NULL;
list->tail = NULL;
} else if (list->head == element){
list->head = element->next;
element->previous = NULL;
} else if (list->tail == element){
list->tail = element->previous;
element->previous->next = NULL;
} else {
element->next->previous = element->previous;
element->previous->next = element->next;
}
if (element->data != NULL){
2017-01-01 23:37:47 +00:00
freeCellElement(element->data);
2016-12-10 01:28:10 +00:00
}
free(element);
list->size = list->size - 1;
} else {
ok = FAILURE;
}
return ok;
}
2017-01-01 15:35:34 +00:00
int removeElement(List *list, int nb){
2016-12-10 01:28:10 +00:00
int ok = SUCCESS;
2017-01-01 15:35:34 +00:00
ListElement *toDelete = getElement(list, nb);
2016-12-10 01:28:10 +00:00
if (toDelete != NULL){
2017-01-01 15:35:34 +00:00
ok = popPtnList(list, toDelete);
2016-12-10 01:28:10 +00:00
} else {
ok = FAILURE;
}
return ok;
}
int shift(List *list){
2017-01-01 15:35:34 +00:00
return removeElement(list, 0);
2016-12-10 01:28:10 +00:00
}
int pop(List *list){
2017-01-01 15:35:34 +00:00
return removeElement(list, -1);
2016-12-10 01:28:10 +00:00
}
2017-01-01 15:35:34 +00:00
int deleteListContent(List *list){
2016-12-10 01:28:10 +00:00
int ok = SUCCESS;
ListElement * current = NULL;
ListElement * toDelete = NULL;
if (list != NULL){
current = list->head;
while (current != NULL){
toDelete = current;
current = current->next;
2016-12-10 04:04:13 +00:00
free(toDelete);
2016-12-10 01:28:10 +00:00
}
list->head = NULL;
list->tail = NULL;
list->size = 0;
} else {
ok = FAILURE;
}
return ok;
}
2017-01-01 15:35:34 +00:00
int freeList(List *list){
2016-12-10 01:28:10 +00:00
int ok = SUCCESS;
if (list != NULL){
2017-01-01 15:35:34 +00:00
ok = deleteListContent(list);
2016-12-10 01:28:10 +00:00
if (ok == SUCCESS){
free(list);
}
} else {
ok = FAILURE;
}
return ok;
}
2016-12-23 13:08:10 +00:00
2017-01-01 15:35:34 +00:00
ListElement * getElementPos(List *list, int pos){
2016-12-23 13:08:10 +00:00
ListElement * el = list->head;
while (el != NULL && el->pos != pos){
el = el->next;
}
return el;
}
2017-01-01 15:35:34 +00:00
int removeElementPos(List *list, int pos){
2016-12-23 13:08:10 +00:00
int ok = SUCCESS;
2017-01-01 15:35:34 +00:00
ListElement *toDelete = getElementPos(list, pos);
2016-12-23 13:08:10 +00:00
if (toDelete != NULL){
2017-01-01 15:35:34 +00:00
ok = popPtnList(list, toDelete);
2016-12-23 13:08:10 +00:00
} else {
ok = FAILURE;
}
return ok;
}
2017-01-01 15:35:34 +00:00
int insertBeforeElement(List *list, ListElement *eli, ListElement *elp){
2016-12-23 13:08:10 +00:00
int ok = SUCCESS;
if (list != NULL){
if (elp->previous == NULL){
eli->next = elp;
eli->previous = NULL;
elp->previous = eli;
} else {
eli->next = elp;
eli->previous = elp->previous;
elp->previous->next = eli;
elp->previous = eli;
}
list->size = list->size + 1;
} else {
ok = FAILURE;
}
return ok;
}
2017-01-01 15:35:34 +00:00
int insertAfterElement(List *list, ListElement *eli, ListElement *elb){
2016-12-23 13:08:10 +00:00
int ok = SUCCESS;
if (list != NULL){
if (elb->next == NULL){
eli->next = NULL;
eli->previous = elb;
elb->next = eli;
} else {
eli->previous = elb;
eli->next=elb->next;
elb->next->previous = eli;
elb->next = eli;
}
list->size = list->size + 1;
} else {
ok = FAILURE;
}
return ok;
}
2017-01-01 15:35:34 +00:00
int insertBefore(List *list, cellElement *data, int nb){
2016-12-23 13:08:10 +00:00
int ok = SUCCESS;
ListElement *newElement = NULL;
2017-01-01 15:35:34 +00:00
ListElement *eli = getElement(list, nb);
2016-12-23 13:08:10 +00:00
if (eli != NULL){
newElement = malloc(sizeof(*newElement));
if (newElement != NULL){
newElement->pos = -1;
newElement->data = data;
2017-01-01 15:35:34 +00:00
ok = insertBeforeElement(list, newElement, eli);
2016-12-23 13:08:10 +00:00
} else {
ok = FAILURE;
}
} else {
ok = FAILURE;
}
return ok;
}
2017-01-01 15:35:34 +00:00
int insertAfter(List *list, cellElement *data, int nb){
2016-12-23 13:08:10 +00:00
int ok = SUCCESS;
ListElement *newElement = NULL;
2017-01-01 15:35:34 +00:00
ListElement *elb = getElement(list, nb);
2016-12-23 13:08:10 +00:00
if (elb != NULL){
newElement = malloc(sizeof(*newElement));
if (newElement != NULL){
newElement->pos = -1;
newElement->data = data;
2017-01-01 15:35:34 +00:00
ok = insertAfterElement(list, newElement, elb);
2016-12-23 13:08:10 +00:00
} else {
ok = FAILURE;
}
} else {
ok = FAILURE;
}
return ok;
}
2017-01-01 15:35:34 +00:00
int insertBeforePos(List *list, cellElement *data, int pos){
2016-12-23 13:08:10 +00:00
int ok = SUCCESS;
ListElement *newElement = NULL;
2017-01-01 15:35:34 +00:00
ListElement *eli = getElementPos(list, pos);
2016-12-23 13:08:10 +00:00
if (eli != NULL){
newElement = malloc(sizeof(*newElement));
if (newElement != NULL){
newElement->pos = -1;
newElement->data = data;
2017-01-01 15:35:34 +00:00
ok = insertBeforeElement(list, newElement, eli);
2016-12-23 13:08:10 +00:00
} else {
ok = FAILURE;
}
} else {
ok = FAILURE;
}
return ok;
}
2017-01-01 15:35:34 +00:00
int insertAfterPos(List *list, cellElement *data, int pos){
2016-12-23 13:08:10 +00:00
int ok = SUCCESS;
ListElement *newElement = NULL;
2017-01-01 15:35:34 +00:00
ListElement *elb = getElementPos(list, pos);
2016-12-23 13:08:10 +00:00
if (elb != NULL){
newElement = malloc(sizeof(*newElement));
if (newElement != NULL){
newElement->pos = -1;
newElement->data = data;
2017-01-01 15:35:34 +00:00
ok = insertAfterElement(list, newElement, elb);
2016-12-23 13:08:10 +00:00
} else {
ok = FAILURE;
}
} else {
ok = FAILURE;
}
return ok;
}