#include "list.h" List::List() { list = NULL; last = NULL; size = 0; hash = (h_elem **)malloc(sizeof(h_elem) * HASH_SIZE); memset(hash, 0, HASH_SIZE * sizeof(h_elem)); } List::~List() { l_elem *temp; h_elem *t2; int i; while(list != NULL) { temp = list; list = list->next; free(temp); } for (i = 0; i < HASH_SIZE; i++) { t2 = hash[i]; while(t2) { hash[i] = hash[i]->next; free(t2); t2 = hash[i]; } } free(hash); } void List::hash_delete(void *data) { data = data; } void List::hash_insert(l_elem *elem, void *data) { h_elem *new_elem; int bucket = HASH((int)data); new_elem = (h_elem *)malloc(sizeof(h_elem)); new_elem->next = hash[bucket]; new_elem->data = data; new_elem->elem = elem; hash[bucket] = new_elem; } l_elem *List::find(void *elem) { h_elem *h; int bucket; bucket = HASH((int)elem); h = hash[bucket]; while(h) { if (h->data == elem) break; h = h->next; } if (!h) return NULL; return h->elem; } void List::InsertBefore(void *new_elem, void *where) { l_elem *new_list_elem; l_elem *temp; temp = find(where); if (temp == NULL) ERROR("Couldn't find element to insert before."); new_list_elem = (l_elem *)malloc(sizeof(l_elem)); new_list_elem->next = temp; new_list_elem->prev = temp->prev; if (temp->prev) temp->prev->next = new_list_elem; else list = new_list_elem; temp->prev = new_list_elem; new_list_elem->data = new_elem; hash_insert(new_list_elem, new_elem); size++; } void List::InsertAfter(void *new_elem, void *where) { l_elem *new_list_elem; l_elem *temp; temp = find(where); if (temp == NULL) ERROR("Couldn't find element to insert after."); new_list_elem = (l_elem *)malloc(sizeof(l_elem)); new_list_elem->prev = temp; new_list_elem->next = temp->next; if (temp->next) temp->next->prev = new_list_elem; else last = new_list_elem; temp->next = new_list_elem; new_list_elem->data = new_elem; hash_insert(new_list_elem, new_elem); size++; } void List::Append(void *new_elem) { l_elem *new_list_elem; new_list_elem = (l_elem *)malloc(sizeof(l_elem)); new_list_elem->data = new_elem; if (!list) { list = last = new_list_elem; new_list_elem->next = NULL; new_list_elem->prev = NULL; } else { last->next = new_list_elem; new_list_elem->prev = last; new_list_elem->next = NULL; last = new_list_elem; } hash_insert(new_list_elem, new_elem); size++; } void List::Delete(void *elem) { l_elem *temp; temp = find(elem); if (!temp) return; if (temp->prev) { temp->prev->next = temp->next; } else { list = temp->next; } if (temp->next) { temp->next->prev = temp->prev; } else { last = temp->prev; } free(temp); hash_delete(elem); size--; } /* * Circular Next * * This function returns the next element in the list. Note that the lists * are circular, so that if the element you give me is the last element, * I'll return the first element in the list as the next element. */ void *List::CircularNext(void *elem) { void *temp; temp = Next(elem); if (temp) return temp; if (!list) return NULL; return list->data; } void *List::Next(void *elem) { l_elem *temp; temp = find(elem); if (!temp) return NULL; if (temp->next) return temp->next->data; return NULL; } void *List::Prev(void *elem) { l_elem *temp; temp = find(elem); if (!temp) return NULL; if (temp->prev) return temp->prev->data; return NULL; } void *List::CircularPrev(void *elem) { void *temp; temp = Prev(elem); if (temp) return temp; if (last) return last->data; return NULL; } void *List::First() { if (!list) return NULL; return list->data; } void *List::Last() { if (!last) return NULL; return last->data; } void *List::Number(int num) { l_elem *temp; int counter; counter = 0; temp = list; while(temp != NULL && counter != num) { temp = temp->next; counter++; } return temp->data; } int List::GetNum(void *elem) { l_elem *temp; int counter; counter = 0; temp = list; while(temp != NULL && temp->data != elem) { temp = temp->next; counter++; } if (temp == NULL) ERROR("Couldn't find elem in GetNum!"); return counter; }