我们来介绍下堆栈,在开始介绍之前,先区分开两种数据结构,堆和栈,区别如下
在数据结构中,栈是一种线性表,而且是只可在表的一端进行插入和删除运算的线性表;而堆是一种树形结构,其满中树中任一非叶结点的关键字均不大于或不小于其左右子树的结点的关键字
堆是一种特殊的线性表,其特殊在哪呢?特殊在只能在线性表的一端进行插入和删除操作,该图是百度百科中的解释
基于顺序存储的栈代码实现如下
//Stack.h
#define STACK_INIT_SIZE 100
#define STACK_INCREATMENT 10
typedef enum Status
{
success,fail,overflow,underflow
};
typedef int StackEntry;
typedef struct Stack
{
int top;//top = -1表示空栈 top = stack_size-1表示栈满
StackEntry * entry;
int stack_size;
}Stack,*StackPtr;
typedef StackPtr Ptr;
Status Stack_Init(StackPtr s);
void Stack_Destroy(StackPtr s);
int Stack_Size(StackPtr s);
bool Stack_Empty(StackPtr s);
void Stack_Clear(StackPtr s);
Status Stack_Top(StackPtr s,StackEntry * item);
Status Stack_Push(StackPtr s,StackEntry item);
Status Stack_Pop(StackPtr s,StackEntry * item);
void Stack_Print(StackPtr s);
//Stack.cpp
#include "Stack.h"
#include <stdio.h>
#include <stdlib.h>
Status Stack_Init(StackPtr s)
{
Status outcome = fail;
if(s != NULL) //不能对NULL指针进行操作
{
s->entry = (StackEntry *)malloc(STACK_INIT_SIZE*sizeof(StackEntry));
if(s->entry)
{
s->stack_size = STACK_INIT_SIZE;
s->top = -1; //表示空栈
outcome = success;
}
}
return outcome;
}
void Stack_Destroy(StackPtr s)
{
Stack_Clear(s);
if(s)
{
if(s->entry)
{
free(s->entry);
s->entry = NULL;
}
}
}
int Stack_Size(StackPtr s)
{
return (s->top+1);
}
bool Stack_Empty(StackPtr s)
{
return (s->top == -1);
}
void Stack_Clear(StackPtr s)
{
if(s)
{
s->top = -1;
}
}
Status Stack_Top(StackPtr s,StackEntry * item)
{
Status outcome = success;
if(Stack_Empty(s))
{
outcome = underflow;
}
else
{
*item = s->entry[s->top];
}
return outcome;
}
Status Stack_Push(StackPtr s,StackEntry item) //入栈
{
Status outcome = success;
if(s->top == s->stack_size-1)
outcome = overflow;
else
{
s->top++;
s->entry[s->top] = item;
}
return outcome;
}
Status Stack_Pop(StackPtr s,StackEntry * item)//出栈
{
Status outcome =success;
if(s->top == -1)
{
outcome = underflow;
}
else
{
*item = s->entry[s->top];
s->top--;
}
return outcome;
}
void Stack_Print(StackPtr s)
{
for(int i=0;i<=s->top;i++)
{
printf("%d ",s->entry[i]);
}
printf("\n");
}
//TestStack.h
#include "Stack.h"
Status Test_PushPrint(StackPtr s,StackEntry data[],int n);
Status Test_PushPop(StackPtr s,StackEntry data[],int n);
Status Test_TopSizeClearEmpty(StackPtr s,StackEntry data[],int n);
//TestStack.cpp
#include "TestStack.h"
#include <stdio.h>
#include <stdlib.h>
/*
为方便测试结果 将下列函数中的主体移至mian.cpp中
*/
Status Test_PushPrint(StackPtr s,StackEntry data[],int n)
{
Status outcome;
outcome = Stack_Init(s);
if(outcome == success)
{
printf("顺序栈建立成功\n");
for(int i=0; i<n ;i++)
{
outcome = Stack_Push(s,data[i]);
if(outcome!=success)
{
break;
}
}
}
return outcome;
}
Status Test_PushPop(StackPtr s,StackEntry data[],int n)
{
Status outcome;
StackEntry elem;
outcome = Stack_Init(s);
if(outcome == success)
{
for(int i=0 ;i<n;i++)
{
outcome = Stack_Push(s,data[i]);
if(outcome !=success)
break;
}
}
return outcome;
}
Status Test_TopSizeClearEmpty(StackPtr s,StackEntry data[],int n)
{
Status outcome;
StackEntry elem;
outcome = Stack_Init(s);
if(outcome == success)
{
for(int i=0 ;i<n ;i++)
{
outcome = Stack_Push(s,data[i]);
if(outcome !=success)
break;
}
}
return outcome;
}
//main.cpp
#include "TestStack.h"
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int size,opt =1 ,* data;
Stack stack;
Status outcome;
StackEntry elem;
while(opt!=4)
{
puts("1 测试 建立空栈 入栈 打印");
puts("2 测试 建立空栈 入栈 出栈");
puts("3 测试 建立空栈 入栈 查看栈顶元素 求栈长度 清空栈 栈是否为空");
puts("4 退出测试");
scanf("%d",&opt);
switch(opt)
{
case 1:{
//Test_PushPrint(StackPtr s,StackEntry data[],int n)
printf("栈的长度\n");
scanf("%d",&size);
data = (StackEntry *)malloc(sizeof(StackEntry)*size);
if(data == NULL) break;
printf("输入栈元素\n");
for(int i=0 ;i<size ;i++)
{
scanf("%d",&data[i]);
}
outcome = Test_PushPrint(&stack,data,size);
if(outcome==success)
{
Stack_Print(&stack);
}
free(data);
Stack_Destroy(&stack);
break;
}
case 2:{
//Test_PushPop(StackPtr s,StackEntry data[],int n)
printf("栈的长度\n");
scanf("%d",&size);
data = (StackEntry *)malloc(sizeof(StackEntry)*size);
if(data == NULL) break;
printf("输入栈元素\n");
for(int i=0 ;i<size ;i++)
{
scanf("%d",&data[i]);
}
outcome = Test_PushPop(&stack,data,size);
if(outcome==success)
{
while(!Stack_Empty(&stack))
{
outcome = Stack_Pop(&stack,&elem);
printf("%d ",elem);
}
printf("\n");
}
free(data);
Stack_Destroy(&stack);
break;
}
case 3:{
//Test_TopSizeClearEmpty(StackPtr s,StackEntry data[],int n)
printf("栈的长度\n");
scanf("%d",&size);
data = (StackEntry *)malloc(sizeof(StackEntry)*size);
if(data == NULL) break;
printf("输入栈元素\n");
for(int i=0 ;i<size ;i++)
{
scanf("%d",&data[i]);
}
outcome = Test_TopSizeClearEmpty(&stack,data,size);
if(outcome==success)
{
Stack_Top(&stack,&elem);
printf("栈顶元素为:%d\n",elem);
}
printf("栈的长度为:%d\n",Stack_Size(&stack));
Stack_Clear(&stack);
if(Stack_Empty(&stack) == true)
{
printf("栈已清空\n");
}
else
{
printf("清空失败\n");
}
free(data);
Stack_Destroy(&stack);
break;
}
case 4:{
break;
}
}
}
return 0;
}
为了做对比,我们也将基于链式存储的栈代码实现如下
Status Stack_Init(StackPtr s)
{
Status outcome = fail;
if(*s == NULL)
{
Ptr p = (Ptr)malloc(sizeof(Stack));
if(p==NULL) return outcome;
(*s) = p;
(*s)->top = NULL;
outcome = success;
}
return outcome;
}
void Stack_Clear(StackPtr s)
{
StackNodePtr p;
if(*s)
{
while ((*s)->top)
{
p = (*s)->top;
(*s)->top = (*s)->top->next;
free(p);
}
}
}
void Stack_Destroy(StackPtr s)
{
Stack_Clear(s);
if(*s)
{
free(*s);
*s = NULL;
}
}
int Stack_Size(StackPtr s)
{
int len = 0;
while((*s)->top)
{
len++;
(*s)->top = (*s)->top->next;
}
return len;
}
bool Stack_Empty(StackPtr s)
{
return ((*s)->top == NULL);
}
Status Stack_Top(StackPtr s,StackEntry * item)
{
Status outcome = success;
if(Stack_Empty(s))
{
outcome = underflow;
}
else
{
*item = (*s)->top->entry;
}
return outcome;
}
Status Stack_Push(StackPtr s,StackEntry item)
{
Status outcome = success;
StackNodePtr p = (StackNodePtr)malloc(sizeof(StackNode));
if(p == NULL)
{
outcome = overflow;
}
else
{
p->entry = item;
p->next = (*s)->top;
(*s)->top = p;
}
return outcome;
}
Status Stack_Pop(StackPtr s,StackEntry * item)
{
Status outcome = success;
if(Stack_Empty(s))
{
outcome = underflow;
}
else
{
StackNodePtr p = (*s)->top;
(*s)->top = p->next;
*item = p->entry;
free(p);
}
return outcome;
}
void Stack_Print(StackPtr s)
{
while((*s)->top)
{
printf("%d",(*s)->top->entry);
(*s)->top = (*s)->top->next;
}
printf("\n");
}