数据结构:《栈》

《栈》

目录:

1.栈的定义

2.栈的抽象数据类型

3.顺序栈

4.链栈

 

1.栈的定义

•  栈(Stack是限定仅在表尾进行插入和删除的线性表。

•  我们把允许插入和删除的一端称为栈顶(top,另一端称为栈底(bottom)。

•  不含任何数据元素的栈称为空栈

•  栈为后进先出(Last In First Out的线性表,简称LIFO结构。(如图1所示)

       图1

•  栈的插入操作,叫做压入栈(push,或压栈

•  栈的删除操作,叫做弹出栈(pop,或弹栈

 

2.栈的抽象数据类型

类型名称:堆栈(Stack).

数据的对象集合:一个有0个或多个的元素的有求线性表。

操作集:对于一个具体的长度为正整数MaxSize的堆栈S属于Stack,记堆栈中的任意一个元素X属于ElementType,堆栈的基本操作主要有:

 

 

Stack CreateStack(int MaxSize);生成空堆栈,其最大长度为MaxSize。

bool IsFull(Stack S);判断堆栈S是否已满。

bool IsEmpty(Stack S); 判断堆栈S是否是空。

bool Push(Stack S,ElementType X);入栈。

ElementType Pop(Stack S);出栈。

 

3.顺序栈

一. 栈的顺序存储实现

#include<stdio.h>
#include<stdlib.h>

#define true 1 
#define ERROR 0
#define false 0

typedef int bool;
typedef int ElementType;
typedef int Position;
typedef struct SNode* PtrToSNode;
typedef PtrToSNode Sequence_Stack;

struct SNode
{
	ElementType* Data;//存储元素的数组 
	Position top;//栈顶指针 
	int MaxSize;//顺序栈的最大容量 
};

Sequence_Stack CreateStack(int MaxSize);
bool IsFull(Sequence_Stack S);
bool IsEmpty(Sequence_Stack S);
bool Push(Sequence_Stack S,ElementType X);
ElementType Pop(Sequence_Stack S);

int main()
{
	printf("请您输入您要输入多少数!\n");
	int n = 0;
	int i = 0;
	scanf("%d", &n);
	Sequence_Stack S = CreateStack(n);
	int m = 0;
	while(i < n)
	{
		scanf("%d", &m);
		Push(S,m);
		i++;
	} 
	i = 0;
	
	while(i < n)
	{
		printf("%d\n", Pop(S));
		i++;
	} 
	
	return 0;
}

Sequence_Stack CreateStack(int MaxSize)
{
	Sequence_Stack S = (Sequence_Stack)malloc(sizeof(struct SNode));
	S->Data = (ElementType*)malloc(MaxSize*sizeof(ElementType)); 
	S->top = -1;
	S->MaxSize = MaxSize;
	return S;
}

bool IsEmpty(Sequence_Stack S)
{
	if(S->top == -1)
	{
		return true;
	}
	else
	{
		return false;
	}
}

bool IsFull(Sequence_Stack S)
{
	if(S->top == S->MaxSize-1)
	{
		return true;
	}
	else
	{
		return false;
	}	
}

bool Push(Sequence_Stack S, ElementType X)
{
	if(IsFull(S))
	{
		printf("顺序栈满!\n");
		return false;
	}
	else
	{
		S->top++;
		S->Data[S->top] = X;
		//简洁版:S->Data[++(S->top)] = X; 
		return true;
	}
}

ElementType Pop(Sequence_Stack S)
{
	if(IsEmpty(S))
	{
		printf("顺序栈空!\n");
		return false;
	}
	else
	{
		S->top--;
		return S->Data[S->top+1];
		//简洁版:return S->Data[(S->top)--]; 
	}
}

二. 栈的共享顺序存储实现

通常,当两个栈的空间需求有相反关系时,也就是一个栈增长时另一个栈在缩短的情况下,可以使用两栈共享空间。

#include<stdio.h>
#include<stdlib.h>

#define true 1 
#define ERROR 0
#define false 0

typedef int bool;
typedef int ElementType;
typedef int Position;
typedef struct SNode* PtrToSNode;
typedef PtrToSNode Sequence_Share_Stack;

struct SNode
{
	ElementType* Data;//存储元素的数组 
	Position top1;//堆栈1的栈顶指针 
	Position top2;//堆栈2的栈顶指针 
	int MaxSize;//顺序栈的最大容量 
};

Sequence_Share_Stack CreateStack(int MaxSize);
bool Push(Sequence_Share_Stack S, ElementType X, int Tag);
ElementType Pop(Sequence_Share_Stack S, int Tag);

int main()
{
	//请读者根据自己的需求来完善代码,这里已经把共享栈搭建好了! 
	return 0;
} 

Sequence_Share_Stack CreateStack(int MaxSize)
{
	Sequence_Share_Stack S = (Sequence_Share_Stack)malloc(sizeof(struct SNode));
	S->Data = (ElementType*)malloc(MaxSize*sizeof(ElementType)); 
	S->top1 = -1;
	S->top2 = S->MaxSize;
	S->MaxSize = MaxSize;
	return S;
}

bool Push(Sequence_Share_Stack S, ElementType X, int Tag)
{
	if(S->top2 - S->top1 == 1)
	{
		printf("共享栈满!\n");
		return false;
	}
	else
	{
		if(Tag == 1)
		{
			S->Data[++(S->top1)] = X; 	
		}
		else
		{
			S->Data[--(S->top2)] = X; 
		}
		return true;
	}
}

ElementType Pop(Sequence_Share_Stack S, int Tag)
{
	if(Tag == 1)
	{
		if(S->top1 == -1)
		{
			printf("栈1空\n");
		}
		else
		{
			return S->Data[(S->top1)--];
		}
	}
	else
	{
		if(S->top2 == S->MaxSize)
		{
			printf("栈2空\n");
			
		} 
		else
		{
			return S->Data[(S->top2)++];
		} 
		
		
	}
}

4.链栈

栈的链式存储实现

//链栈基本结构已搭建好了,用斐波那契函数来完善了链栈的实现

#include<stdio.h>
#include<stdlib.h>

#define OK 1
#define ERROR 0

typedef int bool;
typedef int SElemType;

typedef struct StackNode
{
        SElemType data;
        struct StackNode *next;
}StackNode,*LinkStackPtr;

typedef struct
{
        LinkStackPtr top; /*栈顶指针*/
        int count; /* 链栈元素个数*/
}LinkStack;

LinkStack* InitStack(); 
bool Push(LinkStack *S,SElemType e);
bool Pop(LinkStack *S,SElemType *e);
int Fbi(int i);
void Fbistore();

int main()
{
	Fbistore();
    

    return 0;
}

LinkStack* InitStack()
{
    LinkStack* s = (LinkStack*)malloc(sizeof(LinkStack));
    if(!s)
    {
        printf("内存分配失败!\n");
        return NULL;
    }
    memset(s, 0x00, sizeof(LinkStack));
    
    return s;
}
//进栈
bool Push(LinkStack *S,SElemType e)
{
        LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode)); 
        s->data=e; 
        s->next=S->top;	/* 把当前的栈顶元素赋值给新结点的直接后继,见图中① */
        S->top=s;         /* 将新的结点s赋值给栈顶指针,见图中② */
        S->count++;
        return OK;
}

//出栈
bool Pop(LinkStack *S,SElemType *e)
{ 
        LinkStackPtr p;
        if(S->count == NULL)
                return ERROR;
        *e=S->top->data;
        p=S->top;					/* 将栈顶结点赋值给p,见图中③ */
        S->top=S->top->next;    /* 使得栈顶指针下移一位,指向后一结点,见图中④ */
        free(p);                    /* 释放结点p */        
        S->count--;
        return OK;
}



int Fbi(int i)  /* 斐波那契的递归函数 */
{
	if( i < 2 )
		return i == 0 ? 0 : 1;  
       /* 这里Fbi就是函数自己,等于在调用自己 */
       return Fbi(i - 1) + Fbi(i - 2); 
} 




void Fbistore()
{
    //初始化一个空栈
    LinkStack* s = InitStack();
    int a = 0;
	int m = 0, i = 0;
	scanf("%d", &m);
    while(i <= m)
    {
        Push(s, Fbi(i));
		i++;
        
    }
    while(s->count != 0)
    {
        Pop(s, &a);
        printf("%d ", a);
    }
	printf("\n");
}

接下来将发布栈的几个具体应用(表达式求值迷宫问题)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值