栈的介绍
来源:互联网 发布:java.ext.dirs 编辑:程序博客网 时间:2024/06/07 02:17
栈和线性表很相似,不仅有顺序存储表示也有链式存储表示,而且其创建删除都一样。只是栈的操作方面有如下的特点:
(01) 栈中数据是按照"后进先出(LIFO, Last In First Out)"方式进出栈的。
(02) 向栈中添加/删除数据时,只能从栈顶进行操作。
栈通常包括的三种操作:push、peek、pop。
push -- 向栈中添加元素。
peek -- 返回栈顶元素。
pop -- 返回并删除栈顶元素的操作。
一:顺序存储表示
栈的示意图
1:栈的顺序存储结构表示:
#define STACKINITSIZE 100#define STACKINCREMENT 10typedef struct{ SElemType *base; SElemType *top; int stacksize;}SqStack;
这里需要注意的一点是:顺序存储只需要创建依次结构体,而这个结构体里面的指针不是指向该类型的结构体的(与链表不同),而是只想SElemType类型的数组的!创建的一个数组的信息,全在这个结构体里面表示。
2:栈的初始化
Stack stack_init(SqStack *S){ S->base = (SElemType *)malloc(STACKINITSIZE * sizeof(SElemType)); if(!(S->base)) exit(-1); S->top = S->base; S->stacksize = STACKINITSIZE; return 1;}
3:取得栈顶元素
由于栈顶指针top指向栈顶元素的下一个位置,因此取元素、插入元素以及删除元素都要留意数组索引的变化。同时还要判断栈是否为空,或者是否已满,然后再进行操作。
Status get_top(SqStack S,SElemType *e){ if(S->top == S->base) return 0; *e = *(S->top - 1); return 1;}
4:插入元素
Status push(SqStack *S,SElemType e){ //判断元素空间十分充足 if(S->top - S->base >= S->stacksize){ S->base = (SElemType *)realloc(S->base, (S->stacksize + STACKINCREMENT)*sizeof(SElemType)); if(!(s->base)) exit(-1); S->top = S->base + S->stacksize; S->stacksize += STACKINCREMENT; } *(S->top) = e; S->top++; return 1;}
5:删除元素
Status pop(SqStack *S,SElemType *e){ if(S->top == S->base) return 0; *e = *(--S->top); return 1;}
评注:
栈、队列等其实就是一种工具,看你如何去用,如何去实现。这方式就有很多了。比如也可以用下面的方式来声明一个栈
#define MAXSIZE 200struct seqstack{ Elemtype data[MAXSIZE]; int top;};struct seqstack *s; //定义一个指向顺序栈的指针
二:链式存储表示
当我们建立链表的时候,可以再表头插入结点也可以在表尾插入结点。那么在实现栈的时候,我们选择在表头插入结点,就能很好的实现我们想要的操作。但是,这里不需要头结点,只需要一个头指针就可以了。
1:单链表的结点
// 单向链表的“节点”struct node { int val; struct node* next;};// 单向链表的“表头”static struct node *phead=NULL;
2:创建结点(这里不用初始化,单链表时有表头,需要初始化)
// 创建节点,val为节点值static struct node* create_node(int val) { struct node *pnode=NULL; pnode = (struct node*)malloc(sizeof(struct node)); if (!pnode) return NULL; pnode->val = val; pnode->next = NULL; return pnode;}
3:插入和删除的实现
// 将val插入到链表的表头位置static struct node* push(int val) { struct node *pnode = NULL; pnode = create_node(val); pnode->next = phead; phead = pnode; return phead;}// 删除链表的表头static int pop() { if (!phead) { printf("remove failed! link is empty!"); return -1; } int ret; struct node *pnode; ret = phead->val; pnode = phead; phead = phead->next; free(pnode); return ret;}
栈的链式存储实现代码
#include <stdio.h>#include <malloc.h>/** * C 语言: 单向链表实现的栈,只能存储int数据。 * * @author skywang * @date 2013/11/07 */// 单向链表的“节点”struct node { int val; struct node* next;};// 单向链表的“表头”static struct node *phead=NULL;// 创建节点,val为节点值static struct node* create_node(int val) { struct node *pnode=NULL; pnode = (struct node*)malloc(sizeof(struct node)); if (!pnode) return NULL; pnode->val = val; pnode->next = NULL; return pnode;}// 销毁单向链表static int destroy_single_link() { struct node *pnode=NULL; while (phead != NULL) { pnode = phead; phead = phead->next; free(pnode); } return 0;}// 将val插入到链表的表头位置static struct node* push(int val) { struct node *pnode = NULL; pnode = create_node(val); pnode->next = phead; phead = pnode; return phead;}// 删除链表的表头static int pop() { if (!phead) { printf("remove failed! link is empty!"); return -1; } int ret; struct node *pnode; ret = phead->val; pnode = phead; phead = phead->next; free(pnode); return ret;}// 返回链表的表头节点的值static int peek() { if (!phead) { printf("peek failed! link is empty!"); return -1; } return phead->val;}// 返回链表中节点的个数static int size() { int count=0; struct node *pnode=phead; while (pnode != NULL) { pnode = pnode->next; count++; } return count;}// 链表是否为空static int is_empty() { return phead==NULL;}// 打印“栈”static void print_single_link(){ if (is_empty()) { printf("stack is Empty\n"); return 0; } printf("stack size()=%d\n", size()); struct node *pnode=NULL; while (phead != NULL) { printf("%d\n", phead->val); pnode = phead; phead = phead->next; free(pnode); }}void main() { int tmp=0; // 将10, 20, 30 依次推入栈中 push(10); push(20); push(30); //print_single_link(); // 打印栈 // 将“栈顶元素”赋值给tmp,并删除“栈顶元素” tmp = pop(); printf("tmp=%d\n", tmp); //print_single_link(); // 打印栈 // 只将“栈顶”赋值给tmp,不删除该元素. tmp = peek(); printf("tmp=%d\n", tmp); //print_single_link(); // 打印栈 push(40); print_single_link(); // 打印栈 // 销毁栈 destroy_single_link();}
三:双向链表实现的栈,能存储任意类型的数据
推荐看:栈的图文解析
另外推荐:栈的顺序存储和链式存储
0 0
- 栈的介绍
- 堆和栈的详细介绍
- C#栈集合的简单介绍
- 堆和栈的区别介绍
- C++ 堆与栈简单的介绍
- C# 堆和栈的简单介绍
- 最易懂的栈桢介绍
- C#栈的简单介绍及应用
- Java栈的使用简单介绍
- C++中堆和栈的介绍
- 脱壳的介绍以及脱壳的介绍
- 一个介绍Web Tech的简单介绍
- Base64的介绍以及Base64URL介绍
- 1.0 Swift的作者介绍,出身介绍
- JVM的堆和栈以及GC算法的介绍
- WinInet类的介绍
- WOSA/XFS的介绍
- DecimalFormat的用法介绍
- SAN中的LUN,volume和HBA
- 赵雅智_ProviderContent监听数据变化
- 文件下载漏洞
- vim: wq
- js中使用eval()方法将字符串转换成日期格式、并获取指定时间的日期
- 栈的介绍
- windows8.1初体验
- win8体验
- linux上搭建adb 环境
- 关于 struts2 中 prepare 接口实现数据准备
- LeetCode Combination Sum
- Android app应用调用系统关机菜单
- 一路走来
- UIAlertView