数据结构5-栈

栈和队列的基本操作是线性表操作的子集,它们是操作受限的线性表,因此,可称为限定性的数据结构。

栈(stack)

在这里插入图片描述
1.定义:限定只能在表的一端进行插入和删除操作运算的线性表(只能在栈顶操作)

2.逻辑结构:同线性表一样栈元素具有线性关系即前驱后继关系(一对一)

3.存储结构:顺序栈和链栈均可,顺序栈更常见

4.运算规则:只能在栈顶运算,且访问结点时依照后进后出的原则(LIFO)

5.实现方式:关键是编写入栈和出栈函数具体实现依顺序栈和链栈的不同而不同

栈和线性表唯一的区别在于运算规则。线性表插入删除位置任意而栈只能对表尾(栈顶)的元素进行插入和删除操作。(后进先出的原则)

  • 表尾an端为栈顶Top

  • 表头a1端栈底Base(Bottom)

  • 不含元素的空表称为空栈。

  • 插入元素到栈顶(表尾)的操作叫入栈(压栈)PUSH

  • 从栈顶(表尾)删除最后一个元素的操作称为出栈(弹栈)POP

栈的基本操作

  1. 栈SS的初始化操作。
    void InitStack(SS);
  2. 销毁栈SS。
    void DestroyStack(SS);
  3. 清空栈。
    void Clear(SS);
  4. 元素入栈,返回值:0-失败;1-成功。
    int Push(SS,ee);
  5. 元素出栈,返回值:0-失败;1-成功。
    int Pop(SS,ee);
  6. 判断栈是否为空,返回值:1-空,0-非空或失败。
    int IsEmpty(SS);
  7. 判断栈是已满,返回值:1-已满,0-未满或失败。
    int IsFull(SS);
  8. 求栈的长度,返回栈SS元素的个数。
    int Length(SS);
  9. 获取栈顶元素,返回值:0-失败;1-成功。
    int GetTop ( SS , ee ) ;

在这里插入图片描述

顺序栈

//SeqStac.h顺序栈
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>

using std::cin;


//函数结果状态代码 
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define MAXSIZE 20
//Status 是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef int ElemType;

typedef struct
{
	ElemType data[MAXSIZE];   // 用数组存储顺序栈中的元素。
	int top;                  // 栈顶指针,从0到MAXSIZE-1,-1表示空栈。
							  // 也可以从1到MAXSIZE,0表示空栈。
}SeqStack, *PSeqStack;

// 顺序栈SS的初始化操作。
Status InitStack(PSeqStack SS);

// 销毁顺序栈SS。
void DestroyStack(PSeqStack SS);

// 元素入栈,返回值:0-失败;1-成功。
int Push(PSeqStack SS, ElemType *ee);

// 元素出栈,返回值:0-失败;1-成功。
int Pop(PSeqStack SS, ElemType *ee);

// 求顺序栈的长度,返回值:栈SS中元素的个数。
int Length(PSeqStack SS);

// 清空顺序栈。
void Clear(PSeqStack SS);

// 判断顺序栈是否为空,返回值:1-空,0-非空或失败。
int IsEmpty(PSeqStack SS);

// 判断顺序栈是否已满,返回值:1-已满,0-未满或失败。
int IsFull(PSeqStack SS);

// 打印顺序栈中全部的元素。
void PrintStack(PSeqStack SS);

// 获取栈顶元素,返回值:0-失败;1-成功。
// 只查看栈顶元素的值,元素不出栈。
int GetTop(PSeqStack SS, ElemType *ee);
//SeqStac.cpp顺序栈
#include "SeqStack.h"

// 顺序栈SS的初始化操作。
Status InitStack(PSeqStack SS)
{	
	Clear(SS);
	return OK;
}

// 销毁顺序栈SS。
void DestroyStack(PSeqStack SS)
{
	// 静态顺序栈无需释放内存,不需要销毁操作。
	Clear(SS); // 清空顺序栈。
	return;

}

// 元素入栈,返回值:0-失败;1-成功。
int Push(PSeqStack SS, ElemType *ee)
{
	
	if ((SS == NULL) || (ee == NULL)) return ERROR;  // 检查空指针。
	if (IsFull(SS) == 1)
	{
		printf("顺序栈已满,不能插入。\n"); return 0;
	}
	SS->top++;  // 栈指针先加1。
	memcpy(&SS->data[SS->top], ee, sizeof(ElemType));  // 用数组的下标访问。												   // memcpy(SS->data+SS->top,ee,sizeof(ElemType));    // 采用指针运算也可以。
	return OK;
}

