化栈为队及化队为栈

队列的实现

思路:用链表实现队列,先定义一个结构体QNode,里面存放数据域和指针域,因为队列只在队头和队尾进行操作,可以让两个指针分别指向队头和队尾,所以再定义一个结构体Queue里面存放两个QNode结构体的指针——front和_rear,让这两个结构体一个指向链表的头一个指向尾。然后通过Queue这个结构体里面的两个指针来对队列进行各种操作。

还是上图吧

在这里插入图片描述

代码的实现

在这里插入图片描述

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <malloc.h>

// 链式结构:表示队列 
typedef int QDataType;
typedef struct QNode
{ 
    struct QNode* _pNext; 
    QDataType _data; 
}QNode; 
 
// 队列的结构 
typedef struct Queue 
{ 
  QNode* _front; 
  QNode * _rear; 
}Queue; 
 
// 初始化队列 
void QueueInit(Queue* q)
{
	assert(q);
	q->_front=q->_rear=NULL;
}
// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{
	assert(q);
   QNode* newnode=(QNode*)malloc(sizeof(QNode));
   newnode->_data=data;
   newnode->_pNext=NULL;
   if(q->_rear==NULL)
   {
	   q->_rear= q->_front=newnode;
   }
   else
   {
	   q->_rear->_pNext=newnode;
	   q->_rear=newnode;
   }
}
// 队头出队列 
void QueuePop(Queue* q)
{
	assert(q);
	
	QNode *p=q->_front->_pNext;
	free(q->_front);
	q->_front=p;
	if(q->_front==NULL)
	{
		q->_rear=NULL;
	}
}

// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{
	assert(q);

		return q->_front->_data;

}

// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{
	assert(q);
	
	return q->_rear->_data;
}

// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{
	assert(q);
	int count=0;
	QNode*p=q->_front;

	while(p!=NULL)
	{
		p=p->_pNext;
		++count;
	}
	return count;
}

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{
	assert(q);
	return q->_front==NULL? 1:0;
}

// 销毁队列 
void QueueDestroy(Queue* q)
{
	QNode *p=q->_front;
	while(p!=NULL) 
	{
		QNode *next=p->_pNext;
		free(p);
		p=next;
	}
	q->_front=q->_rear=NULL;
}

void QueuePrint(Queue *q)
{
	assert(q);
	QNode *cur=q->_front;
	while(cur!=NULL)
	{
		printf("%d  ",(cur->_data));
		cur=cur->_pNext;
	}
	printf("\n");
}

void test()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
    QueuePush(&q, 3);
    QueuePush(&q, 5);
   // QueuePop(&q);
    QueuePrint(&q);
    printf("队头的元素: %d\n",QueueFront(&q));
	printf("队尾的元素: %d\n",QueueBack(&q));
	printf("队列中元素个数:%d\n",QueueSize(&q));
	 QueueDestroy(& q);
	printf("1:空 0:非空 队列是否为空 %d\n",QueueEmpty(&q));
}
int main()
{
	test();
	return 0;
}

栈的实现

栈的实现

两个栈实现队列

思路:这里就只讲一下push和pop吧,栈是后进先出,而队列是先进先出,所以要想用栈实现队列可以定义两个栈,一个是push的一个是pop的,入数据进入push栈,出数据从pop栈出,如果pop栈为空,则将push栈里面的数据出栈然后入栈到pop中去。。。。。似乎说的有点绕

在这里插入图片描述

// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack 
{    STDataType* myarr;  
int _top;       // 栈顶  
int _capacity;  // 容量 
}Stack;
void StackInit(Stack* ps)//创建空数组
{
	assert(ps);
	ps->_capacity = 10;
	ps->_top = 0;
	ps->myarr = (STDataType*)malloc(sizeof(STDataType)*ps->_capacity);
	//if (ps->myarr == NULL)
	//	return NULL;
}
void StackCapacity(Stack* ps)//扩容
{
	assert(ps);
	if (ps->_top == ps->_capacity)
	{
		if (ps->myarr == 0)
			ps->_capacity = 2;
		ps->myarr= (STDataType *)realloc(ps->myarr, ps->_capacity*sizeof(STDataType)* 2);
		ps->_capacity = ps->_capacity * 2;

	}
}

void StackPush(Stack* ps, STDataType x)//入栈
{
	assert(ps);
	StackCapacity(ps);
	ps->myarr[ps->_top] = x;
	ps->_top++;
}
void Stackprint(Stack *ps)//打印栈
{
	assert(ps);
	Stack *p = ps;
	for (int i = 0; i < ps->_top; i++)
	{
		printf("%d  ", ps->myarr[i]);

	}printf("\n");
}
void StackPop(Stack* ps)//出栈
{
	assert(ps);
	if (ps->_top == 0)
	{
		//printf("栈为空\n");
		return;
	}
	//STDataType  s=ps->myarr[ps->_top-1];
	(ps->_top)--;
    
    
}
void StackEmpty(Stack* ps)//清空栈
{
	assert(ps);
	ps->_capacity = 0;
	ps->_top = 0;
	free(ps->myarr);
	//if (ps->_top == 0)
		//printf("栈为空");

}
int StackSize(Stack* ps)//输出栈的大小
{
	assert(ps); 
	
	 //printf("栈的长度为%d\n",ps->_top);
     return ps->_top;
}
STDataType StackTop(Stack* ps)
{
	assert(ps);
	/*if (ps->_top == 0)
	{
		printf("栈为空\n");
		return ;
	}*/
	//printf("栈顶的内容%d\n", ps->myarr[ps->_top-1]);
    return ps->myarr[ps->_top-1];
	
}


