栈和队列(思想+伪代码+部分代码)

来源:互联网 发布:清风dj软件下载 编辑:程序博客网 时间:2024/05/02 03:08
ADT 栈(stack)
Data
同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系。
operation
InitStack(*s):初始化操作,建立一个空栈S。
DestroyStack(*s):若栈存在,则销毁它。
ClearStack(*s):将栈清空。
StackEmpty(s):若栈为空,返回ture,否则,返回flash
GetTop(s,*e):若栈不空,用e返回s的栈顶元素
Push(*s,e):插入e到栈s中并成为栈顶元素
Pop(*s,e):删除栈顶元素,并用e返回其值
StackLength(s):返回栈s的元素个数

endADT


ADT   队列( queue)

队列(只允许在一端进行插入操作,另一端进行删除操作的线性表,先进先出)

允许插入的一端是队尾,允许删除的一端是队头
ADT 队列(queue)
data
    同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系
operation
    InitQueue(*Q):初始化操作,创建一个空队列Q
    DeatroyQueue(*Q):若队列Q存在,则销毁它
    ClearQueue(*Q):将队列清空
    QueueEmpty(Q):若队列为空,则返回ture,否则,返回false
    GetHead(Q,*e):若队列存在且非空,用e返回队列Q的队头元素
    EnQueue(*Q,e):若队列存在,插入新元素e到队列Q中并成为队尾元素
    DeQueue(*Q,*e):删除队列Q中队头元素,并用e返回其值
    QueueLength(Q):返回队列Q的元素个数
endADT





*栈的结构定义

typedef int SElemType;//类型定义根据实际情况而定,这里假设为inttypedef struct{    SElemType data[MAXSIZE];    int top;//用于栈顶指针}sqStack;


栈的存储结构

/*插入元素e为新的栈顶元素(push)*/Status Push(SqStack *s,SElemType e){    if(s->top==MAXSIZE-1)//栈满    {        return ERROR;    }    s->top++;//栈顶指针加1    s->data[s->top]=e;//将新插入元素赋值给栈顶空间    return OK;}


出栈pop

/*若栈不空,则删除s的栈顶元素,并用e返回其值,并返回OK,否则返回ERROR;*/

status Pop(SqStack *s,SElemType *e){    if(s->top==-1)        return ERROR;//将要删除的栈顶元素赋值给e    *e=s->data[s->top];//栈顶指针减1    s->top--;    return OK;}


/*两栈共享空间结构*/
typedef struct{    SElemType data[MAXSIZE];    int top1;//栈1栈顶指针    int top2;//栈2栈顶指针}SqDoubleStack;


/*插入元素e为新的栈顶元素*/

Status push(SqDoubleStack *s,SElemType e,int stackNumber){    if(s->top1+1==s->top2)//栈已满,不能再push新元素        return ERROR;    if(stackNumber==1)   //栈1有元素进栈        s->data[++s->top1]=e;//若栈1则先top+1后给数组元素赋值    else if(stackNumber==2) //栈2有元素进栈        s->data[--s->top2]==e;//若栈2则先top-1后给数组元素赋值    return OK;}

/*若栈不空,则删除s的栈顶元素,用e返回其值,并返回OK,否则返回ERROR;*/

Status Pop(SqDoubleStack *s,SElemType *e,int stackNumber){    if(stackNumber==1)    {        if(s->top1==-1)            return ERROR;//说明栈1是空栈,溢出        *e->data[s->top1--];//将栈1的栈顶元素出栈    }    else if(stackNumber==2)    {        if(s->top2==MAXSIZE)            return ERROR;//说明栈2是空栈,溢出        *e=s->data[s->top2++];//将栈2的栈顶元素出栈    }    return OK;}

栈的链式存储结构


typedef struct StackNode{    SElemtype data;    struct StackNode *next;}StackNode,*LinkStack;typedef struct LinkStack{    LinkStack top;    int count;}LinkStack;

/*插入元素e为新的栈顶元素*/

status Push(LinkStack *s,SElemType e){    LinkStack s=(LinkStackPtr)malloc(sizeof(StackNode));    s->data=e;    s->next=s->top;//把当前的栈顶元素赋值给结点的直接后继    s->top=e;//将新的结点s赋值给栈顶指针    s->count++;    return OK;}


/*若栈不空,则删除s的栈顶元素,并用e返回其值,并返回OK,否则返回ERROR;*/

status Pop(LinkStack *s,SElemType *e){    LinkStack p;    if(StackEmpty(*s));    return ERROR;    *e=s->top->data;    p=s->top; //将栈顶结点赋值给p,    s->top=s->top->next;//使得栈顶指针下移一位,指向后一结点    free(p);//释放结点    s->count--;    return OK;}


栈的应用--递归


1,斐波那契数列

2,后缀(逆波兰)表示法定义//不懂啊




循环队列
详细请参考大话数据结构P112-P116


typedef int QElemtype;//QElemtype类型根据实际情况,这里定义为inttypedef struct{    QElemtype data[MAXZIZE];    int front;//头指针    int rear;//尾指针,若队列不空,指向队尾元素的下一个位置}Squeue;

//初始化一个空队列

ststus InitQueue(SqQueue *Q){    Q->front=0;    Q->rear=0;    return OK;}


//循环队列求长度

int QueueLength(SqQueue Q){    return (Q.rear-Q.front+MAXSIZE)%MAXSIZE;}

//循环队列的入队操作

statuas EnQueue(SqQueue *Q,QElemTYpe e){    if((Q->rear+1)%MAXSIZE==Q->front)//队列未满        return ERROR;    Q->data[Q->rear]=e;//将元素e赋值给队尾    Q->rear=(Q->rear+1)%MAXSIZE;//指针向后移动一位    return OK;}

队列的链式存储结构与实现

typedef int QElemTypetypedef struct QNode//结点结构{    QElemType data;    struct QNode *next;}QNode,*QueuePtr;typedef struct//队列的链表结构{    QueuePtr front,rear;//队头,队尾指针}LinkQueue;

//插入元素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;}

队列的链式存储结构-出队


//若队列不空,删除Q的队头元素,并用e返回其值,并返回OK,否则,返回ERROR


ststus 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;}


0 0