博文:
【 C 】经典抽象数据类型(ADT)之堆栈(用静态数组实现堆栈)
已经讲了两种方式实现堆栈,下面是最后一种方式,也就是链式方式实现堆栈。
由于只有堆栈的顶部元素才可以被访问,所以使用单链表就可以很好地实现链式堆栈。把一个新元素压入堆栈是通过在链表的起始位置添加一个元素实现的。从堆栈中弹出一个元素是通过从链表中移除第1个元素实现的。位于链表头部的元素总是很容易被访问。
下面是用链式结构实现链表的程序:
//一个用链表实现的堆栈,这个堆栈没有长度限制
#include < stdio.h >
#include < stdlib.h >
#include < malloc.h >
#include < assert.h >
#include " stack.h "
#define FALSE 0
//定义一个结构以存储堆栈元素,其中link字段将指向堆栈的下一个元素
typedef struct STACK_NODE
{
STACK_TYPE value; //这个类型是在stack.h头文件中定义的
struct STACK_NODE *next;
} StackNode;
//指向堆栈第一个节点的指针
static StackNode *stack;
//create_stack
void create_stack( size_t size )
{
}
//destroy_stack
void destroy_stack( void )
{
while( !is_empty )
pop();
}
//push
void push( STACK_TYPE value )
{
StackNode *new_node; //因为需要压入一个数值,所以要建立一个新节点
new_node = malloc( sizeof( StackNode ) ); //为新节点分配内存
assert( new_node != NULL ); //内存分配成功继续,否则退出
new_node->value = value;
new_node->next = stack;//new_node的指针指向前一个堆栈节点
stack = new_node; //stack指针指向新节点,stack始终指向栈顶节点
}
//pop
void pop( void )
{
StackNode *first_node; //这个指向节点的指针意义在于一个中间指针变量,指向栈顶节点,然后释放
assert( !is_empty() );
first_node = stack;
stack = first_node->next;
free( first_node );
}
//top
STACK_TYPE top( void )
{
assert( !is_empty() );
return stack->value;
}
//is_empty
int is_empty( void )
{
return stack == NULL;
}
//is_full
int is_full( void )
{
return FALSE; //永远不会满
}
STACK_NODE结构用于把一个值和一个指针捆绑在一起,而stack变量是一个指向这些结构变量之一的指针。当stack指针为NULL时,堆栈为空,也就是初始时的状态。
提示:destroy_stack 函数连续从堆栈中弹出元素,直到堆栈为空。同样,注意这个函数使用了现存的is_empty和pop函数,而不是重复那些用于实际操作的代码。
create_stack函数是一个空函数。由于链式堆栈不会填满,所以is_full函数返回假。
最后我提出一个问题,放这里等待我解决,定义
//指向堆栈第一个节点的指针
static StackNode *stack;
这个指针的时候,不应该给它赋值为NULL吗?
然后配合push函数:
//push
void push( STACK_TYPE value )
{
StackNode *new_node; //因为需要压入一个数值,所以要建立一个新节点
new_node = malloc( sizeof( StackNode ) ); //为新节点分配内存
assert( new_node != NULL ); //内存分配成功继续,否则退出
new_node->value = value;
new_node->next = stack;//new_node的指针指向前一个堆栈节点
stack = new_node; //stack指针指向新节点,stack始终指向栈顶节点
}
创建第一个堆栈节点并指向该节点,第一个节点的指针字段值为NULL。
或者是我想错了,第一次学。留在这里!等待查阅!