typedef struct {
Stack s1;//push
Stack s2;//pop
} MyQueue;

/** Initialize your data structure here. */

MyQueue* myQueueCreate() {
MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
StackInit(&(obj->s1));
StackInit(&(obj->s2));
return obj;
}

/** Push element x to the back of queue. */
void myQueuePush(MyQueue* obj, int x) {
 StackPush(&obj->s1,x);

}

/** Removes the element from in front of queue and returns that element. */
int myQueuePop(MyQueue* obj) {
 //如果s2(pop)栈为空,则需要将s1里面的数据倒过来,然后pop
 if(StackSize(&obj->s2)==0)
 {
     while(StackSize(&obj->s1)>0)
     {
         StackPush(&obj->s2,StackTop(&obj->s1));
         StackPop(&obj->s1);
     }
    
 }

 
     STDataType s=StackTop(&obj->s2);
      StackPop(&obj->s2);
 
 return s;
}

/** Get the front element. */
int myQueuePeek(MyQueue* obj) {
  if(StackSize(&obj->s2)==0)
 {
     while(StackSize(&obj->s1)>0)
     {
         StackPush(&obj->s2,StackTop(&obj->s1));
         StackPop(&obj->s1);
     }
    
 }
return StackTop(&obj->s2);
}

/** Returns whether the queue is empty. */
bool myQueueEmpty(MyQueue* obj) {
return StackSize(&(obj->s1))==0&&StackSize(&(obj->s2))==0;
}

void myQueueFree(MyQueue* obj) {
   StackEmpty(&(obj->s1));
   StackEmpty(&(obj->s2));
}

两个队列实现栈

定义两个队列,一个是空队列empty一个是有数据的队列noempty,入栈是将数据存放到有数据的队列,出栈是需要将noempty里面除了队尾的元素,其他都要放到empty中,然后将noempty里面的元素出队列。

在这里插入图片描述

// 链式结构:表示队列 
typedef int QDataType;
typedef struct QNode
{ 
    struct QNode* _pNext; 
    QDataType _data; 
}QNode; 
 
// 队列的结构 
typedef struct Queue 
{ 
  QNode* _front; 
  QNode * _rear; 
}Queue; 
 
// 初始化队列 
void QueueInit(Queue* q)
{
	assert(q);
	q->_front=q->_rear=NULL;
}
// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{
	assert(q);
   QNode* newnode=(QNode*)malloc(sizeof(QNode));
   newnode->_data=data;
   newnode->_pNext=NULL;
   if(q->_rear==NULL)
   {
	   q->_rear= q->_front=newnode;
   }
   else
   {
	   q->_rear->_pNext=newnode;
	   q->_rear=newnode;
   }
}
// 队头出队列 
void QueuePop(Queue* q)
{
	assert(q);
	
	QNode *p=q->_front->_pNext;
	free(q->_front);
	q->_front=p;
	if(q->_front==NULL)
	{
		q->_rear=NULL;
	}
}

// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{
	assert(q);

		return q->_front->_data;

}

// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{
	assert(q);
	
	return q->_rear->_data;
}

// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{
	assert(q);
	int count=0;
	QNode*p=q->_front;

	while(p!=NULL)
	{
		p=p->_pNext;
		++count;
	}
	return count;
}

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{
	assert(q);
	return q->_front==NULL? 1:0;
}

// 销毁队列 
void QueueDestroy(Queue* q)
{
	QNode *p=q->_front;
	while(p!=NULL) 
	{
		QNode *next=p->_pNext;
		free(p);
		p=next;
	}
	q->_front=q->_rear=NULL;
}

typedef struct {
//定义两个队列
Queue q1;
Queue q2;
} MyStack;

/** Initialize your data structure here. */

MyStack* myStackCreate() {
 MyStack *obj=(MyStack*)malloc(sizeof(MyStack));
 QueueInit(&(obj->q1));
  QueueInit(&(obj->q2));
  return obj;
}

/** Push element x onto stack. */
void myStackPush(MyStack* obj, int x) {
  
  if(QueueEmpty(&(obj->q1))==1)//q1为空
  {
     QueuePush(&(obj->q2),x);
  }
  else
  {
      QueuePush(&(obj->q1),x);
  }
}

/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack* obj) {
  
 Queue* empty=&obj->q1;
Queue* noempty=&obj->q2;
  if(QueueEmpty(&(obj->q1))==0)//q1不为空
  {
      empty=&obj->q2;
      noempty=&obj->q1;
  }
  
  while(QueueSize((noempty))>1)
  {
      QueuePush((empty),QueueFront((noempty)));
      QueuePop((noempty));

  }
 int q=QueueFront(noempty);
   QueuePop(noempty);
  return q;
}

/** Get the top element. */
int myStackTop(MyStack* obj) {
    
    
Queue empty=obj->q1;
Queue noempty=obj->q2;
  if(QueueEmpty(&(obj->q1))==0)//q1不为空
  {
      empty=obj->q2;
      noempty=obj->q1;
  }
  return QueueBack(&(noempty));
}

/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj) {
 return QueueEmpty(&(obj->q1))&&QueueEmpty(&(obj->q2));
}

void myStackFree(MyStack* obj) {
    QueueDestroy(&(obj->q1));
     QueueDestroy(&(obj->q2));
   //  free(&MyStack);

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值