· 栈
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;
}