• 【剑指offer】两个队列实现堆栈


    转载请注明出处: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
    ",length(pS1));
    	printf("the length of pS2: %d
    ",length(pS2));
    	if(pop(pS1,pS2,&pData))
    		printf("%d is pop out
    ",pData);
    	else
    		printf("Stack is empty,can not pop
    ");
    	printf("the length of pS1: %d
    ",length(pS1));
    	printf("the length of pS2: %d
    ",length(pS2));
    	push(pS1,pS2,6);
    	printf("the length of pS1: %d
    ",length(pS1));
    	printf("the length of pS2: %d
    ",length(pS2));
    	push(pS1,pS2,7);
    	printf("the length of pS1: %d
    ",length(pS1));
    	printf("the length of pS2: %d
    ",length(pS2));
    	if(pop(pS1,pS2,&pData))
    		printf("%d is pop out
    ",pData);
    	else
    		printf("Stack is empty,can not pop
    ");
    	printf("the length of pS1: %d
    ",length(pS1));
    	printf("the length of pS2: %d
    ",length(pS2));	
    	if(pop(pS1,pS2,&pData))
    		printf("%d is pop out
    ",pData);
    	else
    		printf("Stack is empty,can not pop
    ");
    	printf("the length of pS1: %d
    ",length(pS1));
    	printf("the length of pS2: %d
    ",length(pS2));
    	if(pop(pS1,pS2,&pData))
    		printf("%d is pop out
    ",pData);
    	else
    		printf("Stack is empty,can not pop
    ");
    	printf("the length of pS1: %d
    ",length(pS1));
    	printf("the length of pS2: %d
    ",length(pS2));
    	if(pop(pS1,pS2,&pData))
    		printf("%d is pop out
    ",pData);
    	else
    		printf("Stack is empty,can not pop
    ");
    
    	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!
    ");
    	else
    	{	
    		PNODE pCurrent = pS->front->pNext; 
    		printf("Now datas int the queue are:
    ");
    		while(pCurrent)
    		{
    			printf("%d ",pCurrent->data);
    			pCurrent = pCurrent->pNext;
    		}
    		printf("
    ");
    	}
    	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;
    	}
    }

        測试结果:



    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    unity3d中获得物体的size
    Quartz中时间表达式的设置-----corn表达式
    .net web 开发平台- 表单设计器 一(web版)
    编写你自己的单点登录(SSO)服务
    2009年末最强梅麻呂3D动画游戏大作 汉化补丁
    程序猿加班到深夜,你经历过没?
    初步理解socket
    几种开源分词工具的比較
    ORM框架
    linux tar.gz zip 解压缩 压缩命令
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4675976.html
Copyright © 2020-2023  润新知