// 元素出栈,返回值:0-失败;1-成功。
int Pop(PSeqStack SS, ElemType *ee)
{
	if ((SS == NULL) || (ee == NULL)) return ERROR;  // 检查空指针。
	if (SS->top == -1) { printf("栈为空。\n"); return ERROR; }
	memcpy(ee,&SS->data[SS->top], sizeof(ElemType));
	SS->top--;
	return OK;
}

// 求顺序栈的长度,返回值:栈SS中元素的个数。
int Length(PSeqStack SS)
{
	if (SS == NULL) return 0; // 检查空指针。
	return SS->top + 1;
}

// 清空顺序栈。
void Clear(PSeqStack SS)
{
	if (SS == NULL) return; // 检查空指针。
	SS->top = -1;  // 栈顶指针置为-1。
	memset(SS->data, 0, sizeof(ElemType)*MAXSIZE);  // 数组元素清零。
}

// 判断顺序栈是否为空,返回值:1-空,0-非空或失败。
int IsEmpty(PSeqStack SS)
{
	if (SS == NULL) return 0;  // 检查空指针。
	if (SS->top == -1) return 1;

	return 0;
}

// 判断顺序栈是否已满,返回值:1-已满,0-未满或失败。
int IsFull(PSeqStack SS)
{
	if (SS == NULL) return ERROR; // 检查空指针。
	if (SS->top >= MAXSIZE)
	{
		return OK;
	}
	return 0;
}

// 打印顺序栈中全部的元素。
void PrintStack(PSeqStack SS)
{
	if (SS == NULL) return;  // 检查空指针。

	if (SS->top == -1) { printf("栈为空。\n"); return ; }

	int kk;
	for (kk = 0; kk <= SS->top; kk++)
	{
		printf("SS[%d],value=%d\n", kk, SS->data[kk]);    
		// 用数组的下标访问。
	 // printf("SS[%d],value=%d\n",kk,*(SS->data+kk));   // 采用指针运算也可以。
	}
}

// 获取栈顶元素,返回值:0-失败;1-成功。
// 只查看栈顶元素的值,元素不出栈。
int GetTop(PSeqStack SS, ElemType *ee)
{
	if (SS == NULL) return ERROR;  // 检查空指针。
	if (SS->top == -1) { printf("栈为空。\n"); return ERROR; }
	memcpy(ee, &SS->data[SS->top], sizeof(ElemType));  
	// 用数组的下标访问。
	// memcpy(ee,SS->data+SS->top,sizeof(ElemType));    // 采用指针运算也可以。

	return OK;
}

