1.链式栈:
栈的链式存储结构, 简称链栈。
/*链栈的结构代码*/
typedef struct stackNode{
SElemType data;
struct stackNode *next;
} stackNode ,*LinkStackPtr;
typedef struct LinkStack{
LinkStackPtr top;
int count;
}LinkStack;
(1)进栈操作:
/* 插入元素e为新的栈顶元素 */
Status Push(LinkStack *S,SElemType e){
LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode));
s->data=e;
s->next=S->top; /* 把当前的栈顶元素赋值给新结点的直接后继,见图中① */
S->top=s; /* 将新的结点s赋值给栈顶指针,见图中② */
S->count++;
return OK;
}
(2)出栈操作:Status Pop(LinkStack *S,SElemType *e)
{
LinkStackPtr p;
if(StackEmpty(*S))
return ERROR;
*e=S->top->data;
p=S->top; /* 将栈顶结点赋值给p,见图中③ */
S->top=S->top->next; /* 使得栈顶指针下移一位,指向后一结点,见图中④ */
free(p); /* 释放结点p */
S->count--;
return OK;
}
如果栈的使用过程中元素变化不可预料,有时很小,有时非常大,那么最好是用链栈,反之,如果它的变化在可控范
围内,建议使用顺序栈会更好一些。
2.链式队:
队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,我们简称为链队列。
typedef int QElemType; /*QElemType类型根据实际情况而定,int*/typedef struct QNode /*结点结构*/
{
QElemType data;
struct QNode *next;
} QNode ,*QueuePtr;
typedef struct /*队列的链表结构*/{
QueuePtr front,rear; /*队头队尾指针*/
} LinkQueue;
(1)入队操作:
入队操作时,其实就是在链式尾部插入结点。
/*插入元素e为Q的新的队尾元素*/
Status EnQueue(LinkQueue *Q, QElemType e){
QueuePtr s = (QueuePtr)malloc(sizeof(QNode));
if(!s)
exit(OVERFLOW); /*存储分配失败*/
s->data = e;
s->next = NULL;
Q->rear->next =s; /*把拥有元素e新节点s赋值给原队尾结点的后继*/
Q->rear = s; /*把当前的s设置为队尾结点,rear指向s*/return OK;
}
(2)出队操作:
出队操作时,就是头结点的后继结点出队,将头结点的后继改为它后面的结点,若链表除头结点外只剩一个元素时,
则需将rear指向头结点。
/* 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */
Status DeQueue(LinkQueue *Q,QElemType *e)
{
QueuePtr p;
if(Q->front==Q->rear)
return ERROR;
p=Q->front->next; /* 将欲删除的队头结点暂存给p */
*e=p->data; /* 将欲删除的队头结点的值赋值给e */
Q->front->next=p->next; /* 将原队头结点的后继p->next赋值给头结点后继 */
if(Q->rear==p) /* 若队头就是队尾,则删除后将rear指向头结点*/
Q->rear=Q->front;
free(p);
return OK;
}