Initial revision
commit
a2efe57668
|
@ -0,0 +1,18 @@
|
|||
[Settings]
|
||||
Archive=0
|
||||
Pack=0
|
||||
Packed Variable=
|
||||
Project Name=LinkList
|
||||
GCC Switches=-Os -Wall -W -Wwrite-strings
|
||||
GNU Assembler Switches=
|
||||
Assembler Switches=-g -t
|
||||
GNU Linker Switches=
|
||||
Linker Switches=
|
||||
Debug Info=0
|
||||
Standard Library=1
|
||||
Command Line=
|
||||
Post-Build Process=
|
||||
[Included Files]
|
||||
C File 1=main.c
|
||||
C File 2=Linked.c
|
||||
Header File 1=List.h
|
|
@ -0,0 +1,158 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "List.h"
|
||||
|
||||
void FatalError ( const char *ErrorMessage ) {
|
||||
printf ( "%s\n", ErrorMessage );
|
||||
exit ( 1 );
|
||||
}
|
||||
|
||||
void MakeList ( List *mylist, short (*Compare) ( const Element Data1, const Element Data2 ) ) {
|
||||
mylist->RootNode = malloc ( sizeof( Node ) );
|
||||
if ( mylist->RootNode == NULL )
|
||||
FatalError ( "MakeList: Could not allocate a Node" );
|
||||
mylist->Compare = Compare;
|
||||
mylist->RootNode->Previous = NULL;
|
||||
mylist->RootNode->Next = NULL;
|
||||
mylist->RootNode->NodeElement = NULL;
|
||||
mylist->size = 0;
|
||||
}
|
||||
|
||||
Node *Find ( List *mylist, Element Data ) {
|
||||
Node *n;
|
||||
n = mylist->RootNode->Next;
|
||||
while ( n != mylist->RootNode ) {
|
||||
if ( mylist->Compare ( n->NodeElement, Data ) == 0 )
|
||||
return n;
|
||||
n = n->Next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Node *Get ( List *mylist, unsigned short index ) {
|
||||
unsigned short i, halfsize;
|
||||
Node *GetPtr;
|
||||
if ( index > mylist->size )
|
||||
return (Node *)NULL;
|
||||
halfsize = mylist->size / 2;
|
||||
if ( index > halfsize ) {
|
||||
GetPtr = mylist->RootNode->Previous;
|
||||
for ( i = 0; i < index; i++ )
|
||||
GetPtr = GetPtr->Previous;
|
||||
}
|
||||
else {
|
||||
GetPtr = mylist->RootNode->Next;
|
||||
for ( i = 0; i < index; i++ )
|
||||
GetPtr = GetPtr->Next;
|
||||
}
|
||||
return GetPtr;
|
||||
}
|
||||
|
||||
void InsertAt ( List *mylist, Element Data, Node *Pos ) {
|
||||
Node *New;
|
||||
New = malloc ( sizeof( Node ) );
|
||||
if ( New == NULL )
|
||||
FatalError ( "InsertAt: Could not allocate new Node" );
|
||||
|
||||
New->NodeElement = Data;
|
||||
|
||||
if ( mylist->size == 0 ) {
|
||||
New->Previous = mylist->RootNode;
|
||||
New->Next = mylist->RootNode;
|
||||
mylist->RootNode->Previous = New;
|
||||
mylist->RootNode->Next = New;
|
||||
mylist->size++;
|
||||
return;
|
||||
}
|
||||
|
||||
mylist->size++;
|
||||
New->Next = Pos;
|
||||
|
||||
if ( Pos != NULL ) {
|
||||
New->Previous = Pos->Previous;
|
||||
Pos->Previous = New;
|
||||
}
|
||||
if ( New->Previous != NULL )
|
||||
New->Previous->Next = New;
|
||||
}
|
||||
|
||||
short IsEmpty ( List *mylist ) {
|
||||
return mylist->size == 0;
|
||||
}
|
||||
|
||||
void Push ( List *mylist, Element Data ) {
|
||||
InsertAt ( mylist, Data, mylist->RootNode->Next );
|
||||
}
|
||||
|
||||
Element Pop ( List *mylist ) {
|
||||
Node *Return, *Next;
|
||||
Element data;
|
||||
Return = mylist->RootNode->Next;
|
||||
if ( Return == NULL )
|
||||
return (Element)NULL;
|
||||
Next = Return->Next;
|
||||
mylist->RootNode->Next = Next;
|
||||
data = Return->NodeElement;
|
||||
free ( Return );
|
||||
mylist->size--;
|
||||
return data;
|
||||
}
|
||||
|
||||
void Enqueue ( List *mylist, Element Data ) {
|
||||
InsertAt ( mylist, Data, mylist->RootNode );
|
||||
}
|
||||
|
||||
Element Dequeue ( List *mylist ) {
|
||||
return Pop ( mylist );
|
||||
}
|
||||
|
||||
void Delete ( List *mylist, Element Data ) {
|
||||
Node *Deleted;
|
||||
Deleted = Find ( mylist, Data );
|
||||
if ( Deleted == NULL )
|
||||
return;
|
||||
if ( Deleted->Next != NULL )
|
||||
Deleted->Next->Previous = Deleted->Previous;
|
||||
if ( Deleted->Previous != NULL )
|
||||
Deleted->Previous->Next = Deleted->Next;
|
||||
free ( Deleted->NodeElement );
|
||||
free ( Deleted );
|
||||
}
|
||||
|
||||
void DeletePosition ( List *mylist, unsigned short index ) {
|
||||
Node *Deleted, *Prev, *Next;
|
||||
unsigned short i;
|
||||
Deleted = mylist->RootNode;
|
||||
for ( i = 0; i < index; i++ ) {
|
||||
Deleted = Deleted->Next;
|
||||
if ( Deleted == NULL )
|
||||
return;
|
||||
}
|
||||
Prev = Deleted->Previous;
|
||||
Next = Deleted->Next;
|
||||
free ( Deleted->NodeElement );
|
||||
free ( Deleted );
|
||||
if ( Prev != NULL )
|
||||
Prev->Next = Next;
|
||||
if ( Next != NULL )
|
||||
Next->Previous = Prev;
|
||||
mylist->size--;
|
||||
}
|
||||
|
||||
void MakeEmpty ( List *mylist ) {
|
||||
Node *node, *next;
|
||||
unsigned short i = 0;
|
||||
next = NULL;
|
||||
node = mylist->RootNode;
|
||||
|
||||
for ( i = 0; i <= mylist->size; i++ ) {
|
||||
next = node->Next;
|
||||
if ( node->NodeElement != NULL )
|
||||
free ( node->NodeElement );
|
||||
free ( node );
|
||||
node = next;
|
||||
}
|
||||
mylist->size = 0;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef __List_h
|
||||
|
||||
typedef void *Element;
|
||||
|
||||
typedef struct NodeTag {
|
||||
Element NodeElement;
|
||||
struct NodeTag *Next;
|
||||
struct NodeTag *Previous;
|
||||
} Node;
|
||||
|
||||
typedef struct {
|
||||
Node *RootNode;
|
||||
short (*Compare) ( const Element Data1, const Element Data2 );
|
||||
unsigned short size;
|
||||
} List;
|
||||
|
||||
/* Initializes the list.
|
||||
* Compare compares two Elements. Should return a value < 0
|
||||
* if Data1 < Data2, 0 if equal, and a value > 1 if Data1 > Data2
|
||||
*/
|
||||
void MakeList ( List *mylist, short (*Compare) ( const Element Data1, const Element Data2 ) );
|
||||
|
||||
/* Returns a pointer to a node containing Element Data */
|
||||
Node *Find ( List *mylist, Element Data );
|
||||
/* Returns the index-th item in the List */
|
||||
Node *Get ( List *mylist, unsigned short index );
|
||||
/* Inserts Data in front of Node Pos into the List */
|
||||
void InsertAt ( List *mylist, Element Data, Node *Pos );
|
||||
|
||||
/* Returns true if list size is 0 */
|
||||
short IsEmpty ( List *mylist );
|
||||
|
||||
/* Pushes Data into mylist as if it were a stack */
|
||||
void Push ( List *mylist, Element Data );
|
||||
/* Pops the top Element off mylist, must free the returned Element when done */
|
||||
Element Pop ( List *mylist );
|
||||
/* Enqueues Data as if List were a queue */
|
||||
void Enqueue ( List *mylist, Element Data );
|
||||
/* Dequeues the front Element off mylist, must free the returned Element when done */
|
||||
Element Dequeue ( List *mylist );
|
||||
|
||||
/* Deletes the Node containing Data */
|
||||
void Delete ( List *mylist, Element Data );
|
||||
/* Deletes the index-th item in List */
|
||||
void DeletePosition ( List *mylist, unsigned short index );
|
||||
/* Completely empties a List. Must call MakeList to use again */
|
||||
void MakeEmpty ( List *mylist );
|
||||
|
||||
#endif
|
|
@ -0,0 +1,15 @@
|
|||
CC = gcc
|
||||
CFLAGS = -Os -g -Wall -W -Wwrite-strings
|
||||
LDFLAGS =
|
||||
O_TARGET = linklist
|
||||
SRCS = main.c Linked.c
|
||||
OBJS = main.o Linked.o
|
||||
|
||||
all: $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $(O_TARGET) $(OBJS)
|
||||
|
||||
$(SRCS):
|
||||
$(CC) $(CFLAGS) -o $@ $*.c
|
||||
|
||||
clean:
|
||||
@rm *.o
|
|
@ -0,0 +1,97 @@
|
|||
/* LinkList: a circular linked list implementation for the TI-92+ graphing calculator */
|
||||
|
||||
//#define USE_TI92PLUS
|
||||
|
||||
#ifdef USE_TI92PLUS
|
||||
|
||||
#define ENABLE_ERROR_RETURN
|
||||
#define OPTIMIZE_ROM_CALLS
|
||||
#define SAVE_SCREEN
|
||||
|
||||
#include <tigcclib.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include "List.h"
|
||||
|
||||
void PrintList ( List *mylist ) {
|
||||
Node *P;
|
||||
unsigned short i = 0;
|
||||
P = mylist->RootNode->Next;
|
||||
printf ( "[ " );
|
||||
for ( i = 0; i < mylist->size; i++ ) {
|
||||
printf ( "[%s] ", (char *)P->NodeElement );
|
||||
if ( P->Next == NULL )
|
||||
break;
|
||||
else
|
||||
P = P->Next;
|
||||
}
|
||||
printf ( "]\n" );
|
||||
}
|
||||
|
||||
short CompareString ( const Element Data1, const Element Data2 ) {
|
||||
return strcmp ( Data1, Data2 );
|
||||
}
|
||||
|
||||
#ifdef USE_TI92PLUS
|
||||
|
||||
void _main ( void )
|
||||
|
||||
#else
|
||||
|
||||
int main ( void )
|
||||
|
||||
#endif
|
||||
{
|
||||
List mylist;
|
||||
int i;
|
||||
Element tmp;
|
||||
Node *FindPtr;
|
||||
|
||||
#ifdef USE_TI92PLUS
|
||||
ClrScr();
|
||||
#endif
|
||||
|
||||
MakeList ( &mylist, CompareString );
|
||||
PrintList ( &mylist );
|
||||
|
||||
for ( i = 0; i < 10; i++ ) {
|
||||
tmp = malloc ( sizeof( Element ) * 3 );
|
||||
sprintf ( tmp, "%d", i );
|
||||
Push ( &mylist, tmp );
|
||||
}
|
||||
|
||||
free ( Dequeue ( &mylist ) );
|
||||
|
||||
tmp = malloc ( sizeof( Element ) * 3 );
|
||||
sprintf ( tmp, "%d", 20 );
|
||||
FindPtr = Find ( &mylist, (Element)"3" );
|
||||
InsertAt ( &mylist, tmp, FindPtr );
|
||||
|
||||
tmp = malloc ( sizeof( Element ) * 4 );
|
||||
sprintf ( tmp, "%s", "FOO" );
|
||||
Enqueue ( &mylist, tmp );
|
||||
|
||||
tmp = malloc ( sizeof( Element ) * 4 );
|
||||
sprintf ( tmp, "%s", "BAR" );
|
||||
Enqueue ( &mylist, tmp );
|
||||
|
||||
PrintList ( &mylist );
|
||||
MakeEmpty ( &mylist );
|
||||
|
||||
#ifdef USE_TI92PLUS
|
||||
/* wait on keyboard input to continue */
|
||||
ngetchx();
|
||||
#endif
|
||||
|
||||
#ifndef USE_TI92PLUS
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
Reference in New Issue