C语言中的栈

1. 栈的定义:

限定仅在表尾进行插入或删除的线性表(后进先出LIFO:Last in , First out)。表头端称为栈底,表尾端称为栈顶。不含元素的空表称为空栈。

    

 2. 栈的建立以及初始化

栈类似于线性表,有两种存储表示方法:顺序栈和链栈。

顺序栈 : 利用一组地址连续的存储单元依次存放字栈底到栈顶的元素,同时附设指针top指示栈顶元素在顺序栈中的位置,top=0为空栈。(栈所需大小难以估计,通常先分派一个基本容量,不够时再追加)

顺序栈的定义:建立一个结构体,包含栈底,栈顶,当前分配的内存空间

typedef struct 
{
    SDataType *top;  //栈顶
    SDataType *base; //栈底 
    int StackSize;   //当前已分配的内存空间,以元素为单位
}SqStrack; //此结构体的小名是strack

 栈的初始化:

使用 == malloc()==函数,base是栈底指针,始终指向栈底(s.top=s.base为栈空)。top为栈顶指针,top初值指向栈底,每当插入一个元素时top+1,弹出一个元素时top-1,所以,非空栈中的栈底指针始终在栈顶元素的下一个位置。

 顺序栈初始化,构造一个空栈

Status InitStack(SqStrack &S)
{
   S.base=(SdataType *)malloc(STACK_INI_SIZE*sizeof(SDataType));//给栈分配内存空间
   if(!S.base)
   {
      return OVERFLOW; //如果分配失败,则返回error
   }
   S.top=S.base; //起初S.base指向S.top的位置,为空栈,之后有元素入栈,top向后移,base永远不变
   S.StrackSize=STACK_INIT_SIZE;// 表示栈的内存大小
   return OK;

}
   

3. 判断是否为空栈

当弹出栈顶元素时,需要判断一下栈是否为空防止下溢。(s.top=s.base为栈空标志)

void JudgeNull(SqStack &s)
{
   if(s.top==s.base)
     printf("此栈为空");
   
   else
     printf("此栈不为空");
}

4. 判断是否为满栈

元素入栈前要判断栈是否满栈,防止上溢。StackSize表示当前已经分配的内存空间,可以用s.top-s.base来算当前使用的栈空间,即当s.top-s.base=s.StrackSize时表示满栈。(s.top永远不指向值,s.top指向存储最后一个值的下一个,比如给栈申请了100个空间,s.top指向101,所以栈里存放了100个值)

void JudgeFull(SqStrack &S)
{
   if(s.top-s.base==s.StrackSize)
     printf("栈满!");
   else 
     printf("栈未满");
}
     

5. 栈的遍历 

void StackPrint(strack *p)
{
	while(p->top!=p->base)    //栈不为空
	{
		printf("%c",p->data[p->top-1]); //输出每一个数据
		p->top--;  //栈顶-1,直到栈为空
	}
	
}

6. 入栈

入栈前判断是否满栈,如果满栈,我们要追加存储空间,元素才能入栈

Status Push(SqStrack &s,SdataType e)
{
   SDataType *p;
   if(s.top-s.base==s.StackSize)
   { 
      p=(SDataType *)realloc(s.base,(STRACK_INIT_SIZE+STRACKINCREMENT)*sizeof(SDataType));
      if(!p)
      {
        return OVERFLOW;
      }
      s.base=p;
      s.top=s.base+s.StackSize;
      s.StackSize+=STACKINCREMENT;
    }
    *(s.top)=e;
    s.top++;
    return OK;
}

7. 出栈

出栈时判断栈是否为空栈,若栈已经为空,则返回error。

Status Pop(SqStack &s,SDataType &e)
{
	if(s.top!=s.base)
	{
		s.top--;
		e=*(s.top);
	}
	else return 0;
	return e;
}

8. 实现栈:

#include<stdio.h>
#include<malloc.h>

#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OK 1
#define OVERFLOW -2
typedef int SDataType;
typedef int Status;

typedef struct
{
	SDataType* base; //栈底
	SDataType* top;  //栈顶
	int StackSize;   //当前已分配的内存空间
}SqStack;

Status InitStack(SqStack &S)
{
	S.base = (SDataType*)malloc(STACK_INIT_SIZE * sizeof(SDataType));
	if (!S.base)
	{
		return OVERFLOW;
	}
	S.top = S.base;
	S.StackSize = STACK_INIT_SIZE;
	return OK;

}

Status Push(SqStack &s, SDataType e)
{
	SDataType* p;
	if (s.top - s.base == s.StackSize)
	{
		p = (SDataType*)realloc(s.base, (STACKINCREMENT + STACK_INIT_SIZE) * sizeof(SDataType));
		if (!p)
		{
			return OVERFLOW;
		}
		s.base = p;
		s.top = s.base + s.StackSize;
		s.StackSzie += STACKINCREMENT;
	}
	*(s.top) = e;
	s.top++;
	return OK;
}

Status Pop(SqStack &s, SDataType &e)
{
	if (s.top != s.base)
	{
		s.top--;
		e = *(s.top);
	}
	else
	{
		return 0;
	}
	return e;
}

void judgeNull(SqStack& s)
{
	if (s.top == s.base)
		printf("此栈为空栈");
	else printf("此栈不为空栈");

}

void judgeFull(SqStack& s)
{
	if (s.top - s.base == s.StackSize)
		printf("栈满");
	else printf("栈未满");

}

int main()
{
	SqStack s;
	SDataType element;

	InitStack(s);
	for (int i = 1; i <= 10; i++)
	{
		Push(s, i);
	}
	judegeNull(s);
	judgeFull(s);

	printf("出栈:");
	while (s.top != s.base)
	{
		Pop(s, element);
		printf("%d ", element);
	}
	printf("\n");
	judgeNull(s);

	return 0;
}

还有一种更易理解的方式

#include<stdio.h>
#include<malloc.h>
#include<string.h> //计算所输入数据的长度

//定义栈 
typedef struct 
{
	char data[100];
	int top;
	int base;
}stack; //给结构体起的小名 

//建立栈 
stack *StackCreate()
{
	stack *p=(stack*)malloc(sizeof(stack)); //分配空间 
	if(p==NULL)
	{
		printf("建立失败!");
		return 0;
	}
	else p->base=p->top=0; //分配成功 
	return p; 
} 

//入栈
void StackInput(stack *p,char str)
{
	p->data[p->top]=str; //数据进栈 
	p->top++; //栈顶向上走 
 } 
 
//出栈
char StackOutput(stack *p,char str)
{
	if(p->top!=p->base)  //栈非空 
	{
		str=p->data[p->top]; //栈顶的数据先出栈 
		p->top--;  //栈顶-1 
		return str;  //返回所出栈的元素 
	}
 } 

//输出
void StackPrint(stack *p)
{
	while(p->top!=p->base) 
	{
		printf("%c",p->data[p->top-1]); //栈顶不存放数据,p->top-1存放栈的最后一个数据 
		p->top--;
	}
} 

//主函数 
int main()
{
	stack *p;
	char a[10]="abcde";
	p=StackCreate(); //调用建立栈的函数 
	for(int i=0;i<strlen(a);i++)
	{
		StackInput(p,a[i]); //元素入栈 
	}
	printf("输出栈中的所有字符:");
	StackPrint(p); //调用输出栈的函数 
	
	return 0;
}

 

  • 7
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值