用链表实现堆栈--链式栈

/*
  一、关于链式栈的约定,(目的是在C语言中描述方便)
  1.定义:
  (1)堆栈是一种先进后出的线性表;
  (2)它只允许在表的一端(栈顶)进行入栈和出栈运算,另一端为栈底,入栈和出栈时不需
       要改变栈底指针;
  (3)运算受限的非循环单链表,它没有头结点,尾结点即栈底,栈底不存放有效数据,
       只是指针域为NULL,链表中的插入删除操作在这里只能在栈顶进行。
  (4)栈顶指针指向有效数据,并且可移动;栈底指针指向的结点不存有效数据,指针域
       指向空NULL,永不移动。
  2.创建链式栈时:
  (1)需定义两个结构,一个用于描述结点(此结构跟链表结点对应的结构类似),另一个
       用于描述是哪个栈(此结构包括栈顶和栈底指针);
  (2)初创时,栈顶和栈底指针相等,都指向同一个结点,此结点不存放有效数据,指针域
       指向NULL。入栈后,栈底指针不动。

  3.入栈,出栈,编历,判断是否为空(链式栈不存在满问题),清空栈等操作。

*/

#include "LinkedStack.h"


//构建框架,即空栈
void linkedStackCreat(struct LinkedStack *pS)
{
	pS->pTop =(struct LinkedStackNode *)malloc(sizeof(struct LinkedStackNode));
	if( NULL == pS->pTop )
	{
		printf("initStack():malloc failed!\n");
		exit(-1);
	}
	
	pS->pBottom = pS->pTop;
	pS->pTop->pNext = NULL;//pS->pBottom->pNext = NULL;
	/*
	   1. 即pS指向的对象的pTop成员,pTop成员指向的那个结点的指针域应该是空
	   2. 栈顶和栈底都共同指向一个结点,这个结点的指针域为NULL,即最后的结点pS->pBottom
	      以后就永远指向这个结点,不会移动,并且这个结点不存放有效数据,只是指针域为NULL
	*/
	
	return;
}

/*
  1. 栈不存在满的问题,理论上大小可以是整个虚拟内存空间,所以没有返回值
  2. 参数的含义:pS表示往哪个栈中压,val表示压入的值是多少
  3. 压栈只能从最顶端压入
*/
void linkedStackPush(struct LinkedStack * pS,int val)
{
	struct LinkedStackNode * pNew = NULL;
	pNew =(struct LinkedStackNode *)malloc(sizeof(struct LinkedStackNode));
	if( NULL == pNew )
	{
		printf("linkedStackPush():malloc failed!\n");
		exit(-1);
	}
	
	pNew->data = val;
	pNew->pNext = pS->pTop;//pS->Top不能改成pS->pBottom
	pS->pTop = pNew;
	
	return;
}

//遍历栈,并返回栈的深度
void traverseLinkedStack(struct LinkedStack * pS,int *LinkedStackDepth)
{
	int i=0;
	struct LinkedStackNode * p = pS->pTop;
	
	while( p != pS->pBottom )
	{
		i++;
		printf("data-%d is %d\n",i,p->data);
		p = p->pNext;
	}
	
	*LinkedStackDepth = i;
	
	return;
}

int linkedStackIsEmpty(struct LinkedStack * pS)
{
	if( pS->pTop == pS->pBottom)
		return 1;
	else
		return 0;
}

//把pS所指向的栈出栈一次,并把出栈的元素存入pVal形参所指向的变量中,如果出栈失败,返回false,否则返回true
int linkedStackPop(struct LinkedStack * pS,int *pVal)
{
	struct LinkedStackNode *p=NULL;
	
	if( 1 == linkedStackIsEmpty(pS) )
	{
		printf("linkedStackPop():This stack is empty!\n");
		return 0;
	}
	
	p = pS->pTop;
	
	*pVal = p->data;
	pS->pTop = p->pNext;
/*
  1,释放p指向的malloc所申请的那块内存(标记为可用),并不改变P指针
    的值,即p的指向。
  2,由于指针所指向的内存已经被释放,所以其它代码有机会改写其中的
    内容,相当于该指针从此指向了自己无法控制的地方,也称为野指针;
  3,为了避免失误,最好在free之后,将指针指向NULL。
*/
	free(p);
	p = NULL;
	
	return 1;
}

//清空栈,使其变为空栈,框架还在
int clearLinkedStack(struct LinkedStack * pS)
{
	if( 1 == linkedStackIsEmpty(pS) )
	{
		printf("clearLinkedStack():This stack is empty!\n");
		return 0;
	}
	
	struct LinkedStackNode* p=pS->pTop;
	struct LinkedStackNode* q=NULL;
	
	while( p != pS->pBottom )
	{
		q = p->pNext;
		free(p);
		p = q;
	}
	pS->pTop = pS->pBottom;	
	
	
	return 1;
}


相关头文件:


#ifndef LINKEDSTACK_H
#define LINKEDSTACK_H

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


struct LinkedStackNode 
{
	int data;
	struct LinkedStackNode *pNext;
};

struct LinkedStack
{
	struct LinkedStackNode * pTop;
	struct LinkedStackNode * pBottom;
};

void linkedStackCreat(struct LinkedStack *pS);
void linkedStackPush(struct LinkedStack * pS,int val);
void traverseLinkedStack(struct LinkedStack * pS,int *LinkedStackDepth);
int linkedStackIsEmpty(struct LinkedStack * pS);
int linkedStackPop(struct LinkedStack * pS,int *pVal);
int clearLinkedStack(struct LinkedStack * pS);


#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值