栈和队列的实现问题

问题一:用两个栈实现一个队列

分析:队列遵循的是先进先出的原则,用两个栈来实现,一个栈管理入队列,另一个管理出队列,出队列就是将第一个栈的元素依次放入第二个栈中,然后在第二个栈进行出栈操作,所表现出的就是出队列了

avater

typedef struct QueueS
{
	Stack	stack1;
	Stack	stack2;
}	QueueS;

void QSInit(QueueS *pQS)
{
	StackInit(&(pQS->stack1));
	StackInit(&(pQS->stack2));
}

void QSPush(QueueS *pQS, StackDataType data)
{
	// 对第一个栈进行压栈
	StackPush(&(pQS->stack1), data);
}

void QSPop(QueueS *pQS)
{
	Stack *p1 = &(pQS->stack1);
	Stack *p2 = &(pQS->stack2);

	// 如果栈 2 为空,从栈 1 将数据导过来
	if (StackEmpty(p2)) {

		// 把栈 1 的所有数据依次导入 栈 2
		while (!StackEmpty(p1)) {
			StackDataType data = StackTop(p1);
			StackPush(p2, data);
			StackPop(p1);   //同时将栈 1 的元素出栈
		}
	}
    //出队列
	StackPop(p2);
}

StackDataType QSFront(QueueS *pQS)
{
	Stack *p1 = &(pQS->stack1);
	Stack *p2 = &(pQS->stack2);

	if (StackEmpty(p2)) {
		while (!StackEmpty(p1)) {
			StackDataType data = StackTop(p1);
			StackPush(p2, data);
			StackPop(p1);
		}
	}

	return StackTop(p2);
}

问题二:用两个队列实现一个栈

分析:栈遵循的是先进后出的原则

Push:往非空队列里插入(如果两个队列都是空,选第一个插入)

Pop:从非空队列中 move size - 1 个元素到 空队列中,pop 剩下的一个

Top: 从非空队列中 move size - 1 个元素到空队列中,返回剩下的一个的值, 把剩下的一个也放入另一个队列中

typedef struct {
	Queue	queue_1;
	Queue	queue_2;
}	QStack;

// 初始化/销毁
void QSInit(QStack *pQS)
{
	QueueInit(&(pQS->queue_1));
	QueueInit(&(pQS->queue_2));
}

void QSDestroy(QStack *pQS)
{
	QueueDestroy(&(pQS->queue_2));
	QueueDestroy(&(pQS->queue_1));
}

// Push / Pop / Top
void QSPush(QStack *pQS, QDataType data)
{
    //假设编程
    //先假设 2 为空,看 1 是否为空
    //如果 1 为空,那就给 1 入队列
	Queue *pNotEmpty = &(pQS->queue_2);
	if (QueueEmpty(pNotEmpty)) {
		pNotEmpty = &(pQS->queue_1);
	}

	QueuePush(pNotEmpty, data);
}


void QSPop(QStack *pQS)
{
	// 假设编程
	// 我们程序正确的前提:
	// 1. 一个空、一个非空
	// 2. 两个都是空
	Queue *pEmpty = &(pQS->queue_1);
	Queue *pNotEmpty = &(pQS->queue_2);
	if (QueueEmpty(pNotEmpty)) {
		pEmpty = &(pQS->queue_2);
		pNotEmpty = &(pQS->queue_1);
	}

	// 从非空队列中 move  size - 1 个元素到 空队列中
	while (QueueSize(pNotEmpty) > 1) {
		QDataType data = QueueFront(pNotEmpty);
		QueuePop(pNotEmpty);
		QueuePush(pEmpty, data);
	}

	// pNotEmpty 队列里只剩一个数据
	QueuePop(pNotEmpty);
}

QDataType QSTop(QStack *pQS)
{
	// 假设编程
	// 我们程序正确的前提:
	// 1. 一个空、一个非空
	// 2. 两个都是空
	Queue *pEmpty = &(pQS->queue_1);
	Queue *pNotEmpty = &(pQS->queue_2);
	if (QueueEmpty(pNotEmpty)) {
		pEmpty = &(pQS->queue_2);
		pNotEmpty = &(pQS->queue_1);
	}

	// 从非空队列中 move  size - 1 个元素到 空队列中
	while (QueueSize(pNotEmpty) > 1) {
		QDataType data = QueueFront(pNotEmpty);
		QueuePop(pNotEmpty);
		QueuePush(pEmpty, data);
	}

	// pNotEmpty 队列里只剩一个数据
	QDataType r =  QueueFront(pNotEmpty);
	QueuePop(pNotEmpty);
	QueuePush(pEmpty, r);

	return r;
}

问题三:一个数组实现两个栈

分析:采用两边往中间生长的方式

扩容问题:当 top1>top2 时扩容

数据搬移问题

avater

typedef struct {
	int		*array;
	int		top1;
	int		top2;
	int		capacity;
}	TStack;

// 初始化
void TStackInit(TStack *pTS)
{
	pTS->capacity = 10;
	pTS->array = (int *)malloc(sizeof(int)* pTS->capacity);
	pTS->top1 = 0;

	pTS->top2 = pTS->capacity - 1;	// 不要越界
}

void TStackDestroy(TStack *pTS)
{
	free(pTS->array);
}

void ExpandIfRequired(TStack *pTS)
{
	if (pTS->top1 <= pTS->top2) {
		return;
	}

	int newCapacity = pTS->capacity * 2;
	int *newArray = (int *)malloc(sizeof(int)* newCapacity);
	assert(newArray);
	// 搬移数据

	// 搬移栈 1 的数据
	for (int i = 0; i < pTS->top1; i++) {
		newArray[i] = pTS->array[i];
	}

	// 搬移栈 2 的数据
	// j ~ [top1, capacity)		// 栈2 在老数组中所在下标区间
	for (int j = pTS->top1; j < pTS->capacity; j++) {
		// k 是新数组的下标
		int k = j + pTS->capacity;

		newArray[k] = pTS->array[j];
	}

	pTS->top2 += pTS->capacity;
	pTS->capacity = newCapacity;

	// 空间,下面两句的顺序不能交换
	free(pTS->array);
	pTS->array = newArray;
}

// Push
void Push_1(TStack *pTS, int data)
{
	ExpandIfRequired(pTS);

	pTS->array[pTS->top1] = data;
	pTS->top1++;
}

void Push_2(TStack *pTS, int data)
{
	ExpandIfRequired(pTS);

	pTS->array[pTS->top2] = data;
	pTS->top2--;
}

// Pop
void Pop_1(TStack *pTS)
{
	pTS->top1--;
}

void Pop_2(TStack *pTS)
{
	pTS->top2++;
}

// Top
int Top_1(TStack *pTS)
{
	return pTS->array[pTS->top1 - 1];
}

int Top_2(TStack *pTS)
{
	return pTS->array[pTS->top2 + 1];
}

// Size
int Size_1(TStack *pTS)
{
	return pTS->top1;
}

int Size_2(TStack *pTS)
{
	return pTS->capacity - pTS->top2 - 1;
}

猜你喜欢

转载自blog.csdn.net/qq_40355351/article/details/82953995