【整理】堆栈的特征与实现

1. 基本特征
      具有后进先出特征的数据结构叫做 堆栈   LIFO(last in first out)
      × 堆栈是只能在一端进行增删元素的数据结构,该位置称为栈顶,一般用下标top表示
 
2 基本操作
       创建(create)、销毁(destroy)、入栈(push)、出栈(pop)、遍历(travel)、判断栈是否为满(full)、
            判断栈是否为空(empty)、计算栈中元素的个数(size)、 查看栈顶元素值(peek)


下面基于物理存储结构的两种形式实现堆栈功能

  基于顺序存储结构的堆栈实现
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

// 定义堆栈的数据类型
typedef struct
{
	int *arr;	//存储空间的首地址
	int len;	//存储空间的大小 
	int top;	//下标,记录栈顶的位置
} Stack;

//实现堆栈创建的功能
Stack *creat(int len);
//实现堆栈销毁的功能
void destroy(Stack *ps);
//判断栈是否为满
bool full(Stack *ps);
//判断栈是否为空
bool empty(Stack *ps);
//实现入栈的操作
void push(Stack *ps, int data);
//遍历栈中所有元素的操作
void travel(Stack *ps);
//实现出栈的基本操作
int pop(Stack *ps);
//实现计算栈中元素个数
int size(Stack *ps);
//实现查看栈顶元素值
int peek(Stack *ps);

int main(void)
{
	//创建堆栈变量
	Stack *ps = creat(5);
	printf("%s\n", full(ps)? "栈满了": "栈没有满");
	printf("%s\n", empty(ps)? "栈空了": "栈没有空");

	printf("---------------------------\n");
	int i = 0;
	for (i =1; i <7; i++)
	{
		push(ps, i*10+i);
	}
	travel(ps); // 11 22 33 44 55
	printf("----------------------------\n");
	printf("出栈的元素值是:%d\n", pop(ps)); // 55
	travel(ps);		// 11 22 33 44 
	printf("出栈的元素是:%d\n", pop(ps));	 // 44
	travel(ps);		// 11 22 33
	printf("栈顶元素是:%d\n", peek(ps));	 // 33
	travel(ps);		// 11 22 33
	printf("栈中元素的个数是:%d\n", size(ps));//3

	//销毁堆栈变量
	destroy(ps);

	return 0;
}

//实现出栈的基本操作
int pop(Stack *ps)
{
	if (empty(ps))
	{
		printf("栈已经空,出栈失败\n");
		return -1;  //表示出错
	}

	return ps->arr[--(ps->top)];
}

//计算栈中元素个数
int size(Stack *ps)
{
	return ps->top;
}

//查看栈顶元素值
int peek(Stack *ps)
{
	if (empty(ps))
	{
		printf("栈空了,查看栈顶元素失败\n");
		return -1; //表示失败
	}
	return ps->arr[ps->top - 1];
}

