数据结构(一)线性结构(3)栈

顺序表、链表是线性表的两种表示方法,指定的线性表的组织方式,对于不同的读写顺序的线性表,也有不同的定义,例如:

元素按照先入后出的顺序读写的线性表称为栈

元素按照先入先出的顺序读写的线性表称为队列

按照上面的定义,可以组合出四种数据结构:顺序栈、链栈、顺序队列、链队列

对于顺序栈,空间是事先分配好的,一般都会偏大,为了更好地利用顺序栈空间,可以将一个大栈拆分为两个小栈,大栈的两端分为别两个小栈的头部,数据元素从两端向中间插入

 

本节介绍单向顺序栈和链栈的基本操作实现

栈的构成为:数据域、栈顶指针(对于顺序栈,栈顶指针就是一个整形变量)

顺序栈定义:
typedef struct STACK {
    int aidata[ARRAY_SIZE];
    int iTop;
}T_Stack, *PT_Stack;

链栈定义:

typedef struct STACK {
    int iData;
    struct STACK *ptNext;
}T_Stack, *PT_Stack;

 

对链栈,同前所述,分有无头节点两种情况,这里以常用的有头节点版本为例

栈的主要操作有:

1、创建空栈:PT_Stack createStack(void);

对顺序栈,创建栈就是预先分配一块数据空间和一个栈顶变量,并初始化变量为-1(数据从0位置开始存储)

对链栈,创建栈只需要创建一个头节点(标志性作用)
2、判空/判满:int isEmpty(PT_Stack ptHead); / int isFull(PT_Stack ptStack)

对顺序栈,判空条件为栈顶指针等于-1,判满条件为栈顶指针等于栈大小-1

对链栈,判空条件是头指针的指针域为空,判满条件为内存空间不足
3、入栈:int pushToStack(int iEle, PT_Stack *pptHead);

对顺序栈,入栈时先判满,不满则将栈顶指针加1,写入数据即可

对链栈,入栈时先创建新节点,创建成功则新节点作为第一个数据节点插入链表
4、出栈:int popFromStack(PT_Stack *pptHead);

对于顺序栈,出栈时先判空,不空则先读出数据,然后栈顶指针减1即可

对链栈,出栈时先判空,不空则读出头部数据节点的数据域,并将该节点删除

 

入栈、出栈操作也可以在链尾进行,但这样需要增加查找链表操作,增加工作量

 

顺序栈代码:

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

#define MENU_EXIT	0
#define MENU_PUSH	1
#define MENU_POP	2
#define MENU_PRINT	3

#define ERR			-100

typedef struct STACK {
	int aidata[ARRAY_SIZE];
	int iTop;
}T_Stack, *PT_Stack;


int isEmpty(PT_Stack ptStack)
{
	return ptStack->iTop == -1 ? 1 : 0 ;
}

int isFull(PT_Stack ptStack)
{
	return ptStack->iTop == ARRAY_SIZE - 1 ? 1 : 0 ;
}

int pushToStack(int iEle, PT_Stack ptStack)
{
	if (isFull(ptStack))
		return ERR;

	ptStack->iTop++;
	ptStack->aidata[ptStack->iTop] = iEle;
	printf("Push %d to index %d\r\n", iEle, ptStack->iTop);

	return iEle;
}

int popFromStack(PT_Stack ptStack)
{
	int iEle;

	if (isEmpty(ptStack))
		return ERR;

	iEle = ptStack->aidata[ptStack->iTop];
	printf("Pop %d from index %d\r\n", iEle, ptStack->iTop);
	ptStack->iTop--;

	return iEle;
}

PT_Stack createStack(void)
{
	PT_Stack ptStack = NULL;
	int i, iNum, iEle;

	printf("Enter the num of data\r\n");
	scanf_s("%d", &iNum);
	if (iNum > ARRAY_SIZE || iNum < 0)
	{
		printf("Err in the num of data\r\n");
		goto done;
	}

	ptStack = (PT_Stack)malloc(sizeof T_Stack);
	ptStack->iTop = -1;
	if (!ptStack)	
		goto done;

	printf("Enter your data: ");
	for (i = 0; i < iNum; i++)
	{
		scanf_s("%d", &iEle);
		pushToStack(iEle, ptStack);
	}
done:
	return ptStack;
}

void printStack(PT_Stack ptStack)
{
	int i;
	if (isEmpty(ptStack))
	{
		printf("Stack is empty\r\n");
		return;
	}

	printf("\r\n");
	for (i = 0; i <= ptStack->iTop; i++)
		printf("%d ", ptStack->aidata[i]);
	printf("\r\n\r\n");
}


