栈的链式存储结构及实现
2017-12-26 10:43
387 查看
今天学习栈的链式存储结构。
链式存储结构最大的好处就是没有空间的限制,通过指针指向将结点像一个链子一样把结点链接,那么栈的同样可以用于链式存储结构。
栈的链式存储结构,简称为链栈。想想看,栈只是栈顶来做插入和删除操作,栈顶放在链表的头部还是尾部呢?由于单链表有头指针,而栈顶指针也是必须的,那么干嘛不让他们合二为一呢,所以比较好的办法是把栈顶放到单链表的头部。另外栈顶在头部了,那么单链表的头结点也就失去了意义,通常对于链栈来说,是不需要头结点的。
同样对于链栈来说,基本不存在栈满的情况,除非内存已经没有可用的空间了。
下面是链栈的指向图:
同样链栈中最重要的算法是压栈和弹栈。
压栈操作:
操作很简单,新建结点,给结点数据域赋值,指针域指向原来栈顶元素。
然后将栈顶指针指向新结点,元素个数+1,就ok。如下图:
弹栈操作:
和压栈相反,将栈顶元素的数据域取通过指针返回这个数据,将要弹出的元素的指针域赋值给栈顶指针,然后释放这个元素,这样栈顶指针就指向新的栈顶了,然后元素个-1。如图:
下面我们来看一下相关代码的实现。
验证结果:
学习算法,我们首先要去领悟它的这种思想,以后在遇到问题时才会有思路。
链式存储结构最大的好处就是没有空间的限制,通过指针指向将结点像一个链子一样把结点链接,那么栈的同样可以用于链式存储结构。
栈的链式存储结构,简称为链栈。想想看,栈只是栈顶来做插入和删除操作,栈顶放在链表的头部还是尾部呢?由于单链表有头指针,而栈顶指针也是必须的,那么干嘛不让他们合二为一呢,所以比较好的办法是把栈顶放到单链表的头部。另外栈顶在头部了,那么单链表的头结点也就失去了意义,通常对于链栈来说,是不需要头结点的。
同样对于链栈来说,基本不存在栈满的情况,除非内存已经没有可用的空间了。
下面是链栈的指向图:
同样链栈中最重要的算法是压栈和弹栈。
压栈操作:
操作很简单,新建结点,给结点数据域赋值,指针域指向原来栈顶元素。
然后将栈顶指针指向新结点,元素个数+1,就ok。如下图:
弹栈操作:
和压栈相反,将栈顶元素的数据域取通过指针返回这个数据,将要弹出的元素的指针域赋值给栈顶指针,然后释放这个元素,这样栈顶指针就指向新的栈顶了,然后元素个-1。如图:
下面我们来看一下相关代码的实现。
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #define ERROR 0 #define OK 1 #define TRUE 1 #define FALSE 0 typedef int Status; typedef int EleType; typedef struct StackNode { EleType data;//结点数据域 struct StackNode* next;//结点指针域 }StackNode,* LinkStackPoi; //链栈的数据结构 typedef struct LinkStack { LinkStackPoi top;//栈顶结点 int count;//元素个数 }LinkStack; //初始化 Status InitLinkStack(LinkStack* stack) { if (!stack) { return ERROR; } stack->top = NULL; stack->count = 0; return OK; } //清空数据,释放结点内存,实际上就是pop所有数据 Status ClearLinkStack(LinkStack* stack) { if (!stack||!stack->count) { return ERROR; } while (stack->count) { StackNode* node = stack->top; stack->top = node->next; free(node); stack->count--; } return OK; } //判断链栈是否为空 Status EmptyLinkStack(LinkStack* stack) { if (!stack) { return ERROR; } return stack->count == 0 ? 1 : 0; } //获取元素个数 int GetLengthLinkStack(LinkStack* stack) { if (!stack ) { return -1; } return stack->count; } Status GetTop(LinkStack* stack, StackNode** stackNode) { if (!stack) { return ERROR; } *stackNode = stack->top;//将栈顶元素的指针返回,获取指向可修改栈顶元素内容。 return OK; } //Status GetTop(LinkStack* stack, StackNode* stackNode) //{ // if (!stack) // { // return ERROR; // } // *stackNode = *(stack->top);//将栈顶元素的副本内容,修改不会影响到栈顶元素。 // return OK; //} /* 弹栈 栈顶指针指向要弹出元素前置结点,然后释放弹出元素内存空间,然后count-1 */ Status pop(LinkStack* stack,EleType *e) { if (!stack && stack->count) { return ERROR; } StackNode* node = stack->top; *e = node->data; stack->top = node->next;//栈顶指针指向新的栈顶元素 free(node);//释放元素空间 stack->count--; return OK; } /* 压栈 先将压入元素放入到链表表中,然后再将栈顶指针指向压入的元素,然后count+1. */ Status push(LinkStack* stack,EleType e) { if (!stack) { return ERROR; } StackNode* node = (StackNode*)malloc(sizeof(StackNode)); node->next = stack->top;//将元素加入链表中 node->data = e; stack->top = node;//栈顶元素指向压入元素 stack->count++; return OK; } void PrintfLinkStack(LinkStack* stack) { if (!stack&&stack->count) { return ERROR; } StackNode* node = stack->top; while (node) { printf("%d,", node->data); node = node->next; } puts(""); return; } int main(int argc, char *argv[]) { LinkStack stack; InitLinkStack(&stack);//初始化 push(&stack, 1); push(&stack, 2); push(&stack, 3); push(&stack, 4); push(&stack, 5); puts("链栈元素:"); PrintfLinkStack(&stack); printf("链栈元素个数:%d\n", GetLengthLinkStack(&stack)); EleType e1,e2; pop(&stack, &e1); printf("弹出第一个元素:%d\n", e1); pop(&stack, &e2); printf("弹出第二个元素:%d\n", e2); puts("链栈元素:"); PrintfLinkStack(&stack); printf("链栈元素个数:%d", GetLengthLinkStack(&stack)); printf("\n"); return 0; }
验证结果:
学习算法,我们首先要去领悟它的这种思想,以后在遇到问题时才会有思路。
相关文章推荐
- 线性表的链式存储结构之单链表类的实现_Java
- 二叉树的链式存储结构 前序 后序 中序 层序遍历操作实现 判断是否完全二叉树
- 数据结构(六)---队列的链式存储的实现---java版
- 数据结构(java语言描述)-- 二叉查找树的链式存储结构的实现
- [数据结构]程杰队列的链式存储结构及实现代码
- 第六周:栈的链式存储结构及其基本运算实现
- 线性结构--->栈的链式存储实现
- 栈的链式存储结构及其基本运算的实现
- 数据结构2----线性表顺序存储和链式存储的实现(霜之小刀)
- 数据结构之C/C++实现二叉树的链式存储
- 数据结构与算 5:C++ 顺序/链式存储,栈 模板类实现,编译模板类问题解决
- 队列的链式存储结构及实现
- 链栈-----栈的链式存储结构及其实现
- 栈的链式存储结构及其基本运算实现
- 线性表链式存储结构下基本操作的实现(初始化、赋值、取值、插入、删除、归并等)
- 数据结构基础(4)C语言实现栈--链式存储(动态栈)
- 数据结构单链队列——链式存储实现
- 线性结构的顺序存储和链式存储的实现代码(一)
- 线性结构的顺序存储和链式存储的实现代码(二)
- 栈的链式存储结构及其基本运算实现