//遍历栈中所有元素的操作
void travel(Stack *ps)
{
	int i = 0;
	printf("栈中的元素有:\n");
	for (i =0; i <ps->top; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	printf("\n");
}

//实现入栈的操作
void push(Stack *ps, int data)
{
	if (full(ps))
	{
		printf("栈满了,入栈失败\n");
		return;
	}
	//ps->arr[ps->top] = data;
	//ps->top++;
	ps->arr[ps->top++] = data;
}

//判断是否为满
bool full(Stack *ps)
{
	return ps->len == ps->top;
}

//判断栈是否为空
bool empty(Stack *ps)
{
	return 0 == ps->top;
}

//实现堆栈销毁的功能
void destroy(Stack *ps)
{
	free(ps->arr);
	free(ps);
	ps->arr = NULL;
	ps = NULL;
}

//实现堆栈创建的功能
Stack *creat(int len)
{
	//1.创建堆栈,进行初始化
	// Stack stack;	局部变量,生命周期短暂
	// 动态申请的内存生命周期比较长
	Stack *ps = (Stack *)malloc(sizeof(Stack));
	ps->arr = (int *)malloc(sizeof(int) * len);
	ps->len = len;
	ps->top = 0;
	//2.返回堆栈的首地址
	return ps;
}

基于链式存储结构的堆栈实现
#include <stdio.h>
#include <stdlib.h>

//定义节点的数据类型
typedef struct Node
{
	int data;		//数据内容
	struct Node *next;	//记录下一个节点地址
} Node;

//定义栈的数据类型
typedef struct
{
	Node *head; //头指针
} Stack;

//判断栈是否为空
int empty(Stack *ps);
//判断栈是否为满
int full(Stack *ps);
//实现入栈操作
void push(Stack *ps, int data);
//实现遍历操作
void travel(Stack *ps);
//查看栈顶元素
int peek(Stack *ps);
//计算栈中元素的个数
int size(Stack *ps);
//实现出栈操作
int pop(Stack *ps);
//清空栈中所有元素
void clear(Stack *ps);


int main(void)
{
	//定义栈并且进行初始化
	Stack stack;
	stack.head = NULL;

	push(&stack, 11); // 11
	travel(&stack);
	push(&stack, 22); // 22 11
	travel(&stack);
	push(&stack, 33); // 33 22 11
	travel(&stack);
	printf("%s\n", empty(&stack)?"栈空了":"栈没有空");
	printf("%s\n", full(&stack)?"栈满了":"栈没有满");
	printf("获取到的栈顶元素是:%d\n", peek(&stack));// 33
	printf("栈中元素的个数是:%d\n", size(&stack));  // 3
	printf("--------------------------\n");
	travel(&stack); //33 22 11
	printf("出栈的元素是:%d\n", pop(&stack));//33
	travel(&stack);	//22 11
	//清空栈中所有元素
	clear(&stack);
	travel(&stack); //什么也没有
	return 0;
}

//清空栈中所有元素
void clear(Stack *ps)
{
	while (ps->head != NULL)
	{
		//使用临时指针记录第一个节点
		Node *p = ps->head;
		//头指针指向下一个节点
		ps->head = ps->head->next;
		//释放p指向的节点
		free(p);
		p = NULL;

	}
}

//实现出栈操作
int pop(Stack *ps)
{
	if (empty(ps))
	{
		return -1; //出栈失败
	}
	//准备一个指针记录要删除的节点地址
	Node *p = ps->head;
	//头指针指向下一个节点
	ps->head = ps->head->next;
	//单独存储要删除的节点元素值
	int tmp = p->data;
	//释放要删除的节点内存
	free(p);
	p = NULL;
	//返回已经释放的节点元素值
	return tmp;
}

//查看栈顶元素
int peek(Stack *ps)
{
	if (empty(ps))
	{
		return -1; // 获取失败
	}
	return ps->head->data;
}
//计算栈中元素的个数
int size(Stack *ps)
{
	int cnt = 0;
	Node *p = ps->head;
	while(p != NULL)
	{
		cnt++;
		p = p->next;
	}
	return cnt;
}

//实现遍历操作
void travel(Stack *ps)
{
	//给头指针寻找替身
	Node *p = ps->head;
	printf("栈中的元素有:");
	while (p != NULL)
	{
		printf("%d ", p->data);
		//指向下一个节点
		p = p->next;
	}
	printf("\n");
}

//判断栈是否为空
int empty(Stack *ps)
{
	return NULL == ps->head; 
}

//判断栈是否为满
int full(Stack *ps)
{
	return 0;	//链式可以无限连接,没有满
}

//实现入栈操作
void push(Stack *ps, int data)
{
	//1.创建新节点并初始化
	//Node node; 局部变量 生命周期短
	Node *pn = (Node *)malloc(sizeof(Node));
	pn->data = data;
	pn->next = NULL;
	//2.插入新节点到头节点的位置
	pn->next = ps->head;	//新节点连接原头节点
	ps->head = pn;		//新节点成为头节点
}









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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值