2つのスタックは1つのキューを実現し、2つのキューは1つのスタックを実現する.

4998 ワード

リンク内のスタックとキューで実装されたコードのブログhttps://blog.csdn.net/Damn_Yang/article/details/83928852
2つのスタックで1つのキューを実現
考え方:
エンキュー時、直接stack 1に押し込む
出隊時に、stack 2が空かどうかを判断し、stack 2が空の場合は、stack 1の要素をstack 2に注ぎ込み、そうでない場合は、stack 2の要素を直接ポップアップします.
コード実装(C)
Topic.h
#pragma once

#include "Queue.h"
#include "Stack.h"


//          
typedef struct QueueByTwoStack
{
	Stack s1;
	Stack s2;
}QueueByTwoStack;

void QueueByTwoStackInit(QueueByTwoStack*qts);
void QueueByTwoStackDestory(QueueByTwoStack*qts);
void QueueByTwoStackPush(QueueByTwoStack*qts, DataType x);
void QueueByTwoStackPop(QueueByTwoStack*qts);
DataType QueueByTwoStackFront(QueueByTwoStack*qts);
int QueueByTwoStackEmpty(QueueByTwoStack*qts);
int QueueByTwoStackSize(QueueByTwoStack*qts);
void TestQueueByTwoStack();
​

Topic.c
#include"Topic.h"

void QueueByTwoStackInit(QueueByTwoStack*qts)
{
	assert(qts);
	StackInit(&qts->s1);
	StackInit(&qts->s2);
}
void QueueByTwoStackDestory(QueueByTwoStack*qts)
{
	assert(qts);
	StackDestory(&qts->s1);
	StackDestory(&qts->s2);
}

void QueueByTwoStackPush(QueueByTwoStack*qts, DataType x)
{
	StackPush(&qts->s1,x);
}
//  s2      
//  s2    ,  s1      
void QueueByTwoStackPop(QueueByTwoStack*qts)
{
	if (StackEmpty(&qts->s2))
	{
		while (!StackEmpty(&qts->s1))
		{
			StackPush(&qts->s2, StackTop(&qts->s1));
			StackPop(&qts->s1);             
		}
	}
	StackPop(&qts->s2);
}

DataType QueueByTwoStackFront(QueueByTwoStack*qts)
{
	assert(qts);
	if (StackEmpty(&qts->s2))
	{
		while (StackEmpty(&qts->s1))
		{
			StackPush(&qts->s2, StackTop(&qts->s1));
			StackPop(&qts->s1);
		}
	}
	return StackTop(&qts->s2);
}

int QueueByTwoStackEmpty(QueueByTwoStack*qts)
{
	assert(qts);
	return StackEmpty(&qts->s1) | StackEmpty(&qts->s2);
}
int QueueByTwoStackSize(QueueByTwoStack*qts)
{
	assert(qts);
	return StackSize(&qts->s1) + StackSize(&qts->s2);
}

void TestQueueByTwoStack()
{
	QueueByTwoStack q;
	QueueByTwoStackInit(&q);
	QueueByTwoStackPush(&q, 1);
	QueueByTwoStackPush(&q, 2);
	QueueByTwoStackPush(&q, 3);
	QueueByTwoStackPush(&q, 4);
	QueueByTwoStackPop(&q);
	QueueByTwoStackPop(&q);
	QueueByTwoStackPush(&q, 5);
	QueueByTwoStackPush(&q, 6);
	while (QueueByTwoStackEmpty(&q))
	{
		printf("%d ", QueueByTwoStackFront(&q));
		QueueByTwoStackPop(&q);
	}
	printf("
"); }

2つのキューで1つのスタックを実装
考え方:
スタックに入るときは、空スタックに押し込み、q 1とq 2のどちらが空でどちらの中に入るか(例えばq 1が空)
スタックを出るときは、まずqueue 1の要素を最後の要素のほかに順番にキューを出し、キューqueue 2に押し込み、queue 1に残っている最後の要素をスタック要素とし、最後にqueue 2の要素を再びqueue 1に押し込む
コード実装(C言語)
Topic.h
#include "Stack.h"
#include "Queue.h"
typedef struct StackByTwoQueue
{
	Queue q1;
	Queue q2;
}StackByTwoQueue;

void StackByTwoQueueInit(StackByTwoQueue* stq);
void StackByTwoQueueDestory(StackByTwoQueue* stq);
void StackByTwoQueuePush(StackByTwoQueue* stq, DataType x);
void StackByTwoQueuePop(StackByTwoQueue* stq);
DataType StackByTwoQueueTop(StackByTwoQueue*stq);

int StackByTwoQueueEmpty(StackByTwoQueue* stq);
int StackByTwoQueueSize(StackByTwoQueue* stq);

Topic.c
#include "Topic.h"
void StackByTwoQueueInit(StackByTwoQueue* stq)
{
	assert(stq);
	QueueInit(&stq->q1);
	QueueInit(&stq->q2);

}
void StackByTwoQueueDestory(StackByTwoQueue* stq)
{
	QueueDestory(&stq->q1);
	QueueDestory(&stq->q2);
}
void StackByTwoQueuePush(StackByTwoQueue* stq, DataType x)
{
	assert(stq);
	if (!QueueEmpty(&stq->q1))
	{
		QueuePush(&stq->q1, x);
	}
	else
	{
		QueuePush(&stq->q2, x);
	}
}
void StackByTwoQueuePop(StackByTwoQueue* stq)
{
	assert(stq);
	Queue*empty = &stq->q1, *nonempty = &stq->q2;
	if (!QueueEmpty(&stq->q1))
	{
		empty = &stq->q2;
		nonempty = &stq->q1;
	}
	while (QueueSize(nonempty) > 1)
	{
		QueuePush(empty, QueueFront(nonempty));
		QueuePop(nonempty);
	}
	QueuePop(nonempty);
}
DataType StackByTwoQueueTop(StackByTwoQueue*stq)
{
	assert(stq);
	if (QueueEmpty(&stq->q1) != 0)
	{
		return stq->q1._back->_data;
	}
	else
	{
		return stq->q2._back->_data;
	}
}
int StackByTwoQueueEmpty(StackByTwoQueue* stq)
{
	assert(stq);
	return QueueEmpty(&stq->q1) | QueueEmpty(&stq->q2);
}
int StackByTwoQueueSize(StackByTwoQueue* stq)
{
	assert(stq);
	return QueueSize(&stq->q1) + QueueSize(&stq->q2);
}

TestStackByTwoQueue()
{
	StackByTwoQueue s;
	StackByTwoQueueInit(&s);
	StackByTwoQueuePush(&s, 1);
	StackByTwoQueuePush(&s, 2);
	StackByTwoQueuePush(&s, 3);
	StackByTwoQueuePush(&s, 4);
	StackByTwoQueuePush(&s, 5);
	while (StackByTwoQueueEmpty(&s))
	{
		printf("%d ", StackByTwoQueueTop(&s));
		StackByTwoQueuePop(&s);
	}
}