我们可以把栈形象的看作一个网球筒。当往筒里放球时,球从筒底向上排到筒口;当从筒里拿球时,球从筒口往下依次被拿出,直到筒底的球最后一个被拿出。并且我们想拿到筒底的那个球,那么就必须把筒底那个球之上的球全部拿出才行。
栈的一个显著特征是它按照类似的先进先出(LIFO)的方式存储和删除元素。这意味着,最后一个存入栈中的元素将会第一个被删除。在计算机中,要把元素存储到栈中,就“压入”元素;要删除栈中的元素,就“弹出”元素(见图1)。有时候可以通过检查栈顶元素(而不是实际删除它)来获取元素的某些信息。
栈的接口定义
stack_init |
void stack_init(Stack *stack,void(*destroy)(void *data)); |
返回值:无 |
描述:初始化由stack指定的栈。 在对栈进行其他操作之前,必须调用初始化函数。参数destroy是一个函数指针,通过调用stack_destroy来释放动态分配的内存空间。例如,如果一个栈包含用malloc动态分配内存的数据,那么当此栈销毁时,destroy会调用free来释放内存空间。当一个结构化数据包含若干动态分配内存的数据成员时,destroy应该指向一个用户自定义的函数来释放每个动态分配的数据成员和结构本身的内存空间。如果不需要释放栈中的数据,那么destroy应该指向NULL。 |
复杂度:O(1) |
stack_destroy |
void stack_destroy(Stack *stack); |
返回值:无 |
描述:销毁由stack指定的栈。 在调用stack_destroy之后不再允许进行其他操作,除非再次调用stack_init。stack_destroy会删除栈中的所有元素,如果传递stack_init的参数destroy不为NULL,每次移除一个元素时,都要调用stack_destroy一次。 |
复杂度:O(n),n为栈中元素的个数。 |
stack_push |
int stack_push(Stack *stack,const void *data); |
返回值:如果元素成功入栈则返回0;否则返回-1。 |
描述:向stack指定的栈中压入一个元素。 新元素包含一个指向data的指针,因此只要元素仍然存在于栈中,daga引用的内存就一直有效。与data相关的存储空间将由函数的调用者来管理。 |
复杂度:O(1) |
stack_pop |
int stack_pop(Stack *stack,void **data); |
返回值:如果元素出栈成功则返回0,否则返回-1。 |
描述:从stack指定的栈中弹出一个元素。 返回时,data指向已弹出元素中存储的数据。与data相关的存储空间将由函数的调用者来管理。 |
复杂度:O(n),n为栈中元素的个数。 |
stack_peek |
void *stack_peek(const Stack *stack); |
返回值:栈顶部元素中存储的数据;如果栈为空返回NULL。 |
描述:获取stack指定的栈顶部元素中存储的数据的宏。 |
复杂度:O(1) |
stack_size |
int stack_size(const Stack *stack); |
返回值:栈中元素的个数。 |
描述:获取stack指定的栈中元素个数的宏。 |
复杂度:O(1) |