int menu(PT_Stack ptStack)
{
	int iNum, iEle;

	printf("0 to exit\r\n"
		"1 to push\r\n"
		"2 to pop\r\n"
		"3 to print\r\n");

	scanf_s("%d", &iNum);
	switch (iNum)
	{
		case MENU_EXIT:
			return -1;
		case MENU_PUSH:
			printf("Enter the one to be push\r\n");
			scanf_s("%d", &iEle);
			pushToStack(iEle, ptStack);
			break;
		case MENU_POP:
			popFromStack(ptStack);
			break;
		case MENU_PRINT:
			printStack(ptStack);
			break;
	}

	return 0;
}

int main(void)
{
	PT_Stack ptStack;

	ptStack = createStack();
	if (!ptStack)
		return -1;

	while (1)
	{
		if (menu(ptStack) == -1)
			break;
	}

	return 0;
}

 

链栈代码:

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

#define MENU_EXIT	0
#define MENU_PUSH	1
#define MENU_POP	2
#define MENU_PRINT	3

#define ERR			-100


typedef struct STACK {
	int iData;
	struct STACK *ptNext;
}T_Stack, *PT_Stack;



int isEmpty(PT_Stack ptHead)
{
	return ptHead->ptNext == NULL ? 1 : 0;
}

int pushToStack(int iEle, PT_Stack *pptHead)
{
	PT_Stack ptNew = NULL, ptTmp = NULL;
	
	ptNew = (PT_Stack)malloc(sizeof T_Stack);

	if (!ptNew)
	{
		printf("Err in no memory\r\n");
		return ERR;
	}
	ptNew->iData = iEle;

	ptTmp = (*pptHead)->ptNext;
	if (!ptTmp)
		ptNew->ptNext = NULL;
	else
		ptNew->ptNext = ptTmp;

	(*pptHead)->ptNext = ptNew;

	return iEle;
}

int popFromStack(PT_Stack *pptHead)
{
	PT_Stack ptTmp;
	int iEle;

	if (isEmpty(*pptHead))
		return ERR;

	ptTmp = (*pptHead)->ptNext;
	iEle = ptTmp->iData;
	(*pptHead)->ptNext = ptTmp->ptNext;
	free(ptTmp);
	//printf("Pop %d\r\n", iEle);

	return iEle;
}

PT_Stack createStack(void)
{
	PT_Stack ptHead = NULL;
	int iNum, i, iEle;

	ptHead = (PT_Stack)malloc(sizeof T_Stack);
	if (!ptHead)
	{
		printf("Err in malloc head\r\n");
		goto done;
	}
	ptHead->ptNext = NULL;


	printf("Enter the num of data: ");
	scanf_s("%d", &iNum);

	printf("Enter your data: ");
	for (i = 0; i < iNum; i++)
	{
		scanf_s("%d", &iEle);
		pushToStack(iEle, &ptHead);
	}
	printf("Create a stack with %d nodes\r\n", i);

done:
	return ptHead;
}

void printStack(PT_Stack ptHead)
{
	PT_Stack ptTmp = ptHead;

	if (isEmpty(ptHead))
	{
		printf("Stack is empty\r\n");
		return;
	}

	printf("\r\n\r\n");
	printf("Stack data according to inverted order: ");
	while (!isEmpty(ptTmp))
	{
		ptTmp = ptTmp->ptNext;
		printf("%d ", ptTmp->iData);
	}
	printf("\r\n\r\n");
}


int menu(PT_Stack *pptHead)
{
	int iNum, iEle;

	printf("0 to exit\r\n"
		"1 to push\r\n"
		"2 to pop\r\n"
		"3 to print\r\n");

	scanf_s("%d", &iNum);
	switch (iNum)
	{
	case MENU_EXIT:
		return -1;
	case MENU_PUSH:
		printf("Enter the one to be push\r\n");
		scanf_s("%d", &iEle);
		pushToStack(iEle, pptHead);
		break;
	case MENU_POP:
		popFromStack(pptHead);
		break;
	case MENU_PRINT:
		printStack(*pptHead);
		break;
	}

	return 0;
}

int main(void)
{
	PT_Stack ptHead;

	ptHead = createStack();
	if (!ptHead)
		return -1;

	while (1)
	{
		if (menu(&ptHead) == -1)
			break;
	}

	return 0;
}

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值