栈及其应用 - C语言实现(摘自数据结构与算法分析 C语言描述)
来源:互联网 发布:一建培训班哪家好 知乎 编辑:程序博客网 时间:2024/04/29 18:12
一、概述:
栈(stack)是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫做栈的顶(top)。对栈的基本操作有Push(进栈)和Pop(出栈),前者相当于插入,后者则是删除最后插入的元素。
栈有时又叫做LIFO(后进先出)表。在图1中描述的模型只象征着Push是输入操作而Pop和Top是输出操作。
图1 栈模型:通过Push向栈输入,通过Pop从栈输出
二、实现
1. 栈的链表实现
文件名:stack_list.h
#ifndef _STACK_LIST_H#define _STACK_LIST_H#define ElementType intstruct Node;typedef struct Node *PtrToNode;typedef PtrToNode Stack;int IsEmpty( Stack S );Stack CreateStack( void );void DisposeStack( Stack S );void MakeEmpty( Stack S );void Push( ElementType X, Stack S );ElementType Top( Stack S );void Pop( Stack S );#endif /* _STACK_LIST_H */文件名:stack_list.c
#include "stack_list.h"#include "fatal.h"struct Node{ ElementType Element; PtrToNode Next;};intIsEmpty( Stack S ){ return S->Next == NULL;}StackCreateStack( void ){ Stack S; S = malloc( sizeof( struct Node ) ); if( S == NULL ) FatalError( "Out of space!!!" ); S->Next = NULL; MakeEmpty( S ); return S;}voidMakeEmpty( Stack S ){ if( S == NULL ) Error( "Must use CreateStack first" ); else while( !IsEmpty( S ) ) Pop( S );}voidPush( 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; }}ElementTypeTop( Stack S ){ if( !IsEmpty( S ) ) return S->Next->Element; Error( "Empty stack" ); return 0;}voidPop(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 "stack_list.h"int main(){ Stack S; int n, num, m; int i; S = CreateStack(); printf( "Initialization complete.\n" ); printf( "Please input the number of elements in the stack:\n" ); scanf( "%d", &n ); printf( "Please input %d elements push into stack:\n", n ); for(i = 0; i < n; i++ ) { scanf( "%d", &num ); Push( num, S ); } printf( "Please input the numbers you want pop out from the stack(no more than:%d)\n", n ); scanf( "%d", &n ); printf( "Pop out from the stack %d elements in turns:\n", n ); for( i = 0; i < n; i++ ) { m = Top( S ); Pop( S ); printf( "%3d",m ); } printf( "\n" ); return 0;}
2. 栈的数组实现
文件名:stack_array.h
#ifndef _STACK_ARRARY_H#define _STACK_ARRARY_Hstruct StackRecord;typedef struct StackRecord *Stack;#define ElementType intint IsEmpty( Stack S );int IsFull( Stack S );Stack CreateStack( int MaxElements );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 /* _STACK_ARRARY_H */
文件名:stack_array.c
#include "stack_array.h"#include "fatal.h"#define EmptyTOS ( -1 )#define MinStackSize ( 5 )struct StackRecord{ int Capacity; int TopOfStack; ElementType *Array;};StackCreateStack( 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;}voidDisposeStack( Stack S ){ if( S != NULL ) { free( S-> Array ); free( S ); }}intIsEmpty( Stack S ){ return S->TopOfStack == EmptyTOS;}voidMakeEmpty( Stack S ){ S->TopOfStack = EmptyTOS;}voidPush( ElementType X, Stack S ){ if( IsFull( S ) ) Error( "Full Stack" ); else S->Array[ ++S->TopOfStack ] = X;}intIsFull( Stack S ){ return S->TopOfStack == S->Capacity - 1;}ElementTypeTop( Stack S ){ if( !IsEmpty( S ) ) return S->Array[ S->TopOfStack ]; Error( "Empty Stack" ); return 0; /* Return value used to avoid * warning */}voidPop( Stack S ){ if( IsEmpty( S ) ) Error( "Empty Stack" ); else S->TopOfStack--;}ElementTypeTopAndPop( Stack S ){ if( !IsEmpty( S ) ) return S->Array[ S->TopOfStack-- ]; Error( "Empty Stack" ); return 0; /* Return value used to avoid * warning */}
文件名:main.c
#include <stdio.h>#include "stack_array.h"#include "fatal.h"int main(){ Stack S; int n, num, m; int i; S = CreateStack( 10 ); printf( "Initialization complete.\n" ); printf( "Please input the number of elements in the stack:\n" ); scanf( "%d", &n ); printf( "Please input %d elements push into stack:\n", n ); for( i = 0; i < n; i++ ) { scanf( "%d", &num ); Push( num, S ); } printf( "Top of the stack:%d\n", Top( S ) ); printf( "Please input the numbers you want pop out from the stack(no more than %d):\n", n ); scanf( "%d", &n ); printf( "Pop out from the stack %d elements in turns:\n", n ); for( i = 0; i < n; i++ ) { m = TopAndPop( S ); printf( "%3d", m ); } printf( "\n" ); return 0;}
附录:上述代码中用到了Error、FatalError等函数,其实现如下(即fatal.h文件):
#include <stdio.h>#include <stdlib.h>#define Error( Str ) FatalError( Str )#define FatalError( Str ) fprintf( stderr, "%s\n", Str ), exit( 1 )
三、应用
1. 平衡符号:
编译器检查你的程序的语法错误,但是常常由于缺少一个符号(如遗漏一个花括号或是注释起始符)引起编译器列出上百行的诊断,而真正的错误并没有找出。
在这种情况下,一个有用的工具就是检验是否每件事情都能成对出现的一个程序。于是,每一个右花括号、右方括号及右圆括号必然对应其相应的左括号。序列“[()]”是合法的,但“[(])”是错误的。显然,不值得为此编写一个大型程序,事实上检验这些事情是很容易的。为简单起见,我们就圆括号、方括号和花括号进行检验并忽略出现的任何其他字符。
这个简单的算法用到一个栈,叙述如下:
做一个空栈。读入字符直到文件尾。如果字符是一个开放符号,则将其推入栈中。如果字符是一个封闭符号,则当栈空时报错。否则,将栈元素弹出。如果弹出的符号不是对应的开放符号,则报错。在文件尾,如果栈非空则报错。
算法实现:
boolbalance( char ch, Stack S ){ switch( ch ) { case '(': case '[': case '{': Push( ch, S ); break; case ')': if( IsEmpty( S ) || Top( S ) != '(' ) { return false; } Pop( S ); break; case ']': if( IsEmpty(S) || Top(S) != '[' ) { return false; } Pop( S ); break; case '}': if( IsEmpty( S ) || Top( S ) != '{' ) { return false; } Pop( S ); break; default: break; } return true;}
2. 后缀表达式
3. 中缀到后缀的转换
4. 函数调用
附录:上述代码中用到了Error、FatalError等函数,其实现如下(即fatal.h文件):
#include <stdio.h>#include <stdlib.h>#define Error( Str ) FatalError( Str )#define FatalError( Str ) fprintf( stderr, "%s\n", Str ), exit( 1 )
备注:本文摘自《数据结构与算法分析 C语言描述 Mark Allen Weiss著》,代码经gcc编译测试通过。
附件下载:
http://download.csdn.net/detail/shuxiao9058/4212444#stack_array_20111229.tar.gz,
http://download.csdn.net/detail/shuxiao9058/4212446#stack_list_20111229.tar.gz,
http://download.csdn.net/detail/shuxiao9058/4212449#stack_balance_20111229.tar.gz
- 栈及其应用 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 栈及其应用 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 排序 - C语言实现(摘自数据结构与算法分析C语言描述))
- 队列 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 二叉查找树 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 散列 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 优先队列(堆) - C语言实现(摘自数据结构与算法分析 C语言描述)
- 散列 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 优先队列(堆) - C语言实现(摘自数据结构与算法分析 C语言描述)
- 散列 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 二叉查找树 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 队列 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 队列 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 优先队列(堆) - C语言实现(摘自数据结构与算法分析 C语言描述)
- AVL(Adelson-Velskii和Landis)树 - C语言实现(摘自数据结构与算法分析 C语言描述)
- AVL(Adelson-Velskii和Landis)树 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 排序-c语言实现(摘自数据结构与算法分析c语言实现)
- 数据结构与算法分析 C语言描述 单链表的实现
- 1.4.4 mother milk(模拟 DFS )
- ACCESS 数据库 自增字段 语句
- vmvare server 2.2安装 vmvare tools 过程
- 用java做的一个小游戏—黑白反斗棋(适合菜鸟)
- MP4文件格式的解析,以及MP4文件的分割算法
- 栈及其应用 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 关于 java中Calendar类的用法 ,在Eclipse中运行
- 【从头学android】在两个Activity中传递参数
- java calendar 类的用法
- JQuery 斑马条纹功能实现
- Google Protocol Buffers浅析(一)
- AsyncTask的用法
- mp4文件格式解析
- android的Handler