栈和队列之间的互相实现

来源:互联网 发布:linux 查看命令的路径 编辑:程序博客网 时间:2024/06/02 13:52

第一部分、两个队列实现一个栈

本来想画图,可实在没这时间,且理解起来相对容易

主要思想是,先将 所有数先导入一个队列A中去,另一个队列B此刻为空。将队列A中除了最后一个数其他都导入B中,然后将A中仅剩的一个数输出,这样循环下去,就造成了栈的假象。

实现如下:

//队列实现#ifndef QUEUE_H#define QUEUE_H#include <stdio.h> #include <stdlib.h>#include <malloc.h>typedef struct NODE{int n;struct NODE *pnext;}nod, * pnod;typedef struct S{pnod phead;pnod ptail;}ss, * pss;void init(pss);void en_queue(pss,int );void out_queue(pss,int &);bool is_empty(pss);int nodes_remain(pss);void init(pss Y){Y->phead=(pnod)malloc(sizeof(nod));if(Y->phead == NULL)exit(-1);Y->phead->pnext=NULL;Y->ptail=Y->phead;}void en_queue(pss Y,int val){pnod new_x=(pnod)malloc(sizeof(nod));if(new_x == NULL)exit(-1);new_x->n=val;new_x->pnext=NULL;Y->ptail->pnext=new_x;Y->ptail=new_x;}bool is_empty(pss Y){if(Y->phead == Y->ptail)return true;elsereturn false;}void out_queue(pss Y,int & T){if(is_empty(Y))return;else{pnod r=Y->phead->pnext;Y->phead->pnext=r->pnext;if(Y->phead->pnext==NULL)         //我就觉得这里需要注意一下  就是只剩下一个没有val的头结点和一个尾节点指向的节点的时候   没有这一步的话无法判断 is_emptyY->ptail=Y->phead;T = r->n;free(r);}}int nodes_remain(pss Y){int count=0;pnod p = Y->phead->pnext;while(p){count++;p = p->pnext;}return count;}#endif


//main#include <stdio.h>//与两个栈实现一个队列相对应#include "queue.h"int main(){int a[] = {1,2,3,4,5,6,7};pss Queue_A,Queue_B;Queue_A = (pss)malloc(sizeof(ss));Queue_B = (pss)malloc(sizeof(ss));init(Queue_A);init(Queue_B);int i;for(i=0;i<7;i++)en_queue(Queue_A,a[i]);printf("Datas stored in Queue_A:\n");//输出存储在A中的数据for(i=0;i<7;i++)printf("%d%c",a[i],(i+1)%7==0?'\n':' ');int temp;//以下为按照栈的形式输出第一个数for(i=0;i<6;i++)//将队列A中数据逐个导入B中,但是 最后一个数不导 而是直接输出out_queue  这样就把最后一个数第一个输出了{out_queue(Queue_A,temp);en_queue(Queue_B,temp);}printf("Output the first data as Stack-style : \n");out_queue(Queue_A,temp);printf("%d\n",temp);//以上是输出一个数 那如果要连续输出呢//以下就是连续输出   为了避免只将一个栈作为存储 而另一个作为临时的浪费 利用两个指针pss p, q;if(is_empty(Queue_A)){p = Queue_B;q = Queue_A;}else{p = Queue_A;q = Queue_B;}while(!is_empty(p))//将p作为有数的那个栈 q作为空栈{while(nodes_remain(p)>1)//使队列中仅剩一个数{out_queue(p,temp);en_queue(q,temp);}out_queue(p,temp);printf("%d ",temp);if(is_empty(Queue_A))//有数的队列已经变成了另一个 此刻将p指针指向这个队列{p = Queue_B;q = Queue_A;}else{p = Queue_A;q = Queue_B;}}puts("");return 0;}



第二部分:两个栈实现一个队列

简单的设想是将所有元素导入A,再倒入B,之后直接输出。这里考虑了如果需要新增元素该怎么处理,并不需要因为新元素来回倒腾

//栈实现#ifndef STACK_H#define STACK_H#include <stdio.h>                  #include <malloc.h>#include <stdlib.h>typedef struct subject {int data;struct subject *pnext;}node,* pnode;typedef struct First {pnode ptop;pnode pbottom;}s,* ps;void init(ps S)               {S->ptop=(pnode)malloc(sizeof(node));if(NULL == S->ptop){printf("FALE\n");exit(1);}S->ptop->pnext=NULL;S->pbottom=S->ptop;}void push(ps S,int val)           {pnode newx=(pnode)malloc(sizeof(node));if(NULL == newx){printf("FALE\n");exit(1);}newx->data=val;newx->pnext=S->ptop;S->ptop=newx;}bool empty(ps S)            {if(S->ptop==S->pbottom)return true;elsereturn false;}void pop(ps S,int &e)         {if(empty(S))return;else{pnode r;r=S->ptop;S->ptop=r->pnext;e = r->data;free(r);}}void traverse(ps S){if(empty(S))return;else{pnode p;p=S->ptop;while(p!=S->pbottom){printf("%d  ",p->data);p=p->pnext;}putchar('\n');}}void clear(ps S)                 {pnode p;pnode q;p=S->ptop;while(p != S->pbottom){q=p->pnext;free(p);p=q;}S->ptop=S->pbottom;}#endif


//main#include <stdio.h>//实现 出队列操作#include <malloc.h>#include "stack.h"//不难理解  只是在看到问题时候是否想得到是否有思路  将两个栈一起来实现队列的出队int main(){ps Stack_A = (ps)malloc(sizeof(s));ps Stack_B = (ps)malloc(sizeof(s));init(Stack_A);init(Stack_B);int i;int a[] = {1,2};printf("The origin order of the array:\n");for(i=0;i<2;i++)printf("%d ",a[i]);puts("");for(i=0;i<2;i++)push(Stack_A,a[i]);printf("Datas in Stack_A:\n");traverse(Stack_A);int temp;while(!empty(Stack_A))//此处可以优化可以计数  不必将所有都导入B 而是留下A中的最后一个 继而直接输出 而不是导入B后由B输出{pop(Stack_A,temp);push(Stack_B,temp);}printf("Datas in Stack_B:\n");traverse(Stack_B);pop(Stack_B,temp);printf("Output the first number as the Queue-style :\n");printf("%d\n",temp);//以上实现的是一次性  若是需要反复加入新元素同时能够按队列形式输出呢//一种方式是在按需输出元素后,将所有元素导入A如果需要入队则直接入A  之后再入B,输出,按需重复上述步骤//还有一种方式如下://如果需要入队 则直接进A  (为什么不需要来回倒腾一番呢?因为我要入队的数全都暂时存在A中 一旦B中的数消耗掉了 就将A中的数字导入B)push(Stack_A,10);//不空的话 说明数全在A中 直接将此数入A//这种方式如果要出队 并不会在上一次出队后将B中所有数全倒回A 而是将计就计(当然 这得需要没有新增的入队操作) if(empty(Stack_B))//如果为空,即B中元素全都输出完了,则将A中的后来元素全部导入Bwhile(!empty(Stack_A)){pop(Stack_A,temp);push(Stack_B,temp);}printf("Datas in Stack_B:\n");traverse(Stack_B);pop(Stack_B,temp);//如果不空 则说明数全在B中(或者说并没有进行入队操作) 则直接将B中数据popprintf("Output the next number as the Queue-style :\n");printf("%d\n",temp);//当然 如果要继续的话 可以设循环return 0;}



0 0
原创粉丝点击