数据结构 栈、队列

· 栈

1、栈的顺序存储结构

栈的一些操作

struct SqStack
{
	int data[MaxSize];
	int top;	//栈顶指针
};

/*进栈操作*/
Status Push(SqStack* S,int e)
{
	if(S->top==MaxSize-1)//栈满
	{
		return Error;
	}
	S->top++;		//栈顶指针增加1
	S->data[S->top]=e;//新元素赋给栈顶空间
	return Ok
}
/*出栈操作*/
Status Pop(SqStack *S,int *e)
{
	if(S->top==-1)//栈为空
		return Error;
	*e=S->data[S->top];//要删除的元素赋给*e
	S->top--;		//栈顶元素减1
	return OK
}

两栈共享空间(一个数组存储两个栈)【一定用在相同类型的栈,否则将会复杂化】

两栈 栈顶 顶对顶存储于同一个数组内,两栈如果同时增加元素就是向中间汇聚,只要两个栈顶不见面,就可以一直使用。

top1+1=top2为栈满

struct SqDoubleStack;
{
	int data[MaxSize];
	int top1;	//栈1顶指针
	int top2;	//栈2顶指针
};
/*共享栈入栈*/
Status Push(SqDoubleStack *S,int e,int StackNo)
{
	if(S->top1+1==S->top2)//栈满
		return error;
	if(StackNo==1)//栈1有元素进栈
		S->data[++S->top1]=e;//进栈数值赋给top1+1
	else if(stackNo==2)
		S->data[--S->top2]=e;//进栈数值赋给top2-1
	return ok;
}
/*出栈*/
Status Pop(SqDoubleStack *S,int *e,itn stackNo)
{
	if(stackNo==1)
	{
		if(S->top1==-1)
			return error;
		else
			*e=S->data[S->top1--]//同普通栈的出栈一样
	}
	else if(stackNo==2)
	{
		if(S->top2==MaxSize)
			return error;
		else
			*e=S->data[S->top1++]
	}
	return OK;
}

2、栈的链式存储结构(链栈)

以链表头作为栈顶,利用链表指针作为top指针,不需要头结点。

链栈不需要考虑栈满问题,因为整个链栈可以占用所有空内存。

链栈空,即是链表指针指向栈尾,top==null 的时候。

typedef int elmtp;
typedef struct StackNode
{
	elmtp data;
	struct StackNode *next;
}StackNode,*LinkStackPtr;

typedef struct LinkStack
{
	LinkStackPtr top;
	int count;
}LinkStack;

/*链栈进栈*/
Status Push(LinkStack *S,elmtp e,)
{
	LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode));
	s->data=e;
	s->next=S->top;//把原来的top指针变为next指针
	S->top=s;	//新节点s赋给顶指针
	S->count++;
	return OK;
}
/*链栈出栈*/
Status Pop(LinkStack *S,elmtp *e)
{
	LinkStackPtr p;
	if(StackEmpty(*S))
		return error;
	*e=S->top->data;
	p=S->top;
	S->top=S->top->next;
	free(p);
	S->count--;
	return OK;
}

栈的应用:好多,比如算数表达式的计算。。。

Link:http://blog.csdn.net/zesicus/article/details/37901627(C++栈)


· 队列

秉着尾进头出的原则。

1、队列顺序存储结构:

typedef int qelmtp;	//qelmtp根据实际情况定
/*循环对列顺序存储结构*/
struct SqQueue
{
	qelmtp data[MaxSize];
	int front;	//头指针
	int rear;	//尾指针
};
/*初始化一个空对列*/
Status InitQueue(SqQueue *Q)
{
	Q->front=0;
	Q->rear=0;
	return ok;
}
/*返回Q的元素个数,也就是队列当前长度*/
int QueueLength(SqQueue Q)
{//这句话和Q.rear-Q.front有什么不同?
	return(Q.rear-Q.front+MaxSize)%MaxSize;
}
/*若队列未满,则插入元素e为Q新的队尾元素*/
Status EnQueue(SqQueue *Q,qelmtp e)
{
	if((Q->rear+1)%MaxSize==Q->front)//你(Q->rear+1)==Q->front不行???
		return error;//判断是否队列满
	Q->data[Q->rear]=e;//元素插入队尾
	Q->rear=(Q->rear+1)%MaxSize;//蛋疼
	return ok;
}
/*出队,删除Q队头元素,e返回其值*/
Status DeQueue(SqQueue *Q,qelmtp *e)
{
	if(Q->front==Q->rear)
		return error;//判断队列是否为空
	*e=Q->data[Q->front];//队头元素赋给e
	Q->front=(Q->front+1)%MaxSize;
	return OK;
}

2、链式队列

/*链式队列结构*/
typedef int qelmtp;
typedef struct QNode	//节点结构
{
	qelmtp data;
	struct QNode *next;
}QNode,*QueuePtr;
/*队列链表结构*/
typedef struct	
{
	QueuePtr front,rear;//队头,队尾指针
}LinkQueue;
/*插入e为Q的新队尾元素*/
Status EnQueue(LinkQueue *Q,qelmtp e)
{
	QueuePtr s=(QueuePtr)malloc(sizeof(QNode));
	if(!s)	//存储分配失败
		exit(overflow);
	s->data=e;	//e元素给新节点数据域
	s->next=NULL;//新节点的指针域指向空,即是尾指针
	Q->rear->next=s;//原来的尾指针的next指向新加入的节点
	Q->rear=s;	//原来的尾指针移位变为新的尾指针
	return ok;
}
/*出队操作*/
Status DeQueue(LinkQueue *Q,qelmtp *e)
{
	QueuePtr p;
	if(Q->front==Q->rear)	//判断是否空对列
		return error;
	p=Q->front->next;	//欲删除的对头next指针暂存p
	*e=p->data;		//欲删除对头节点值给e
	Q->front->next=p->next;//更新对头next指针
	if(Q->rear==P)//若对头是队尾,删除后rear指向头结点
		Q->rear=Q->front;
	free(p);
	return OK;
}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值