First Hack At It
Well, I figured the best place to start is with the stack. I've implemented a stack using a single-linked list. At first, I had trouble with it. When pushing objects into the stack, I realized I needed to get to the last node, and set its next pointer to the new node. That's not too complicated, but it is inefficient because of the need to scroll through all the nodes until the next pointer is NULL. To correct this, I resorted to keeping a pointer to the last node, and storing it in the head of the linked-list. Problem fixed? Not quite.
When poping the stack, access to the last node is quick because of the pointer in the head. But when the last node is popped, the previous node needs to become the last. Which means its next pointer needs to be NULLED, and the quick access pointer needs to modified. So, how do we get to the next-to-the-last node? Oops. Yes, you need to scroll through all the nodes! ARG! Unless, we have a quick access pointer to it too. But, do you see how ugly this can get?
A Better Way
So... how about... adding and deleteing nodes to the head of the list! I couldn't believe my tiny brain came up with this! Let me explain. Reference my ASCII diagram below (sorry, to lazy to use Inscape).
|H| --->|Na|
In the illustration above, H is the head of the list. The head contains a pointer to the first node and an int to store the length of the list. Na is a node. Pushing (adding) a node only takes 3 steps.
1. |Nb|
2. |H|--->|Na|
|Hb|-----^
3. |H|--->|Hb|--->|Ha|
First, a new node, Hb, is created. Then, the next pointer of Hb is pointed to Ha. So at this point, Ha has two pointers pointing at it, the head node H and the new node Nb. Finally, the head node is modified so that it points to the new node, Hb. And now we have an efficient method for pushing objects into the xX stack! Popping the stack is pretty easy to. But it does need a temporary pointer to the node to be deleted.
Below is part of the code.
Well, I figured the best place to start is with the stack. I've implemented a stack using a single-linked list. At first, I had trouble with it. When pushing objects into the stack, I realized I needed to get to the last node, and set its next pointer to the new node. That's not too complicated, but it is inefficient because of the need to scroll through all the nodes until the next pointer is NULL. To correct this, I resorted to keeping a pointer to the last node, and storing it in the head of the linked-list. Problem fixed? Not quite.
When poping the stack, access to the last node is quick because of the pointer in the head. But when the last node is popped, the previous node needs to become the last. Which means its next pointer needs to be NULLED, and the quick access pointer needs to modified. So, how do we get to the next-to-the-last node? Oops. Yes, you need to scroll through all the nodes! ARG! Unless, we have a quick access pointer to it too. But, do you see how ugly this can get?
A Better Way
So... how about... adding and deleteing nodes to the head of the list! I couldn't believe my tiny brain came up with this! Let me explain. Reference my ASCII diagram below (sorry, to lazy to use Inscape).
|H| --->|Na|
In the illustration above, H is the head of the list. The head contains a pointer to the first node and an int to store the length of the list. Na is a node. Pushing (adding) a node only takes 3 steps.
1. |Nb|
2. |H|--->|Na|
|Hb|-----^
3. |H|--->|Hb|--->|Ha|
First, a new node, Hb, is created. Then, the next pointer of Hb is pointed to Ha. So at this point, Ha has two pointers pointing at it, the head node H and the new node Nb. Finally, the head node is modified so that it points to the new node, Hb. And now we have an efficient method for pushing objects into the xX stack! Popping the stack is pretty easy to. But it does need a temporary pointer to the node to be deleted.
Below is part of the code.
xxstack.h
typedef struct xxStackNode_t
{
struct xxObject_t *obj;
struct xxStackNode_t *next;
} xxStackNode;
typedef struct xxStack_t
{
struct xxStackNode_t *node;
int length;
} xxStack;
xxStackNode* xxStackNode_New();
void xxStackNode_Delete(xxStackNode *node);
xxStack* xxStack_New();
int xxStack_GetLength(xxStack *stack);
int xxStack_Push(xxStack *stack, xxObject *obj);
xxObject* xxStack_Pop(xxStack *stack);
xxstack.c
xxStackNode* xxStackNode_New()
{
xxStackNode *node;
node = (xxStackNode *) malloc(sizeof(xxStackNode));
node->obj = NULL;
node->next = NULL;
return node;
}
void xxStackNode_Delete(xxStackNode *node)
{
node->obj = NULL;
node->next = NULL;
free(node);
}
/* xxStack functions */
xxStack* xxStack_New()
{
xxStack *stack;
stack = (xxStack *) malloc(sizeof(xxStack));
stack->node = NULL;
stack->length = 0;
return stack;
}
int xxStack_GetLength(xxStack *stack)
{
return stack->length;
}
int xxStack_Push(xxStack *stack, xxObject *obj)
{
xxStackNode *newNode;
newNode = xxStackNode_New();
newNode->obj = obj;
if(stack->node == NULL)
{
stack->node = newNode;
}
else
{
newNode->next = stack->node;
stack->node = newNode;
}
stack->length++;
return 0;
}
xxObject* xxStack_Pop(xxStack *stack)
{
xxObject *obj;
xxStackNode *node;
if(stack->node == NULL)
{
obj = NULL;
}
else
{
obj = stack->node->obj;
node = stack->node;
if(stack->node->next == NULL)
{
stack->node = NULL;
}
else
{
stack->node = stack->node->next;
xxStackNode_Delete(node);
}
stack->length--;
}
return obj;
}
<\pre>
PS: Sorry for the lame title. The title field in Blogger seems to have dissapeared. REALLY!


0 Comments:
Post a Comment
<< Home