1999-12-09 23:15:14 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include "LL.h"
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
#undef DEBUG
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//TODO: Comment everything
|
|
|
|
|
//TODO: Test everything?
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Creates a new list...
|
2001-10-26 16:29:12 +00:00
|
|
|
LinkedList *
|
2000-03-30 20:28:01 +00:00
|
|
|
LL_new ()
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2001-10-26 16:29:12 +00:00
|
|
|
LinkedList *list;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2001-10-26 16:29:12 +00:00
|
|
|
list = malloc (sizeof (LinkedList));
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return NULL;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
list->head.data = NULL;
|
|
|
|
|
list->head.prev = NULL;
|
|
|
|
|
list->head.next = &list->tail;
|
|
|
|
|
list->tail.data = NULL;
|
|
|
|
|
list->tail.prev = &list->head;
|
|
|
|
|
list->tail.next = NULL;
|
|
|
|
|
list->current = &list->head;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return list;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// TODO: test this function
|
|
|
|
|
// Destroys the entire list
|
|
|
|
|
// Warning! Does not free the list data! (only the list itself)
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Destroy (LinkedList * list)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_node *node, *next;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
node = &list->head;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
for (node = node->next; node && node->next; node = next) {
|
|
|
|
|
// Avoid accessing "node" after it's freed.. :)
|
|
|
|
|
next = node->next;
|
|
|
|
|
if (LL_node_Destroy (node) < 0)
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
free (list);
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// TODO: test this function
|
|
|
|
|
// Warning! This does not assert that the node data is free!
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
|
|
|
|
LL_node_Destroy (LL_node * node)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!node)
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (LL_node_Unlink (node) < 0)
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
free (node);
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
|
|
|
|
LL_node_Unlink (LL_node * node)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_node *next, *prev;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!node)
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
next = node->next;
|
|
|
|
|
prev = node->prev;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (next)
|
|
|
|
|
next->prev = prev;
|
|
|
|
|
if (prev)
|
|
|
|
|
prev->next = next;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
node->next = NULL;
|
|
|
|
|
node->prev = NULL;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Frees the data in a list node, if not NULL...
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
|
|
|
|
LL_node_DestroyData (LL_node * node)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!node)
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (node->data)
|
|
|
|
|
free (node->data);
|
|
|
|
|
else
|
|
|
|
|
return -1;
|
|
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Returns to the beginning of the list...
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Rewind (LinkedList * list)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
/*
|
|
|
|
|
printf("LL_Rewind: list=%8x\n", list);
|
|
|
|
|
printf("LL_Rewind: list.head=%8x\n", &list->head);
|
|
|
|
|
printf("LL_Rewind: list.tail=%8x\n", &list->tail);
|
|
|
|
|
*/
|
|
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (list->head.next != &list->tail)
|
|
|
|
|
list->current = list->head.next;
|
|
|
|
|
else
|
|
|
|
|
list->current = &list->head;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Goes to the end of the list...
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_End (LinkedList * list)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (list->tail.prev != &list->head)
|
|
|
|
|
list->current = list->tail.prev;
|
|
|
|
|
else
|
|
|
|
|
list->current = &list->tail;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Go to the next node
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Next (LinkedList * list)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
|
|
|
|
if (!list->current)
|
|
|
|
|
return -1;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (list->current->next != &list->tail) {
|
|
|
|
|
list->current = list->current->next;
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Go to the previous node
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Prev (LinkedList * list)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
|
|
|
|
if (!list->current)
|
|
|
|
|
return -1;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (list->current->prev != &list->head) {
|
|
|
|
|
list->current = list->current->prev;
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Data manipulation
|
2000-03-30 20:28:01 +00:00
|
|
|
void *
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Get (LinkedList * list)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (!list->current)
|
|
|
|
|
return NULL;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return list->current->data;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Put (LinkedList * list, void *data)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
|
|
|
|
if (!list->current)
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
list->current->data = data;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
LL_node *
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_GetNode (LinkedList * list)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return NULL;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return list->current;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Don't use this unless you know what you're doing.
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_PutNode (LinkedList * list, LL_node * node)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
|
|
|
|
if (!node)
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
list->current = node;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
void *
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_GetFirst (LinkedList * list) // gets data from first node
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return NULL;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (0 > LL_Rewind (list))
|
|
|
|
|
return NULL;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return LL_Get (list);
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
2000-03-30 20:28:01 +00:00
|
|
|
void *
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_GetNext (LinkedList * list) // ... next node
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return NULL;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (0 > LL_Next (list))
|
|
|
|
|
return NULL;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return LL_Get (list);
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
void *
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_GetPrev (LinkedList * list) // ... prev node
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return NULL;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (0 > LL_Prev (list))
|
|
|
|
|
return NULL;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return LL_Get (list);
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
void *
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_GetLast (LinkedList * list) // ... last node
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return NULL;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (0 > LL_End (list))
|
|
|
|
|
return NULL;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return LL_Get (list);
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_AddNode (LinkedList * list, void *add) // Adds node AFTER current one
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_node *node;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
|
|
|
|
//if(!add) return -1; // Nevermind.. NULL entries can be good...
|
|
|
|
|
if (!list->current)
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
//LL_dprint(list);
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
node = malloc (sizeof (LL_node));
|
|
|
|
|
if (!node)
|
|
|
|
|
return -1;
|
|
|
|
|
//printf("Allocated node\n");
|
1999-12-09 23:15:14 +00:00
|
|
|
|
|
|
|
|
/* printf("Current: prev: %8x\tnode: %8x\tnext: %8x\n", */
|
|
|
|
|
/* (int)list->current->prev, */
|
|
|
|
|
/* (int)list->current, */
|
|
|
|
|
/* (int)list->current->next); */
|
2000-04-03 22:13:57 +00:00
|
|
|
if (list->current == &list->tail) {
|
|
|
|
|
list->current = list->current->prev;
|
1999-12-09 23:15:14 +00:00
|
|
|
/* printf("Was at end of list...\n"); */
|
|
|
|
|
/* printf("Current: prev: %8x\tnode: %8x\tnext: %8x\n", */
|
|
|
|
|
/* (int)list->current->prev, */
|
|
|
|
|
/* (int)list->current, */
|
|
|
|
|
/* (int)list->current->next); */
|
2000-04-03 22:13:57 +00:00
|
|
|
}
|
1999-12-09 23:15:14 +00:00
|
|
|
// printf("Setting node data\n");
|
2000-04-03 22:13:57 +00:00
|
|
|
node->next = list->current->next;
|
|
|
|
|
node->prev = list->current;
|
|
|
|
|
node->data = add;
|
1999-12-09 23:15:14 +00:00
|
|
|
// printf("...done\n");
|
|
|
|
|
/* printf("NewNode: prev: %8x\tnode: %8x\tnext: %8x\n", */
|
|
|
|
|
/* (int)node->prev, */
|
|
|
|
|
/* (int)node, */
|
|
|
|
|
/* (int)node->next); */
|
2000-03-30 20:28:01 +00:00
|
|
|
|
1999-12-09 23:15:14 +00:00
|
|
|
// printf("Relinking...\n");
|
2000-04-03 22:13:57 +00:00
|
|
|
if (node->next)
|
|
|
|
|
node->next->prev = node;
|
1999-12-09 23:15:14 +00:00
|
|
|
// printf("...\n");
|
2000-04-03 22:13:57 +00:00
|
|
|
list->current->next = node;
|
1999-12-09 23:15:14 +00:00
|
|
|
// printf("...done\n");
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
list->current = node;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
|
|
|
|
// printf("Added node\n");
|
|
|
|
|
// LL_dprint(list);
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_InsertNode (LinkedList * list, void *add) // Adds node BEFORE current one
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_node *node;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
|
|
|
|
if (!add)
|
|
|
|
|
return -1;
|
|
|
|
|
if (!list->current)
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
node = malloc (sizeof (LL_node));
|
|
|
|
|
if (!node)
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (list->current == &list->head)
|
|
|
|
|
list->current = list->current->next;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
node->next = list->current;
|
|
|
|
|
node->prev = list->current->prev;
|
|
|
|
|
node->data = add;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (list->current->prev)
|
|
|
|
|
list->current->prev->next = node;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
list->current->prev = node;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
list->current = node;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Removes a node from the link
|
|
|
|
|
// ... and advances one node forward
|
2000-03-30 20:28:01 +00:00
|
|
|
void *
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_DeleteNode (LinkedList * list)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_node *next, *prev;
|
|
|
|
|
void *data;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (!list->current)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (list->current == &list->head)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (list->current == &list->tail)
|
|
|
|
|
return NULL;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2002-08-04 20:52:36 +00:00
|
|
|
/*
|
2000-04-03 22:13:57 +00:00
|
|
|
printf ("LL_DeleteNode: Before...\n");
|
|
|
|
|
LL_dprint (list);
|
2002-08-04 20:52:36 +00:00
|
|
|
*/
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
next = list->current->next;
|
|
|
|
|
prev = list->current->prev;
|
|
|
|
|
data = list->current->data;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (prev)
|
|
|
|
|
prev->next = next;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (next)
|
|
|
|
|
next->prev = prev;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
list->current->prev = NULL;
|
|
|
|
|
list->current->next = NULL;
|
|
|
|
|
// This should not free things; the user should do it explicitly.
|
|
|
|
|
//if(list->current->data) free(list->current->data);
|
|
|
|
|
list->current->data = NULL;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
free (list->current);
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
list->current = next;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2002-08-04 20:52:36 +00:00
|
|
|
/*
|
2000-04-03 22:13:57 +00:00
|
|
|
printf ("LL_DeleteNode: After...\n");
|
|
|
|
|
LL_dprint (list);
|
2002-08-04 20:52:36 +00:00
|
|
|
*/
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return data;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
2000-03-30 20:28:01 +00:00
|
|
|
|
1999-12-09 23:15:14 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Removes a specific node...
|
2000-03-30 20:28:01 +00:00
|
|
|
void *
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Remove (LinkedList * list, void *data)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
void *find;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return NULL;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_Rewind (list);
|
|
|
|
|
do {
|
|
|
|
|
find = LL_Get (list);
|
|
|
|
|
if (find == data)
|
|
|
|
|
return LL_DeleteNode (list);
|
|
|
|
|
} while (LL_Next (list) == 0);
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return NULL;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Stack operations
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Push (LinkedList * list, void *add) // Add node to end of list
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
|
|
|
|
if (!add)
|
|
|
|
|
return -1;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
1999-12-09 23:15:14 +00:00
|
|
|
// printf("Going to end of list...\n");
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_End (list);
|
1999-12-09 23:15:14 +00:00
|
|
|
|
|
|
|
|
// printf("Adding node...\n");
|
2000-04-03 22:13:57 +00:00
|
|
|
return LL_AddNode (list, add);
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
void *
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Pop (LinkedList * list) // Remove node from end of list
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return NULL;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (0 > LL_End (list))
|
|
|
|
|
return NULL;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return LL_DeleteNode (list);
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
void *
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Top (LinkedList * list) // Peek at end node
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
return LL_GetLast (list);
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
void *
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Shift (LinkedList * list) // Remove node from start of list
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return NULL;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (0 > LL_Rewind (list))
|
|
|
|
|
return NULL;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return LL_DeleteNode (list);
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
void *
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Look (LinkedList * list) // Peek at first node
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
return LL_GetFirst (list);
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Unshift (LinkedList * list, void *add) // Add node to beginning of list
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
|
|
|
|
if (!add)
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_Rewind (list);
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return LL_InsertNode (list, add);
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Roll (LinkedList * list) // Make last node first
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_node *node, *next;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
|
|
|
|
//if(!list->current) return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (0 > LL_End (list))
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
// Avoid rolling an empty list, or unlinking the head/tail...
|
|
|
|
|
if (list->current == &list->head)
|
|
|
|
|
list->current = list->current->next;
|
|
|
|
|
if (list->current == &list->tail)
|
|
|
|
|
list->current = list->current->prev;
|
|
|
|
|
// List is empty
|
|
|
|
|
if (list->current == &list->head)
|
|
|
|
|
return 0;
|
|
|
|
|
// List has one item
|
|
|
|
|
if (list->current->prev == &list->head)
|
|
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
node = list->current;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_node_Unlink (node);
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (0 > LL_Rewind (list))
|
|
|
|
|
return -1;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
next = list->head.next;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
list->head.next = node;
|
|
|
|
|
next->prev = node;
|
|
|
|
|
node->prev = &list->head;
|
|
|
|
|
node->next = next;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_UnRoll (LinkedList * list) // Roll the other way...
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_node *node, *prev;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
|
|
|
|
//if(!list->current) return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (0 > LL_Rewind (list))
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
// Avoid rolling an empty list, or unlinking the head/tail...
|
|
|
|
|
if (list->current == &list->tail)
|
|
|
|
|
list->current = list->current->prev;
|
|
|
|
|
if (list->current == &list->head)
|
|
|
|
|
list->current = list->current->next;
|
|
|
|
|
// List is empty
|
|
|
|
|
if (list->current == &list->tail)
|
|
|
|
|
return 0;
|
|
|
|
|
// List has one item
|
|
|
|
|
if (list->current->next == &list->tail)
|
|
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
node = list->current;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_node_Unlink (node);
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (0 > LL_End (list))
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
prev = list->tail.prev;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
list->tail.prev = node;
|
|
|
|
|
prev->next = node;
|
|
|
|
|
node->next = &list->tail;
|
|
|
|
|
node->prev = prev;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
// Add an item to the end of its "priority group"
|
|
|
|
|
// The list is assumed to be sorted already...
|
|
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_PriorityEnqueue (LinkedList * list, void *add, int compare (void *, void *))
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
void *data;
|
|
|
|
|
int i;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
|
|
|
|
if (!add)
|
|
|
|
|
return -1;
|
|
|
|
|
if (!compare)
|
|
|
|
|
return -1;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
// From the end of the list, keep searching while we're "less than"
|
|
|
|
|
// the given nodes...
|
|
|
|
|
LL_End (list);
|
|
|
|
|
do {
|
|
|
|
|
data = LL_Get (list);
|
|
|
|
|
if (data) {
|
|
|
|
|
i = compare (add, data);
|
|
|
|
|
if (i >= 0) // If we're in the right place, add it and exit
|
|
|
|
|
{
|
|
|
|
|
LL_AddNode (list, add);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} while (LL_Prev (list) == 0);
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
// If we're less than *everything*, put it at the beginning
|
|
|
|
|
LL_Unshift (list, add);
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
2000-03-30 20:28:01 +00:00
|
|
|
|
1999-12-09 23:15:14 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
|
|
|
|
LL_SwapNodes (LL_node * one, LL_node * two) // Switch two nodes positions...
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_node *firstprev, *firstnext;
|
|
|
|
|
LL_node *secondprev, *secondnext;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!one || !two)
|
|
|
|
|
return -1;
|
|
|
|
|
if (one == two)
|
|
|
|
|
return 0; // Do nothing
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
firstprev = one->prev; // Look up the nodes neighbors...
|
|
|
|
|
firstnext = one->next;
|
|
|
|
|
secondprev = two->prev;
|
|
|
|
|
secondnext = two->next;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (firstprev != NULL)
|
|
|
|
|
firstprev->next = two; // Swap the neighboring
|
|
|
|
|
if (firstnext != NULL)
|
|
|
|
|
firstnext->prev = two; // nodes pointers...
|
|
|
|
|
if (secondprev != NULL)
|
|
|
|
|
secondprev->next = one;
|
|
|
|
|
if (secondprev != NULL)
|
|
|
|
|
secondnext->prev = one;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
one->next = secondnext; // Swap the nodes pointers
|
|
|
|
|
one->prev = secondprev;
|
|
|
|
|
two->next = firstnext;
|
|
|
|
|
two->prev = firstprev;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (firstnext == two)
|
|
|
|
|
one->prev = two; // Fix things in case
|
|
|
|
|
if (firstprev == two)
|
|
|
|
|
one->next = two; // they were next to
|
|
|
|
|
if (secondprev == one)
|
|
|
|
|
two->next = one; // each other...
|
|
|
|
|
if (secondnext == one)
|
|
|
|
|
two->prev = one;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
|
|
|
|
LL_nSwapNodes (int one, int two) // Switch two nodes positions...
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
return -1;
|
2000-03-30 20:28:01 +00:00
|
|
|
}
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-03-30 20:28:01 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Length (LinkedList * list) // Returns # of nodes in entire list
|
2000-03-30 20:28:01 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_node *node;
|
|
|
|
|
int num = 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
node = &list->head;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
for (num = -1; node != &list->tail; num++)
|
|
|
|
|
node = node->next;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return num;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Searching...
|
|
|
|
|
// Goes to the list item which matches "value", and returns the
|
|
|
|
|
// data found there.
|
|
|
|
|
//
|
|
|
|
|
// The "compare" function should return 0 for a "match"
|
|
|
|
|
//
|
|
|
|
|
// Note that this does *not* rewind the list first! You should do
|
|
|
|
|
// it yourself if you want to start from the beginning!
|
2000-03-30 20:28:01 +00:00
|
|
|
void *
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Find (LinkedList * list, int compare (void *, void *), void *value)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
void *data;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (!compare)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (!value)
|
|
|
|
|
return NULL;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
do {
|
|
|
|
|
data = LL_Get (list);
|
|
|
|
|
if (0 == compare (data, value))
|
|
|
|
|
return data;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
} while (LL_Next (list) == 0);
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return NULL;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
2002-05-26 19:21:23 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Array like...
|
|
|
|
|
// Goes to the nth list item, and returns the
|
|
|
|
|
// data found there.
|
|
|
|
|
//
|
|
|
|
|
void *
|
|
|
|
|
LL_GetByIndex (LinkedList * list, int index)
|
|
|
|
|
{
|
|
|
|
|
LL_node *node;
|
|
|
|
|
int num = 0;
|
|
|
|
|
|
|
|
|
|
if (!list)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (index<0)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
for (node = list->head.next; node != &list->tail; node = node->next) {
|
|
|
|
|
if (num == index)
|
|
|
|
|
return node->data;
|
|
|
|
|
num ++;
|
|
|
|
|
}
|
|
|
|
|
return NULL; // got past the end
|
|
|
|
|
}
|
|
|
|
|
|
1999-12-09 23:15:14 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
// Sorts the list, then rewinds it...
|
|
|
|
|
//
|
2000-03-30 20:28:01 +00:00
|
|
|
int
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_Sort (LinkedList * list, int compare (void *, void *))
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
int i, j; // Junk / loop variables
|
|
|
|
|
int numnodes; // number of nodes in list
|
|
|
|
|
LL_node *best, *last; // best match and last node in the list
|
|
|
|
|
LL_node *current;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (!list)
|
|
|
|
|
return -1;
|
|
|
|
|
if (!compare)
|
|
|
|
|
return -1;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
numnodes = LL_Length (list); // get the number of nodes...
|
|
|
|
|
if (0 > LL_End (list))
|
|
|
|
|
return -1; // Find the last node.
|
|
|
|
|
last = LL_GetNode (list);
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (numnodes < 2)
|
|
|
|
|
return 0;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
for (i = numnodes - 1; i > 0; i--) {
|
|
|
|
|
LL_Rewind (list); // get the first node again
|
|
|
|
|
best = last; // reset our "best" node
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
for (j = 0; j < i; j++) {
|
|
|
|
|
current = LL_GetNode (list);
|
|
|
|
|
// If we found a better match...
|
|
|
|
|
if (compare (current->data, best->data) > 0) {
|
|
|
|
|
best = current; // keep track of the "best" match
|
|
|
|
|
}
|
|
|
|
|
LL_Next (list); // Go to the next node.
|
|
|
|
|
}
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_SwapNodes (last, best); // Switch two nodes...
|
|
|
|
|
if (best)
|
|
|
|
|
last = best->prev;
|
|
|
|
|
else
|
|
|
|
|
return -1;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
//last = LL_FindPrev(best); // And go backwards by one node.
|
|
|
|
|
}
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
//return LLFindFirst(current); // return pointer to the first node.
|
|
|
|
|
LL_Rewind (list);
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
2000-03-30 20:28:01 +00:00
|
|
|
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|
|
|
|
|
|
2000-03-30 20:28:01 +00:00
|
|
|
void
|
2001-10-26 16:29:12 +00:00
|
|
|
LL_dprint (LinkedList * list)
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2000-04-03 22:13:57 +00:00
|
|
|
LL_node *current;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
current = &list->head;
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2001-10-19 22:23:25 +00:00
|
|
|
printf ("Head: prev:\t0x%p\taddr:\t0x%p\tnext:\t0x%p\n", list->head.prev, &list->head, list->head.next);
|
2000-03-30 20:28:01 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
for (current = current->next; current != &list->tail; current = current->next) {
|
2001-10-19 22:23:25 +00:00
|
|
|
printf ("node: prev:\t0x%p\taddr:\t0x%p\tnext:\t0x%p\n", current->prev, current, current->next);
|
2000-04-03 22:13:57 +00:00
|
|
|
}
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2001-10-19 22:23:25 +00:00
|
|
|
printf ("Tail: prev:\t0x%p\taddr:\t0x%p\tnext:\t0x%p\n", list->tail.prev, &list->tail, list->tail.next);
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|