栈的原理以及实现(基于数组)

栈的定义:

限制仅在表的一端进行插入和删除运算的线性表。

可以实现“先进后出(或者叫后进先出)”的存储结构。

栈顶(Top): 允许操作的一端。

栈底(Bottom): 不允许操作的一端。

特点:后进先出。

举例:物流装车,先装车的后出来,后装车的先出来。

图片加载中

栈的结构:

空栈:栈顶和栈顶都指向一个无用的头结点


存有结点的栈:栈顶指针指向栈顶结点,栈底指针指向头结点


栈的三种实现方案:静态数组、动态分配的数组、动态分配的链式结构。

静态数组:长度固定,在编译时确定。优点:结构简单,实现方便。缺点:不够灵活、适用于知道明确长度的场合。

动态数组:长度可在运行的时才确定,并且可以更改原来数组的长度。优点:灵活。缺点:会因此增加程序的复杂性。

链式结构:无长度上限。需要的时候再申请分配内存空间。优点:最灵活。缺点:链式结构的链接字段需要消耗一定内存;在链式结构中访问特定元素效率不如数组。

栈的三种实现

首先确定一个栈接口的头文件,里面包含了各个实现方案下的函数原型,放在一起是为了实现程序的模块化以及便于修改。然后再分别介绍各个方案的具体实现方法。


静态数组实现栈:

/* 
**  
** 静态数组实现堆栈程序,数组长度由#define确定 
*/  
  
#include <stack.h>
#include <stdio.h>
#include <assert.h>

#define STACK_SIZE 100 /*栈最大容纳元素数量*/

typedef struct Stack{
	SElemType data[STACK_SIZE];  /*栈中的数组*/
	int top; /*指向栈顶元素的指针*/
}SeqStack;

/*init stack*/
void InitStack(SeqStack *S)
{
	S->top = 0;
}
/*判断栈是否为空*/
int StackEmpty(SeqStack *S)
{
	if(S->top == 0)
		return 1;
	else
		return 0;
}
/*取栈顶元素*/
int GetTop(SeqStack S, SElemType *e)
{
	if(S->top <= 0){
		printf("当前栈已空\n");
		return 0;
	}
	*e = S.stack[S.top - 1];
	return 1;
}
/*将元素e入栈*/
int push(SeqStack *S, SElemType e)
{
	if(S->top >= StackSize){
		printf("栈满\n");
		return 0;	
	}
	S->stack[S->top] = e;
	S->top ++;
	return 1;
}
/*将栈顶元素出栈,并赋值给e*/
int PopStack(SeqStack *S, SElemType *e)
{
	if(S->top == 0){
		printf("空栈");	
		return 0;
	}
	S->top --; 
	*e = S->stack[S->top];
	return 1;
}
/*栈的长度*/
int StackLength(SeqStack S){
     return S.top;//存储着数据的部分是0到top-1,入栈时,如果栈未满,则在top处存入数据,然后top++
}
/*清空栈*/ 
void ClearStack(SeqStack *S){
     S->top = 0;                    
}
/*判断栈是否为空*/
int isEmpty(SeqStack *S)
{
	return S->top == 0;
}

/*判断栈是否满*/  
int isFull(SeqStack *S)  
{  
    return S->top == StackSize;  
}  
   

动态分配的数组实现栈:并用栈解决禁止转换问题:(十进制转二进制或八进制)

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

#define STACK_INIT_SIZE 10 //定义最初申请的内存大小
#define STACK_INCREMENT 2  //每一次申请内存不足的时候扩展的内存大小

#define OVERFLOW 0
#define FALSE 0
#define TRUE 1
#define ERROR 0
#define INFEAIBLE 0 //不可实行的
#define OK 1

typedef int SElemType;
typedef int Status;

int Length;

/*****************结构类型部分******************/
typedef struct Stack
{
	SElemType *base;
	SElemType *top;
	int stacksize;
}SqStack;  //sequence stack顺序栈

/*****************构造一个空栈**********************/
Status InitStack(SqStack &S)
{
	if( !( S.base = (SElemType *)malloc( STACK_INIT_SIZE * sizeof(SElemType) ) ) )
		exit(OVERFLOW);  //存储分配失败
	
	S.top = S.base;
	S.stacksize = STACK_INIT_SIZE;  //初始栈容量
	
	return OK;
}

/******************压入栈元素*********************/
Status Push(SqStack &S, SElemType e)//这里不是SElemType &e
{
	//栈满追加内存
	if(S.top - S.base >= S.stacksize){
		S.base = (SElemType *) realloc(S.base, sizeof(SElemType) * (S.stacksize + STACK_INCREMENT));
		if(!S.base)
			exit(OVERFLOW);
		//给SqStack的三个对象赋值
		S.top = S.base + S.stacksize;
		S.stacksize += STACK_INCREMENT; 
	}
	*S.top++ = e;//先把e压入栈顶,S.top再增加1指向栈顶元素e的下一个位置
	return OK;
}
/******************输出栈元素*********************/
void PrintList(SqStack S)
{
	S.top = S.base;
	for( int i = 0; i< Length; i++){
		printf("%d\n",*(S.top) ++);
	}
}
/******************判断栈是否为空*****************/
Status StackEmpty(SqStack S)
{
	if(S.base == S.top) return true;
	else return false;
}
/******************删除栈顶元素*******************/
Status Pop(SqStack &S, SElemType &e)
{
	//判断是否为空
	if( S.base == S.top ) return ERROR;
	
	e = *--S.top;
	return OK;
}

/********************进制转换********************/
int conversion(unsigned int n,unsigned int m)//十进制数转化成m进制
{
	SqStack s;
	InitStack(s);
	int e = 0;

	unsigned result = 0;
	while(n)
	{
		Push(s, (SElemType)n%m);
		n /= m;
	}
	while( !StackEmpty(s))
	{
		Pop(s,e);
		result = result*10 + e;
	}
	return result;
} 

int main()
{
	int n = 123;
	int m = 2;
	int result = conversion(n,m);
	printf("%d\n", result);
	return 0;
}






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值