数据结构与算法1 堆栈的实现

一、什么是堆栈

首先,我们要理解堆栈的含义。
堆栈是一个特定的存储区或寄存器,它的一端是固定的,另一端是浮动的 。对这个存储区存入的数据,是一种特殊的数据结构。所有的数据存入或取出,只能在浮动的一端(称栈顶)进行,严格按照“先进后出”的原则存取,位于其中间的元素,必须在其栈上部(后进栈者)诸元素逐个移出后才能取出。

二、堆栈结构体的基本形态

typedef struct Stack{
	T* m_vect;   //存储元素内存空间 
	size_t size; //堆栈总容量
	size_t index;//堆栈中已经存储元素的个数
}Stack;

以上是堆栈结构体的基本组成部分。

三、实现堆栈需要包含的头文件

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

四、堆栈的主要相关函数

//初始化堆栈   申请动态内存
void init(Stack *stack,size_t size);
//把data这个元素放到堆栈中去
void push(Stack *stack,T data);
//从堆栈中取到一个元素  该元素是最后放到堆栈中那个元素
T pop(Stack *stack);
//查看堆栈顶的元素  并不拿走
T peek(Stack *stack);
//堆栈是否为空
bool isEmpty(Stack *stack);
//堆栈中存储元素的个数
size_t getCnt(Stack *stack);
//堆栈中容量的大小
size_t getSize(Stack *stack);
//堆栈是否已经满了
bool isFull(Stack *stack);
//清空堆栈
void clear(Stack *stack);
//销毁堆栈
void destroy(Stack *stack);
//遍历一下堆栈中的元素
void travel(Stack *stack);

五、相关函数的实现

//为了便于今后开发过程中对于数据类型的修改,此处将T代表int类型
typedef int T;

//初始化堆栈   申请动态内存
void init(Stack *stack,size_t size){
	stack->m_vect = calloc(size,sizeof(T));
	stack->size = size;
	stack->index = 0;
}

//把data这个元素放到堆栈中去
void push(Stack *stack,T data){
	stack->m_vect[stack->index] = data;
	stack->index++;
}

//从堆栈中取到一个元素  该元素是最后放到堆栈中那个元素
T pop(Stack *stack){
	return stack->m_vect[--stack->index];	
}

//查看堆栈顶的元素  并不拿走
T peek(Stack *stack){
	return stack->m_vect[stack->index-1];	
}

//堆栈是否为空
bool isEmpty(Stack *stack){
	return stack->index == 0;	
}

//堆栈中存储元素的个数
size_t getCnt(Stack *stack){
	return stack->index;	
}

//堆栈中容量的大小
size_t getSize(Stack *stack){
	return stack->size;	
}

//堆栈是否已经满了
bool isFull(Stack *stack){
	return stack->size == stack->index;	
}

//销毁堆栈
void destroy(Stack *stack){
	if(stack->m_vect != NULL){
		free(stack->m_vect);
		stack->m_vect = NULL;
	}
}
//清空堆栈中的元素
void clear(Stack *stack){
	while(!isEmpty(stack)){
		pop(stack);	
	}
}
//遍历一下堆栈中的元素
void travel(Stack *stack){
	for(int i=0;i<stack->index;i++){
		printf("%d ",stack->m_vect[i]);	
	}	
	printf("\n");
}

六、堆栈进阶功能

判断brr是否是arr作为入栈的出栈顺序

bool isOutOfStack(T arr[],T brr[],size_t len){
	Stack s;
	init(&s,len);
	int j = 0;//记录brr[]数组下标位置
	for(int i=0;i<len;i++){
		push(&s,arr[i]);//把入栈元素依次入栈
		while(!isEmpty(&s) && peek(&s)==brr[j]){//一旦栈顶元素等于出栈元素 
			pop(&s);//出栈
			j++;    //下一个出栈元素
		}
	}
	bool flag = isEmpty(&s);//栈里面元素全部都出列了 
	destroy(&s);
	return flag;
}

七、堆栈的使用示例

int main(){
	Stack s;
	init(&s,10);
	
	push(&s,5);
	push(&s,3);
	push(&s,2);

	int x = pop(&s);
	printf("%d\n",x);
	x = pop(&s);
	printf("%d\n",x);

	push(&s,10);
	x = pop(&s);
	printf("%d\n",x);

	destroy(&s);


	int arr[5] = {1,2,3,4,5};
	int brr[5] = {5,4,3,1,2};
	if(isOutOfStack(arr,brr,5)){
		printf("是\n");	
	}else{
		printf("否\n");	
	}
	return 0;	
}

八、注意事项

大家要注意,堆栈的大小是有限的,是在建立堆栈的时候确定下来的。
堆栈的本质是按照先进后出的方式,在一个固定大小的空间中存储和读取数据,而不是像链表这样不断地去申请更大的内存空间来存放数据,这两者有本质的不同。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值