转载请注明出处:http://blog.csdn.net/ns_code/article/details/25076689
题目:用两个队列模拟一个栈,即用两个队列的出队和入队操作。来实现栈的出栈和入栈操作。
思路:略微画下草图。便不难想出该题的解决方法。思路例如以下:
如果有两个队列Q1和Q2,当二者都为空时,入栈操作能够用入队操作来模拟。能够随便选一个空队列,如果选Q1进行入栈操作。如今如果a,b,c依次入栈了(即依次进入队列Q1)。这时如果想模拟出栈操作,则须要将c出栈,由于在栈顶。这时候能够考虑用空队列Q2。将a,b依次从Q1中出队,而后进入队列Q2,将Q1的最后一个元素c出队就可以,此时Q1变为了空队列,Q2中有两个元素。队头元素为a,队尾元素为b,接下来如果再运行入栈操作,则须要将元素进入到Q1和Q2中的非空队列,即进入Q2队列,出栈的话,就跟前面的一样,将Q2除最后一个元素外所有出队,并依次进入队列Q1,再将Q2的最后一个元素出队就可以。
实现代码例如以下:
/* 用两个队列模拟入栈操作 */ void push(PQUEUE pS1,PQUEUE pS2,int val) { if(is_empty(pS2)) en_queue(pS1, val); else en_queue(pS2, val); } /* 用两个队列模拟出栈操作 */ bool pop(PQUEUE pS1,PQUEUE pS2,int *pData) { if(is_empty(pS1) && is_empty(pS2)) return false; int DelData; if(!is_empty(pS2)) { int len = length(pS2); while(len-- > 1) { de_queue(pS2,&DelData); en_queue(pS1,DelData); } //将队列的最后一个元素出队。作为出栈元素 de_queue(pS2,pData); return true; } if(!is_empty(pS1)) { int len = length(pS1); while(len-- > 1) { de_queue(pS1,&DelData); en_queue(pS2,DelData); } //将队列的最后一个元素出队,作为出栈元素 de_queue(pS1,pData); return true; } }
完整的代码(用的曾经写的链式队列)例如以下:
/******************************************************************* 题目:用两个队列模拟一个栈 *******************************************************************/ #include<stdio.h> #include<stdlib.h> typedef struct Node { int data; struct Node *pNext; }NODE,*PNODE; typedef struct Queue { PNODE front; //队头指针 PNODE rear; //队尾指针 }QUEUE,*PQUEUE; PQUEUE create_queue(); bool is_empty(PQUEUE); void en_queue(PQUEUE, int); bool de_queue(PQUEUE,int *); void destroy_queue(PQUEUE); void traverse_queue(PQUEUE); int length(PQUEUE); void push(PQUEUE,PQUEUE,int); bool pop(PQUEUE,PQUEUE,int *); int main() { int pData; //用来保存出队的元素值 //创建队列并进行入队測试 PQUEUE pS1 = create_queue(); PQUEUE pS2 = create_queue(); push(pS1,pS2,4); push(pS1,pS2,5); printf("the length of pS1: %d\n",length(pS1)); printf("the length of pS2: %d\n",length(pS2)); if(pop(pS1,pS2,&pData)) printf("%d is pop out\n",pData); else printf("Stack is empty,can not pop\n"); printf("the length of pS1: %d\n",length(pS1)); printf("the length of pS2: %d\n",length(pS2)); push(pS1,pS2,6); printf("the length of pS1: %d\n",length(pS1)); printf("the length of pS2: %d\n",length(pS2)); push(pS1,pS2,7); printf("the length of pS1: %d\n",length(pS1)); printf("the length of pS2: %d\n",length(pS2)); if(pop(pS1,pS2,&pData)) printf("%d is pop out\n",pData); else printf("Stack is empty,can not pop\n"); printf("the length of pS1: %d\n",length(pS1)); printf("the length of pS2: %d\n",length(pS2)); if(pop(pS1,pS2,&pData)) printf("%d is pop out\n",pData); else printf("Stack is empty,can not pop\n"); printf("the length of pS1: %d\n",length(pS1)); printf("the length of pS2: %d\n",length(pS2)); if(pop(pS1,pS2,&pData)) printf("%d is pop out\n",pData); else printf("Stack is empty,can not pop\n"); printf("the length of pS1: %d\n",length(pS1)); printf("the length of pS2: %d\n",length(pS2)); if(pop(pS1,pS2,&pData)) printf("%d is pop out\n",pData); else printf("Stack is empty,can not pop\n"); return 0; } /* 创建一个空队列,队头指针和队尾指针都指向头结点, 头结点中不存放数据,仅仅存放指针 */ PQUEUE create_queue() { PQUEUE pS = (PQUEUE)malloc(sizeof(Queue)); pS->front = (PNODE)malloc(sizeof(NODE)); if(!pS || !pS->front) { printf("pS or front malloc failed!!"); exit(-1); } else { pS->rear = pS->front; pS->front->pNext = NULL; } return pS; } /* 推断队列是否为空 */ bool is_empty(PQUEUE pS) { if(pS->front == pS->rear) return true; else return false; } /* 进队函数,从队尾进队,队头指针保持不变 */ void en_queue(PQUEUE pS, int e) { PNODE pNew = (PNODE)malloc(sizeof(NODE)); if(!pNew) { printf("pNew malloc failed"); exit(-1); } else { pNew->data = e; pNew->pNext = NULL; pS->rear->pNext = pNew; pS->rear = pNew; } return; } /* 出队函数,从队头出队,队尾指针保持不变,但当最后一个元素出队时, 须要对队尾指针又一次赋值,使其指向头结点 */ bool de_queue(PQUEUE pS,int *pData) { if(is_empty(pS)) return false; else { PNODE p = pS->front->pNext; *pData = p->data; pS->front->pNext = p->pNext; //这里是队列头元素出队的特殊情况,普通情况下,删除队头元素时 //仅需改动头结点中的指针。但当队列中最后一个元素被删除时。 //队列尾指针也丢失了,因此需对队尾指针又一次赋值(指向头结点)。 if(pS->rear == p) pS->rear = pS->front; free(p); } return true; } /* 遍历队列。从对头向队尾依次输出队中的元素 */ void traverse_queue(PQUEUE pS) { if(is_empty(pS)) printf("there is no data in the queue!\n"); else { PNODE pCurrent = pS->front->pNext; printf("Now datas int the queue are:\n"); while(pCurrent) { printf("%d ",pCurrent->data); pCurrent = pCurrent->pNext; } printf("\n"); } return; } /* 求队列的长度 */ int length(PQUEUE pS) { int count = 0; PNODE pCurrent = pS->front->pNext; while(pCurrent) { count++; pCurrent = pCurrent->pNext; } return count; } /* 销毁队列,头结点也被销毁,最后也将pS节点销毁,并将其指向为空。避免垂直指针的产生 */ void destroy_queue(PQUEUE pS) { if(is_empty(pS)) return; else { while(pS->front) { pS->rear = pS->front->pNext; free(pS->front); pS->front = pS->rear; } } free(pS); pS = 0; return; } /* 用两个队列模拟入栈操作 */ void push(PQUEUE pS1,PQUEUE pS2,int val) { if(is_empty(pS2)) en_queue(pS1, val); else en_queue(pS2, val); } /* 用两个队列模拟出栈操作 */ bool pop(PQUEUE pS1,PQUEUE pS2,int *pData) { if(is_empty(pS1) && is_empty(pS2)) return false; int DelData; if(!is_empty(pS2)) { int len = length(pS2); while(len-- > 1) { de_queue(pS2,&DelData); en_queue(pS1,DelData); } //将队列的最后一个元素出队,作为出栈元素 de_queue(pS2,pData); return true; } if(!is_empty(pS1)) { int len = length(pS1); while(len-- > 1) { de_queue(pS1,&DelData); en_queue(pS2,DelData); } //将队列的最后一个元素出队。作为出栈元素 de_queue(pS1,pData); return true; } }
測试结果:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbnNfY29kZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" />
版权声明:本文博客原创文章,博客,未经同意,不得转载。
时间: 2024-11-10 07:09:30