栈
来源:互联网 发布:淘宝简明英语语法教程 编辑:程序博客网 时间:2024/05/22 03:17
前言
本文在完成过程中,得到许多朋友的帮助,在此谢谢诸位。本人欢乐无限,技术有限,如有任何问题,欢迎各位不吝赐教。
1 栈ADT
栈(stack)是限制插入和删除操作只能在一端进行的线性表。允许插入和删除的这一端称为栈顶(top),相对的另外一端称为栈底(bottom)。从定义中我们知道栈有两种基本操作:进栈(push,也称为入栈)和出栈(pop,也称为弹出)。进栈是指将新元素插入栈中,而出栈是删除最后进栈的元素。有时候需要得到栈顶元素,可以通过执行top函数返回。
栈具有后进先出(Last In, First Out)的特性,因此又称为后进先出的表(LIFO)。
2 栈的实现
栈有两种常见的实现方法:一是采用链表,二是采用数组实现。采用哪种方法好取决于具体应用。
2.1 栈的链表实现
先给出用单链表实现的栈的模型,初始时栈为空:
从这里我们可以看出栈的初态和单链表的初态一样,也就是说,栈的链表实现保留了头结点。
如果我们依次将A1,A2,……,An进栈,这时栈的模型如下:
好了,模型弄明白后其实进栈和出栈操作大家应该会有想法了,对,进栈其实就是在头结点后面插入新元素,如下push(x, S):
出栈当然是要删除头结点后面的元素,如下pop(S):
好了,大家看代码吧。首先Stackli.h:
typedef int ElementType;#ifndef STACKLI_H#define STACKLI_Hstruct Node;typedef struct Node *PtrToNode;typedef PtrToNode Stack;int isEmpty( Stack S );Stack createStack( );void disposeStack( Stack S );void makeEmpty( Stack S );void push( ElementType x, Stack S );ElementType top( Stack S );void pop( Stack S );#endif
Fatal.h:
#include <stdio.h>#include <stdlib.h>#define Error( Str ) FatalError( Str )#define FatalError( Str ) fprintf( stderr, "%s\n", Str ), exit( 1 )
Stackli.c:
#include <stdlib.h>#include "Stackli.h"#include "Fatal.h"struct Node{ ElementType element; PtrToNode next;};int isEmpty( Stack S ){ return S->next == NULL;}Stack createStack( ){ Stack S; S = malloc( sizeof( struct Node ) ); if( S == NULL ) FatalError( "Out of space!!!" ); S->next = NULL; return S;}void makeEmpty( Stack S ){ if( S == NULL ) Error( "Must use CreateStack first" ); else while( !isEmpty( S ) ) pop( S );}void disposeStack( Stack S ){ makeEmpty( S ); free( S );}void push( ElementType x, Stack S ){ PtrToNode tmpCell; tmpCell = malloc( sizeof( struct Node ) ); if( tmpCell == NULL ) FatalError( "Out of space!!!" ); else { tmpCell->element = x; tmpCell->next = S->next; S->next = tmpCell; }}ElementType top( Stack S ){ if( isEmpty( S ) ) Error( "Empty stack" ); return S->next->element;}void pop( Stack S ){ PtrToNode firstCell; if( isEmpty( S ) ) Error( "Empty stack" ); else { firstCell = S->next; S->next = S->next->next; free( firstCell ); }}
main.c:
#include <stdio.h>#include <stdlib.h>#include "Stackli.h"int main(int argc, char *argv[]) { Stack S; S = createStack( ); for(int i = 0; i < 5; i++ ) push( i, S ); while( !isEmpty( S ) ) { printf( "%d\n", top( S ) ); pop( S ); } disposeStack( S ); return 0;}
2.2 栈的数组实现
如果在任何时候,你的程序中栈的大小都不会太大,则用数组实现栈可能是更好的方案。数组实现栈时,其数据结构包含两部分:栈的结构和栈的数组。如下图所示:
中间显示的是栈的结构,它有三个成员:
- capacity:int型变量,存储栈的容量。
- topOfStack:int型变量,存储栈顶元素的下标,用来指示栈顶位置。空栈时为-1。
- array:指针,指向栈的数组。
\
上图中右面是栈的数组,它是一个动态数组。为了和抽象的栈的模型相对应,我们将数组画成竖的。所以,靠近上面的位置是栈顶,而array[0]为栈底(栈非空时)。
至此,栈的数组实现应该水落石出了。首先是Stackar.h:
typedef int ElementType;#ifndef STACKAR_H#define STACKAR_Hstruct StackRecord;typedef struct StackRecord *Stack;int isEmpty( Stack S );int isFull( Stack S );Stack createStack( int maxElements );int size(Stack S);void disposeStack( Stack S );void makeEmpty( Stack S );void push( ElementType x, Stack S );ElementType top( Stack S );void pop( Stack S );ElementType topAndPop( Stack S );#endif
Fatal.h:
#include <stdio.h>#include <stdlib.h>#define Error( Str ) FatalError( Str )#define FatalError( Str ) fprintf( stderr, "%s\n", Str ), exit( 1 )
Stackar.c:
#include <stdlib.h>#include "Stackar.h"#include "Fatal.h"#define EmptyTOS ( -1 )#define MinStackSize ( 5 )struct StackRecord{ int capacity; int topOfStack; ElementType *array;};int isEmpty( Stack S ){ return S->topOfStack == EmptyTOS;}int isFull( Stack S ){ return S->topOfStack == S->capacity - 1;}Stack createStack( int maxElements ){ Stack S; if( maxElements < MinStackSize ) Error( "Stack size is too small" ); S = malloc( sizeof( struct StackRecord ) ); if( S == NULL ) FatalError( "Out of space!!!" ); S->array = malloc( sizeof( ElementType ) * maxElements ); if( S->array == NULL ) FatalError( "Out of space!!!" ); S->capacity = maxElements; makeEmpty( S ); return S;}int size(Stack S){ return S->topOfStack + 1;}void makeEmpty( Stack S ){ S->topOfStack = EmptyTOS;}void disposeStack( Stack S ){ if( S != NULL ) { free( S->array ); free( S ); }}void push( ElementType x, Stack S ){ if( isFull( S ) ) Error( "Full stack" ); S->array[ ++S->topOfStack ] = x;}ElementType top( Stack S ){ if( isEmpty( S ) ) Error( "Empty stack" ); return S->array[ S->topOfStack ];}void pop( Stack S ){ if( isEmpty( S ) ) Error( "Empty stack" ); S->topOfStack--;}ElementType topAndPop( Stack S ){ if( isEmpty( S ) ) Error( "Empty stack" ); return S->array[ S->topOfStack-- ];}
测试程序main.c:
#include <stdio.h>#include <stdlib.h>#include "Stackar.h"int main(int argc, char *argv[]) { Stack S; S = createStack(15); for(int i = 0; i < 10; i++ ) push( i, S ); printf("栈的大小为:%d\n", size(S)); while( !isEmpty( S ) ) { printf( "%d\n", top( S ) ); pop( S ); } disposeStack( S ); return 0;}
- 栈
- 栈
- 栈
- 栈
- 栈
- 栈
- 栈
- 栈
- 栈
- 栈
- 栈
- 栈
- 栈
- 栈
- 栈
- 栈
- 栈
- 栈
- System.out.println引发的volatile和synchronize
- 使用动画的注意事项
- 一个沪漂三年IT青年的感悟
- Windows系统结构图
- 欢迎使用CSDN-markdown编辑器
- 栈
- CSS选择器
- 25个经典的Spring面试问答
- leetcode-19-Remove Nth Node From End of List
- Linux下图形函数库---curses.h
- GridView smoothScrollBy移动距离不正确
- 视音频编解码基本术语及解释
- 数据访问的一些笔记
- The Dole Queue(子过程设计)(UVa 133)