严蔚敏数据结构C语言实现栈的基本操作
源码如下:
#include <stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OVERFLOW -1
#define OK 1
#define ERROR 0
typedef int Status;
typedef int SElemType;
typedef struct {
SElemType* base;
SElemType* top;
int stacksize;
} SqStack;
Status InitStack ( SqStack* S)
{
S-> base = ( SElemType* ) malloc ( STACK_INIT_SIZE * sizeof ( SElemType) ) ;
if ( ! S-> base) exit ( OVERFLOW) ;
S-> top = S-> base;
S-> stacksize = STACK_INIT_SIZE;
return OK;
}
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 ( OVERFLOW) ;
S-> top = S-> base + S-> stacksize;
S-> stacksize + = STACKINCREMENT;
}
* S-> top++ = e;
return OK;
}
Status Pop ( SqStack* S, SElemType* e)
{
if ( S-> top == S-> base)
return ERROR;
* e = * -- S-> top;
return OK;
}
Status GetTop ( SqStack S, SElemType* e)
{
if ( S. top == S. base)
return ERROR;
* e = * ( -- S. top) ;
return OK;
}
Status StackEmpty ( SqStack S)
{
if ( S. top == S. base)
return OK;
else
return ERROR;
}
int StackLength ( SqStack S)
{
return ( S. top - S. base) ;
}
Status PrintElem ( SElemType e)
{
printf ( "%d\t" , e) ;
return OK;
}
Status StackTraverse ( SqStack S, Status ( * visit) ( SElemType) )
{
SElemType* p;
p = S. base;
while ( p != S. top)
{
if ( ! visit ( * p) )
return ERROR;
p++ ;
}
return OK;
}
Status ClearStack ( SqStack* S)
{
S-> top = S-> base;
return OK;
}
Status DestroyStack ( SqStack* S)
{
free ( S-> base) ;
S-> base = NULL ;
S-> top = NULL ;
S-> stacksize = 0 ;
return OK;
}
int main ( )
{
SqStack S;
SElemType e;
int n, i;
InitStack ( & S) ;
printf ( "请输入需要入栈的数据个数:\n" ) ;
scanf_s ( "%d" , & n) ;
printf ( "请输入需要入栈的%d个数据,用空格隔开:\n" , n) ;
for ( i = 0 ; i < n; i++ )
{
scanf_s ( "%d" , & e) ;
Push ( & S, e) ;
}
printf ( "\n" ) ;
printf ( "栈的遍历\n" ) ;
StackTraverse ( S, PrintElem) ;
printf ( "\n栈的长度为:\n" ) ;
printf ( "%d" , StackLength ( S) ) ;
printf ( "\n返回栈首元素:\n" ) ;
GetTop ( S, & e) ;
printf ( "%d" , e) ;
printf ( "\n元素出栈后\n" ) ;
while ( ! StackEmpty ( S) )
{
Pop ( & S, & e) ;
printf ( "%d\t" , e) ;
}
printf ( "\n" ) ;
printf ( "\n\t\t\tBy Cherish599" ) ;
printf ( "\n" ) ;
return 0 ;
}
运行截图:
线性栈(参考大话数据结构)
源码如下:
#include <stdio.h>
#define MAXSIZE 100
typedef int SELemType;
typedef struct
{
SELemType data[ MAXSIZE] ;
int top;
} SeqStack;
void Init_SeqStack ( SeqStack* s)
{
s-> top = - 1 ;
}
int Empty_SeqStack ( SeqStack* s)
{
if ( s-> top == - 1 )
return 1 ;
else
return 0 ;
}
void Push_Stack ( SeqStack * s, SELemType e)
{
if ( s-> top == MAXSIZE - 1 )
printf ( "Stack is full!\n" ) ;
else
{
s-> top++ ;
s-> data[ s-> top] = e;
}
}
void Pop_SeqStack ( SeqStack* s, SELemType* e)
{
if ( s-> top == - 1 )
printf ( "栈为空!\n" ) ;
else
{
* e = s-> data[ s-> top] ;
s-> top-- ;
}
}
void Top_SeqStack ( SeqStack* s, SELemType* e)
{
if ( s-> top == - 1 )
printf ( "栈为空!\n" ) ;
else
{
* e = s-> data[ s-> top] ;
printf ( "出栈成功!\n" ) ;
}
}
void Output_SeqStack ( SeqStack* s)
{
SeqStack* w;
int i;
printf ( "栈中的元素有:" ) ;
for ( i = s-> top; i >= 0 ; i-- )
printf ( "%d " , s-> data[ i] ) ;
printf ( "\n" ) ;
}
void Menu ( )
{
puts ( "****************" ) ;
puts ( "1.初始化" ) ;
puts ( "2.判断栈为空" ) ;
puts ( "3.入栈" ) ;
puts ( "4.出栈" ) ;
puts ( "5.取栈顶元素" ) ;
puts ( "0.程序结束" ) ;
puts ( "****************" ) ;
}
int main ( )
{
SeqStack S;
int choice = - 1 , i, n;
SELemType e;
Menu ( ) ;
while ( choice == - 1 )
{
printf ( "\nYour choice is:" ) ;
scanf_s ( "%d" , & i) ;
switch ( i)
{
case 1 :
Init_SeqStack ( & S) ;
printf ( "初始化完成!\n" ) ;
break ;
case 2 :
if ( Empty_SeqStack ( & S) == 1 )
printf ( "栈为空!\n" ) ;
else
printf ( "栈不为空!\n" ) ;
break ;
case 3 :
printf ( "请输入入栈的数量:" ) ;
scanf_s ( "%d" , & n) ;
printf ( "请输入需要入栈的数据,用空格隔开:" ) ;
for ( int j = 0 ; j < n; j++ )
{
scanf_s ( "%d" , & e) ;
Push_Stack ( & S, e) ;
}
Output_SeqStack ( & S) ;
break ; ;
case 4 :
Pop_SeqStack ( & S, & e) ;
Output_SeqStack ( & S) ;
break ;
case 5 :
Top_SeqStack ( & S, & e) ;
printf ( "栈顶元素为:%d\n" , e) ;
Output_SeqStack ( & S) ;
break ;
case 0 :
choice = 0 ;
break ;
default : printf ( "选择有误,请重新选择 \n" ) ;
}
}
puts ( "\n" ) ;
puts ( "\t\t\t\t By Cherish599" ) ;
return 0 ;
}
运行截图:
两栈共享空间:
如果有两个类型相同的栈,我们为它们分别开辟了数组空间。极有可能是一个栈已经满了,再入栈就溢出了,而另一个栈却还有很多存储空间。这又何必呢?我们完全可以用一个数组来存储两个栈,只不过需要一些小的技巧。
我们的做法如下,数组有两个端点,两个栈有两个栈底。让一个栈的栈底为数组的始端,即数组下标为0的位置。让另一个栈的栈底为数组的末端,即数组下标为n-1的位置。这样如果两个栈增加元素,就是两端点向中间延伸。
从这里可以分析出来,栈 1 为空时,就是top1等于-1;而当top2等于n时,即栈2为空;当top1 + 1 == top2 时为栈满
1. 两栈共享空间的结构代码
typedef struct {
SElemType data[ MAXSIZE] ;
int top1;
int top2;
} SqDoubleStack;
2.入栈操作(stackNumber判断是栈1还是栈2)
Status push ( SqDoubleStack * S, SElemType e, int stackNumber) {
if ( S-> top1 + 1 == S-> top2) {
return ERROR;
}
if ( stackNumber == 1 ) {
top1 ++ ;
S-> data[ top1] = e;
} else if ( stackNumber == 2 ) {
top2-- ;
S-> data[ top2] = e;
}
return OK;
}
3.出栈操作
Status Pop ( SqDoubleStack * S, SElemType * e, int stackNumber) {
if ( stackNumber == 1 ) {
if ( S-> top1 == - 1 ) {
return ERROR;
}
* e = S-> data[ S-> top1]
S-> top1-- ;
} else if ( stackNumber == 2 ) {
if ( S-> top2 == MAXSIZE) {
return ERROR;
}
* e = S-> data[ S-> top2] ;
S-> top2++ ;
}
return OK;
}
栈的链式存储结构:(参考大话数据结构)
链栈指向图:
源码如下:
#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;
}
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 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;
}
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 ;
}
StackNode* node = stack-> top;
while ( node)
{
printf ( "%d," , node-> data) ;
node = node-> next;
}
puts ( "" ) ;
return ;
}
int main ( int argc, char * argv[ ] )
{
LinkStack stack;
StackNode snode;
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\n" , GetLengthLinkStack ( & stack) ) ;
printf ( "栈顶元素为: %d\n" , GetTop ( & stack, & snode) ) ;
printf ( "\n" ) ;
printf ( "\t\t\t\t By Cherish599" ) ;
puts ( "\n" ) ;
return 0 ;
}
运行截图: