题集-栈和队列的相互转化

题集-栈和队列的相互转化_第1张图片

 这里,队列的性质是先入先出,但是栈的性质是后入先出。两个队列就可以通过相互捯实现数据的后入先出。

typedef int QDataType;

//这是一个队列结点的结构

typedef struct QueueNode

{

    struct QueueNode* next;

    QDataType data;

}QNode;

//这是一个队列结构

typedef struct Queue

{

    QNode* phead;

    QNode* ptail;

    int size;

}Queue;

//这是通过两个队列搭建的栈结构

typedef struct {

    Queue q1;

    Queue q2;

} MyStack;

//栈的初始化

void QueueInit(Queue* pq)

{

    assert(pq);

    pq->phead = NULL;

    pq->ptail = NULL;

    pq->size = 0;

}

//队列判空

bool QueueEmpty(Queue* pq)

{

    assert(pq);

    return pq->size == 0 ;

}

//栈数据个数

int QueueSize(Queue* pq)

{

    assert(pq);

    return pq->size;

}

//入队

void QueuePush(Queue* pq, QDataType x)

{

    assert(pq);

    QNode* newnode = malloc(sizeof(QNode));

    if (newnode == NULL)

    {

        perror("malloc fail::");

        return;

    }

    newnode->data = x;

    newnode->next = NULL;

    if (pq->ptail == NULL)

    {

        assert(pq->phead == NULL);

        pq->phead = pq->ptail = newnode;

    }

    else

    {

        pq->ptail->next = newnode;

        pq->ptail = newnode;

    }

    pq->size++;

}

//出队列

void QueuePop(Queue* pq)

{

    assert(pq);

    //队列为空

    if(QueueEmpty(pq))

    {

        return NULL;

    }

    //当队列只有一个结点时,ptail会成为野指针,所以要分情况处理

    if (QueueSize(pq)==1)

    {

        free(pq->phead);

        pq->phead = pq->ptail = NULL;

        pq->size = 0;

    }

    else

    {

        QNode* cur = pq->phead;

        pq->phead = pq->phead->next;

        free(cur);

        cur = NULL;

        pq->size--;

    }

}

//获取队首元素

QDataType QueueFront(Queue* pq)

{

    assert(pq);

    if(pq->phead == NULL)

    {

        return NULL;

    }

    return pq->phead->data;

}

//队列的销毁

void QueueDestroy(Queue* pq)

{

    assert(pq);

    if(pq->size == 0) return;

    if(pq->size == 1)

    {

        QueuePop(pq);

    }

    else

    {

    QNode* cur = pq->phead;

    QNode* after = cur->next;

    while (cur)

    {

        free(cur);

        cur = after;

        if (cur)

        {

            after = after->next;

        }

    }

    pq->phead = pq->ptail = NULL;

    pq->size = 0;   

    }

}

//队尾底元素的获取

QDataType QueueBack(Queue* pq)

{

    assert(pq);

    if (QueueEmpty(pq))

    {

        return NULL;

    }

    return pq->ptail->data;

}

//创建栈

MyStack* myStackCreate() {

     MyStack *obj = (MyStack*)malloc(sizeof(MyStack));

     if(obj == NULL)

     {

         perror("malloc fail::");

         return;

     }

        QueueInit(&obj->q1);

        QueueInit(&obj->q2);

    return obj;

}

//压栈

void myStackPush(MyStack* obj, int x) {

      assert(obj);

      if (!QueueEmpty(&obj->q1))

    {

        QueuePush(&obj->q1,x);

    }

    else

    {

        QueuePush(&obj->q2,x);

    }

}

//出栈

int myStackPop(MyStack* obj) {

    assert(obj);

    Queue* pEmptyQ = &obj->q1;

    Queue* pNonEmptyQ = &obj->q2;

    if(!QueueEmpty(&obj->q1))

    {

        pEmptyQ = &obj->q2;

        pNonEmptyQ = &obj->q1;

    }

    while(QueueSize(pNonEmptyQ)>1)

    {

        QueuePush(pEmptyQ,QueueFront(pNonEmptyQ));

        QueuePop(pNonEmptyQ);

    }

    int ret = QueueFront(pNonEmptyQ);

    QueuePop(pNonEmptyQ);

    return ret;

}

//获取栈顶元素

int myStackTop(MyStack* obj) {

    assert(obj);

    if(!QueueEmpty(&obj->q1))

    {

        return QueueBack(&obj->q1);

    }

    else

    {

        return QueueBack(&obj->q2);

    }

}

