数据结构4--栈

1.特点:栈先进后出,栈是受操作限制的顺序表

2.栈的实现有两种方式:顺序表(结构更优,因为在尾部插数据代价更小)、链表

3.顺序栈

(1)有两种top指针的用法:top指针从0开始,先放入数据,再top++;从-1开始,先top++,再放入数据。

(2)出栈的时候,只用将top--就行,其值会被下一个插入的值覆盖

(3)取栈顶元素的时候不能--top元素

(4)栈的入栈,相当于顺序表的尾插;栈的出栈相当于顺序表的尾删。

//Common.h
#ifndef _COMMON_H_
#define _COMMON_H_

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <assert.h>
#include <vld.h>

typedef int  ElemType;

#endif
//stack.h
#ifndef _QUEUE_H_
#define _QUEUE_H_

#include "Common.h"

#define STACK_DEFAULT_SIZE 8

//顺序栈
typedef struct SeqStack{
	ElemType* base;//栈空间
	size_t capacity;
	int top;//栈顶指针
}SeqStack;

//声明
void SeqStackInit(SeqStack *pst, int sz = STACK_DEFAULT_SIZE);
void SeqStackPush(SeqStack *pst, ElemType x);
void SeqStackPop(SeqStack *pst);
ElemType SeqStackTop(SeqStack *pst); //取栈顶元素
void SeqStackTop(SeqStack *pst, ElemType *top_val);
void SeqStackShow(SeqStack *pst);
void SeqStackDestroy(SeqStack *pst);
int  SeqStackSize(SeqStack *pst);
///
bool SeqStackIsFull(SeqStack* pst)
{
	assert(pst != NULL);
	return pst->top >= pst->capacity;
}
bool SeqStackIsEmpty(SeqStack* pst)
{
	assert(pst != NULL);
	return pst->top == 0;
}
void SeqStackInit(SeqStack *pst, int sz = STACK_DEFAULT_SIZE)
{
	assert(pst != NULL);
	pst->capacity = sz > STACK_DEFAULT_SIZE ? sz : STACK_DEFAULT_SIZE;//注意!!!
	pst->base = (ElemType*)malloc(sizeof(ElemType)*pst->capacity);
	pst->top = 0;
}
//栈是先进后出 也就是顺序表的尾插
void SeqStackPush(SeqStack *pst, ElemType x)
{
	assert(pst != NULL);
	//考虑特殊情况
	if (SeqStackIsFull(pst))
	{
		printf("栈已满,%d不能进行插入!\n",x);
		return;
	}
	pst->base[pst->top] = x;
	pst->top++;
}
//栈的删除 也就是顺序表的尾删
void SeqStackPop(SeqStack *pst)
{
	assert(pst != NULL);
	//直接--top就可以了
	if (SeqStackIsEmpty(pst))
	{
		printf("栈为空,不能进行删除!\n");
		return;
	}
	pst->top--;
}
//取栈顶元素 不能像销毁一样直接对top--
ElemType SeqStackTop(SeqStack *pst)
{
	//检查顺序栈结构存在
	assert(pst != NULL);
	//不能这样写 是因为如果栈顶元素为0,就会无法判断到底是栈不存在还是栈顶元素是0
	考虑顺序栈不存在的情况
	//if (SeqStackIsEmpty(pst))
	//{
	//	printf("栈空间不存在,不能取栈顶元素\n");
	//	return;
	//}
	assert(!SeqStackIsEmpty(pst));
	return pst->base[pst->top - 1];
}
//考虑入参 出参的情况
void SeqStackTop(SeqStack *pst, ElemType *top_val)//pst入参 top_val 出参
{
	assert(pst != NULL);
	if (SeqStackIsEmpty(pst))
	{
		printf("栈已空, 不能取栈顶元素.\n");
		return;
	}
	*top_val = pst->base[pst->top-1];
}
void SeqStackShow(SeqStack *pst)
{
	assert(pst != NULL);
	//从上往下打印
	size_t i =pst->top-1;
	for (; i >0; --i)
	{
		printf("| %d |\n", pst->base[i]);
	}
	printf("----\n");
}
void SeqStackDestroy(SeqStack *pst)
{
	assert(pst != NULL);
	free(pst->base);//注意!!!
	pst->capacity = pst->top = 0;
	pst->base = NULL;

}
int  SeqStackSize(SeqStack *pst)
{
	assert(pst != NULL);
	return pst->top ;//因为top是从0开始的,所以不需要-1
}

#endif _QUEUE_H_

4.链栈

栈的入栈,相当于链表的头插;栈的出栈,相当于链表的头删。

//链栈
typedef struct LinkStackNode{

	ElemType data;
	struct LinkStackNode* link;
}LinkStackNode;

typedef LinkStackNode* LinkStack;
//声明
void LinkStackInit(LinkStack *pst);
void LinkStackPush(LinkStack *pst, ElemType x);
void LinkStackPop(LinkStack *pst);
ElemType LinkStackTop(LinkStack *pst);
void LinkStackShow(LinkStack *pst);
int LinkStackSize(LinkStack *pst);
void LinkStackDestroy(LinkStack *pst);

//
//实现
void LinkStackInit(LinkStack *pst)
{
	assert(pst != NULL);
	*pst = NULL;
}
//链表的头插
void LinkStackPush(LinkStack *pst, ElemType x)
{
	assert(pst != NULL);
	LinkStackNode* head = *pst;
	//先申请节点
	LinkStackNode* s = (LinkStackNode*)malloc(sizeof(LinkStackNode));
	assert(s != NULL);//说明申请节点成功
	s->data = x;

	s->link = head;
	head = s;
}
//链表的头删 
void LinkStackPop(LinkStack *pst)
{
	assert(pst != NULL);
	if (*pst != NULL)
	{
		LinkStackNode* p = *pst;
		*pst = p->link;
		free(p);
	}
}
ElemType LinkStackTop(LinkStack *pst)
{
	assert(pst != NULL&&*pst!=NULL);
	return (*pst)->data;
}
void LinkStackShow(LinkStack *pst)
{
	assert(pst != NULL);
	LinkStackNode* p = *pst;
	while (p != NULL)
	{
		printf("| %d |\n", p->data);
		p = p->link;
	}
	printf("--\n");
}
int LinkStackSize(LinkStack *pst)
{
	assert(pst != NULL);
	LinkStackNode* head = *pst;
	int size = 0;
	while (head != NULL)
	{
		size++;
		head = head->link;
	}
	return size;
}
void LinkStackDestroy(LinkStack *pst)
{
	assert(pst != NULL);
	LinkStackNode*  p = *pst;
	//有节点存在时
	while (p != NULL)
	{
		*pst = p->link;
		free(p);
		p = *pst;
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_43807876/article/details/115474155