赞
踩
链栈,即用链表实现栈存储结构。
链栈的实现思路同顺序栈类似,顺序栈是将数顺序表(数组)的一端作为栈底,另一端为栈顶;链栈也如此,通常我们将链表的头部作为栈顶,尾部作为栈底。
链式栈是通过单链表来实现的。每次入栈一个元素,向链表中添加一个节点,出栈一个元素,释放一个节点。因为栈具有“后进先出”的特点,如果每次在链表的尾部进行插入和删除,就要遍历整个链表来找到尾节点。而在头部进行插入和删除时,只需根据头指针即可找到链表的首元素结点。而无需遍历链表。所以链式栈的出,入栈通过对链表进行头删和头插来实现。
将链表头部作为栈顶的一端,可以避免在实现数据 "入栈" 和 "出栈" 操作时做大量遍历链表的耗时操作。
链表的头部作为栈顶,意味着:
因此,链栈实际上就是一个只能采用头插法插入或删除数据的链表。
例如,将元素 1、2、3、4 依次入栈,等价于将各元素采用头插法依次添加到链表中,每个数据元素的添加过程如图 所示:
例如,上图 e) 所示的链栈中,若要将元素 3 出栈,根据"先进后出"的原则,要先将元素 4 出栈,也就是从链表中摘除,然后元素 3 才能出栈,整个操作过程如图 所示:
//linkstack.h 文件 #ifndef __LINKSTACK_H__ #define __LINKSTACK_H__ #include <stdbool.h> typedef int LinkStackType; //定义链栈的节点结构 typedef struct LinkStackNode { LinkStackType data; struct LinkStackNode* next; }LinkStackNode; LinkStackNode* LinkStackPush(LinkStackNode* pstack,LinkStackType value); LinkStackNode* LinkStackPop(LinkStackNode* pstack); bool LinkStackTop(LinkStackNode* pstack,LinkStackType* value); bool LinkStackDetory(LinkStackNode* pstack); #endif // !__LINKSTACK_H__
//LinkStack.c 功能函数文件 #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <stdbool.h> #include"LinkStack.h" /** * @brief Create a Node object * * @param value 链表结点元素值 * @return ** LinkStackNode* */ static LinkStackNode* CreateNode(LinkStackType value) { LinkStackNode* new_node = (LinkStackNode*)malloc(sizeof(LinkStackNode)); new_node->data = value; new_node->next = NULL; return new_node; } /** * @brief 头插入栈 * * @param pstack * @param value * @return LinkStackNode* */ LinkStackNode* LinkStackPush(LinkStackNode* pstack,LinkStackType value) { //创建节点 LinkStackNode* new_node = CreateNode(value); //将新节点的next指向原来的首原节点来做为新的首原节点 new_node->next = pstack; //使头指针指向新的首原节点 pstack = new_node; return pstack; } /** * @brief 销毁节点 * * @param node */ static void DestoryNode(LinkStackNode* node) { free(node); } /** * @brief 头删出栈 * * @param pstack * @return LinkStackNode* */ LinkStackNode* LinkStackPop(LinkStackNode* pstack) { if(pstack == NULL) { //空链栈 return pstack; } //保存要删除的首原节点 LinkStackNode* to_delete = pstack; //使头指针指向第二个节点 pstack = pstack->next; //释放要删除的节点 DestoryNode(to_delete); return pstack; } /** * @brief 取栈顶元素 * * @param stack * @param value * @return true * @return false */ bool LinkStackTop(LinkStackNode* pstack,LinkStackType* value) { if(pstack == NULL) { //空链表 return false; } *value = pstack->data; return true; } /** * @brief 销毁链式栈 * * @param stack * @return true * @return false */ bool LinkStackDetory(LinkStackNode* pstack) { if(pstack == NULL) { //非法输入 return false; } //遍历链表各节点对其进行释放 LinkStackNode* to_delete = pstack; while(to_delete != NULL) { LinkStackNode* next_node = to_delete->next; free(to_delete); to_delete = next_node; } //将头指针置空 pstack = NULL; return true; }
//测试文件 void displayLinkStack(LinkStackNode * pstack) { LinkStackNode* temp = pstack; printf("LinkStack: "); while (temp->next) { printf("%d ",temp->data); temp=temp->next; } printf("%d ",temp->data); printf("\n"); } void test(void) { LinkStackType topValue = 0; bool ret = false; LinkStackNode * stack = NULL; stack = LinkStackPush(stack, 1); //1 stack = LinkStackPush(stack, 2); // 1 2 stack = LinkStackPush(stack, 3); // 1 2 3 stack = LinkStackPush(stack, 4); // 1 2 3 4 stack = LinkStackPush(stack, 5); // 1 2 3 4 5 displayLinkStack(stack); ret = LinkStackTop(stack,&topValue); if(ret == true) { printf("topValue = %d \r\n",topValue); } stack = LinkStackPop(stack); // 1 2 3 4 stack = LinkStackPop(stack); // 1 2 3 stack = LinkStackPop(stack); // 1 2 stack = LinkStackPop(stack); // 1 displayLinkStack(stack); ret = LinkStackTop(stack,&topValue); if(ret == true) { printf("topValue = %d \r\n",topValue); } else { printf("empty linkStack!\r\n"); } stack =LinkStackPop(stack); // null ret = LinkStackTop(stack,&topValue); if(ret == true) { printf("topValue = %d \r\n",topValue); } else { printf("empty linkStack!\r\n"); } } /** * @brief 测试函数 * * @return int */ int main(void) { test(); system("pause"); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。