//栈判空

bool myStackEmpty(MyStack* obj) {

     return (QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2));

}

//栈空间释放

void myStackFree(MyStack* obj) {

     QueueDestroy(&obj->q1);

     QueueDestroy(&obj->q2);

     free(obj);

     obj = NULL;

}

题集-栈和队列的相互转化_第2张图片

用栈实现队列就不能通过相互捯实现了,因为栈换到另一个栈中时,顺序就是相反的顺序,所以此时压栈顺序和出栈顺序就无法判断。

所以此时,我们将两个栈区分清楚,一个叫做“入”栈,专门用来进数据的,一个叫做“出”栈,专门用来出数据的。

 题集-栈和队列的相互转化_第3张图片

 此时要求出数据,若“出”栈内没有数据,则从“入”栈中捯过来,然后再出。若出栈中本来就有数据,则直接出栈即可。

要求入数据时,直接放在“入”栈中即可。

typedef int STDataType;

//栈的结点结构

typedef struct Stack

{

    STDataType* a;

    int top;

    int capacity;

}ST;

//初始化栈

void STInit(ST* pst)

{

    assert(pst);//如果指针为空,无法通过动态申请进行初始化,因为参数为一级指针。

    pst->a = NULL;

    pst->top = 0;

    pst->capacity = 0;

}

//栈判空

bool STEmpty(ST* pst)

{

    assert(pst);

    /*if (pst->top == 0)

        return true;

    else return false;

    */

    return pst->top == 0;

}

//销毁栈

void STDestroy(ST* pst)

{

    assert(pst);

    free(pst->a);

    pst->a = NULL;

    pst->capacity = 0;

    pst->top = 0;

}

//压栈

void STPush(ST* pst,STDataType a)

{

    if (pst->top == pst->capacity)

    {

        int newCapacity = pst->capacity == 0 ? 4 : 2 * pst->capacity;

        STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));

        if (tmp == NULL)

        {

            perror("realloc fail::");

            return;

        }

        pst->a = tmp;

        pst->capacity = newCapacity;

    } 

    pst->a[pst->top] = a;

    pst->top += 1;

}

//出栈

void STPop(ST* pst)

{

    assert(pst);

    assert(!STEmpty(pst));

    pst->top--;

}

//获取栈顶元素

STDataType STTop(ST* pst)

{

    assert(pst);

    assert(!STEmpty(pst));

    return pst->a[pst->top - 1];

}

//栈元素个数统计

int STSize(ST* pst)

{

    assert(pst);

    return pst->top;

}

//由两个栈构建的队列结构

typedef struct {

    ST pushst;

    ST popst;

} MyQueue;

//队列的创建

MyQueue* myQueueCreate() {

    MyQueue * obj = (MyQueue*)malloc(sizeof(MyQueue)); 

    if(obj == NULL)

    {

        perror("malloc fail::");

        return;

    }

    STInit(&obj->pushst);

    STInit(&obj->popst); 

    return obj;

}

//入队

void myQueuePush(MyQueue* obj, int x) {

     assert(obj);

     STPush(&obj->pushst,x);

}

//出队

int myQueuePop(MyQueue* obj) {

     assert(obj);

     int ret = 0;

     if(!STEmpty(&obj->popst))

     {

         ret = STTop(&obj->popst);

         STPop(&obj->popst);

     }

     else 

     {

         while(STSize(&obj->pushst))

         {

             STPush(&obj->popst,STTop(&obj->pushst));

             STPop(&obj->pushst);

         }

          ret = STTop(&obj->popst);

         STPop(&obj->popst);

     }

     return ret;

}

//获取队首元素

int myQueuePeek(MyQueue* obj) {

    assert(obj);

    if(!STEmpty(&obj->popst))

     {

         return STTop(&obj->popst);

     }

     else 

     {

         while(STSize(&obj->pushst))

         {

             STPush(&obj->popst,STTop(&obj->pushst));

             STPop(&obj->pushst);

         }

         return STTop(&obj->popst);

     }

}

//队列判空

bool myQueueEmpty(MyQueue* obj) {

    assert(obj);

    return (STEmpty(&obj->pushst)&&(STEmpty(&obj->popst)));

}

//释放队列空间

void myQueueFree(MyQueue* obj) {

     STDestroy(&obj->popst);

     STDestroy(&obj->pushst);

     free(obj);

     obj=NULL;

}

你可能感兴趣的:(数据结构,c++)