void test01()
{
	SeqStack SS;
	InitStack(&SS);
	printf("栈的长度是%d\n", Length(&SS));

	ElemType ee;     // 创建一个数据元素。

	printf("元素(1、2、3、4、5、6、7、8、9、10)入栈。\n");
	ee = 1;  Push(&SS, &ee);
	ee = 2;  Push(&SS, &ee);
	ee = 3;  Push(&SS, &ee);
	ee = 4;  Push(&SS, &ee);
	ee = 5;  Push(&SS, &ee);
	ee = 6;  Push(&SS, &ee);
	ee = 7;  Push(&SS, &ee);
	ee = 8;  Push(&SS, &ee);
	ee = 9;  Push(&SS, &ee);
	ee = 10; Push(&SS, &ee);

	printf("栈的长度是%d\n", Length(&SS));

	// 只查看栈顶元素的值,元素不出栈。
	if (GetTop(&SS, &ee) == 1)  printf("栈顶的元素值为%d\n", ee);

	PrintStack(&SS);

	if (Pop(&SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(&SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(&SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(&SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(&SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(&SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(&SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(&SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(&SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(&SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(&SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(&SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
}
int main()
{
	test01();
	system("pause");
	return EXIT_SUCCESS;
	
}

链栈

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//函数结果状态代码 
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1

//Status 是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef int ElemType;

typedef struct SNode
{
	ElemType data;       // 链栈中的元素。
	struct SNode *next;  // 指向下一个结点的指针。
}SNode, *LinkStack;

// 链栈SS的初始化操作,分配头结点,返回头结点的地址。
SNode *InitStack();

// 销毁链栈SS。
void DestroyStack(LinkStack SS);

// 元素入栈,返回值:0-失败;1-成功。
int Push(LinkStack SS, ElemType *ee);

// 元素出栈,返回值:0-失败;1-成功。
int Pop(LinkStack SS, ElemType *ee);

// 求链栈的长度,返回值:栈SS中元素的个数。
int  Length(LinkStack SS);

// 清空链栈。
void Clear(LinkStack SS);

// 判断链栈是否为空,返回值:1-空,0-非空或失败。
int  IsEmpty(LinkStack SS);

// 打印链栈中全部的元素。
void PrintStack(LinkStack SS);

// 获取栈顶元素,返回值:0-失败;1-成功。
// 只查看栈顶元素的值,元素不出栈。
int GetTop(LinkStack SS, ElemType *ee);
#include "LinkStack.h"
// 链栈SS的初始化操作,分配头结点,返回头结点的地址。
SNode *InitStack()
{
	SNode * SS = new SNode;
	if (SS == NULL) return NULL;  // 内存不足,返回失败。
	SS->next = NULL;  // 头结点的下一结点暂时不存在,置空。
	return SS;
}

// 销毁链栈SS。
void DestroyStack(LinkStack SS)
{
	if (SS == NULL) return ;
	Clear(SS);
	if (SS)
	{
		delete SS;
	}
}

// 元素入栈,返回值:0-失败;1-成功。
int Push(LinkStack SS, ElemType *ee)
{
	if ((SS == NULL) || (ee == NULL)) return 0;  // 检查空指针。
	// 内存不足,返回失败。								
	// 考虑数据元素为结构体的情况,这里采用了memcpy的方法而不是直接赋值
	SNode * p = new SNode;
	memcpy(&p->data, ee, sizeof(ElemType));

	p->next = SS->next;
	SS->next = p;
	return OK;
}

// 元素出栈,返回值:0-失败;1-成功。
int Pop(LinkStack SS, ElemType *ee)
{
	if ((SS->next == NULL) || (ee == NULL)) return 0;  // 检查空指针。
	SNode * p = SS->next;
	memcpy( ee,&p->data, sizeof(ElemType));

	SS->next = p->next;
	delete p;
	return OK;
}

// 求链栈的长度,返回值:栈SS中元素的个数。
int  Length(LinkStack SS)
{
	if ((SS->next == NULL) ) return 0;  // 检查空指针。
	int i = 0;
	SNode * p = SS->next;
	while (p)
	{
		i++;
		p = p->next;
	}
	return i;
}

// 清空链栈。
void Clear(LinkStack SS)
{
	if (SS == NULL) return;
	SNode * p = SS->next;
	SNode * q;
	while (p)
	{
		q = p->next;
		delete p;
		p = q;
	}
	SS->next = NULL;
}

// 判断链栈是否为空,返回值:1-空,0-非空或失败。
int  IsEmpty(LinkStack SS)
{
	if (SS == NULL)
	{
		return -1;
	}
	if (SS->next)
	{
		return 0;
	}
	return 1;
}

// 打印链栈中全部的元素。
void PrintStack(LinkStack SS)
{
	if (SS == NULL) return;
	if (SS->next == NULL) { printf("栈为空。\n"); return; }

	int kk = 0;
	SNode *pp = SS->next;  // 从第1个结点开始。

	while (pp != NULL)
	{
		printf("SS[%d],value=%d\n", kk++, pp->data);
		pp = pp->next;
	}
}

// 获取栈顶元素,返回值:0-失败;1-成功。
// 只查看栈顶元素的值,元素不出栈。
int GetTop(LinkStack SS, ElemType *ee)
{
	if (SS == NULL) return ERROR;
	if (SS->next == NULL) { printf("栈为空。\n"); return ERROR; }
	memcpy(ee, &SS->next->data, sizeof(ElemType));
	return OK;
}



void test01()
{
	LinkStack SS;     // 创建链栈。

	SS = InitStack();  // 初始化链栈。

	printf("栈的长度是%d\n", Length(SS));

	ElemType ee;     // 创建一个数据元素。

	printf("元素(1、2、3、4、5、6、7、8、9、10)入栈。\n");
	ee = 1;  Push(SS, &ee);
	ee = 2;  Push(SS, &ee);
	ee = 3;  Push(SS, &ee);
	ee = 4;  Push(SS, &ee);
	ee = 5;  Push(SS, &ee);
	ee = 6;  Push(SS, &ee);
	ee = 7;  Push(SS, &ee);
	ee = 8;  Push(SS, &ee);
	ee = 9;  Push(SS, &ee);
	ee = 10; Push(SS, &ee);

	printf("栈的长度是%d\n", Length(SS));

	if (GetTop(SS, &ee) == 1)  printf("栈顶的元素值为%d\n", ee);

	PrintStack(SS);

	if (Pop(SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);
	if (Pop(SS, &ee) == 1)  printf("出栈的元素值为%d\n", ee);

	// 销毁链栈SS。
	DestroyStack(SS); SS = 0;  // 销毁链栈后把SS置为空,防止野指针。
}
int main()
{
	test01();
	system("pause");
	return EXIT_SUCCESS;
	
}```

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值