用栈实现队列&用队列实现栈(破防时刻)

目录

栈的实现

队列的实现

相互实现

用队列实现栈

破防时刻

栈结构体用队列指针

栈结构体用队列实体

用栈实现队列


栈的实现

栈的实现

队列的实现

队列的实现

相互实现

既然栈和队列的基本结构和规则都有了,那么,一个成熟的程序员要学会变着花样玩。

首先,上两道题目了解一下:

用队列实现栈

用栈实现队列

用队列实现栈

破防时刻

既然要用两个队列去实现栈,那么很显然,新栈的结构体成员就是两个队列,那么问题来了,我们是用结构体呢?还是用结构体指针呢?

这个问题啊,当然是只有经历了才知道,本小白通过自己的惨痛教训告诫大家,还是尽量用结构体成员吧。😭😭😭

那用指针有什么问题呢?

如果你不幸用了指针(啊其实是在说我自己),那么初始化的时候就不能调用队列的初始化函数,否则结构体里面的就是两个随机值,从而导致找不到q1的实体,那么你就需要直接将q1,q2置为空,这一置空,你就需要在bush和pop函数中对队列进行实体化,而且判断队列为空的函数也需换成obj->q1==NULL,在后续函数实现中也需要多很多判断,有些内容甚至需要探到链表的一层去完成。总的来说别用指针就对了。当然,两种实现方法都贴出来让大家鉴赏一下。

栈结构体用队列指针

对列结构:

typedef int QDataType;
typedef struct QListNode
{
	struct QListNode* _next;
	QDataType _data;
}QNode;

// 队列的结构 
typedef struct Queue
{
	QNode* _head;
	QNode* _tail;
}Queue;
void QueueInit(Queue* q)
{
	assert(q);
	q->_head = NULL;
	q->_tail = NULL;
}
void QueuePush(Queue* q, QDataType data)
{
	assert(q);
	QNode* newNode = (QNode*)malloc(sizeof(QNode));
	assert(newNode);
	newNode->_next = NULL;
	newNode->_data = data;
	if (q->_tail == NULL)
	{
		assert(q->_head == NULL);
		q->_head = q->_tail = newNode;
	}
	else
	{
		q->_tail->_next = newNode;
		q->_tail = newNode;
	}
}
void QueuePop(Queue* q)
{
	assert(q);
	assert(q->_head && q->_tail);
	if (q->_head->_next == NULL)
	{
		free(q->_head);
		q->_head = q->_tail = NULL;
	}
	else
	{
		QNode* next = q->_head->_next;
		free(q->_head);
		q->_head = next;
	}
}
QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(q->_head);
	return q->_head->_data;
}
QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(q->_tail);
	return q->_tail->_data;
}
int QueueSize(Queue* q)
{
	assert(q);
	QNode* cur = q->_head;
	size_t size = 0;
	while (cur)
	{
		size++;
		cur = cur->_next;
	}
	return size;
}
int QueueEmpty(Queue* q)
{
	assert(q);
	return q->_head == NULL;
}
void QueueDestroy(Queue* q)
{
	assert(q);
	QNode* next = NULL;
	QNode* cur = q->_head;
	while (cur)
	{
		next = cur->_next;
		free(cur);
		cur = next;
	}
	q->_head = NULL;
	q->_tail = NULL;
}

用队列实现栈:

typedef struct 
{
	Queue* q1;
	Queue* q2;
} MyStack;


MyStack* myStackCreate() 
{
	MyStack* st = (MyStack*)malloc(sizeof(MyStack));
	assert(st);
	st->q1 = NULL;
	st->q2 = NULL;
	return st;
}

void myStackPush(MyStack* obj, int x)
{
	assert(obj);
	if (obj->q1)
	{
		QueuePush(obj->q1, x);
	}
	else if(obj->q2)
	{
		QueuePush(obj->q2, x);
	}
	else
	{
		Queue* q1 =(Queue*) malloc(sizeof(Queue));
		assert(q1);
		obj->q1 = q1;
		QueueInit(obj->q1);
		QueuePush(obj->q1,x);
	}
}

int myStackPop(MyStack* obj) 
{
	Queue* empty = NULL;
	Queue* noEmpty = NULL;
	if (obj->q1)
	{
		if (obj->q1->_head == obj->q1->_tail)
		{
			QDataType ret = QueueFront(obj->q1);
			QueueDestroy(obj->q1);
			obj->q1 = NULL;
			return ret;
		}
		noEmpty = obj->q1;
		obj->q1 = NULL;
		empty = obj->q2 = (Queue*)malloc(sizeof(Queue));
		assert(empty);
		QueueInit(obj->q2);
	}
	else if (obj->q2)
	{
		if (obj->q2->_head == obj->q2->_tail)
		{
			QDataType ret = QueueFront(obj->q2);
			QueueDestroy(obj->q2);
			obj->q2 = NULL;
			return ret;
		}
		noEmpty = obj->q2;
		obj->q2 = NULL;
		empty = obj->q1 = (Queue*)malloc(sizeof(Queue));
		assert(empty);
		QueueInit(obj->q1);

	}
	else
	{
		return 0;
	}
	QDataType top = QueueBack(noEmpty);
	QNode* cur = noEmpty->_head;
	while (cur != noEmpty->_tail)
	{
		QueuePush(empty, cur->_data);
		cur = cur->_next;
	}
	QueueDestroy(noEmpty);
	return top;
}
int myStackTop(MyStack* obj)
{
	Queue* empty = NULL;
	Queue* noEmpty = NULL;
	if (obj->q1)
	{
		noEmpty = obj->q1;
		empty = obj->q2;
	}
	else if (obj->q2)
	{
		noEmpty = obj->q2;
		empty = obj->q1;
	}
	else
	{
		return -1;
	}
	return QueueBack(noEmpty);
}

bool myStackEmpty(MyStack* obj)
{
	if (obj->q1|| obj->q2)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

void myStackFree(MyStack* obj)
{
	if(obj->q1)
	QueueDestroy(obj->q1);
	if(obj->q2)
	QueueDestroy(obj->q2);
	free(obj);
}

int main()
{
	MyStack* st;
	st = myStackCreate();
	myStackPush(st, 1);
	myStackPop(st);
	myStackPush(st, 2);
	printf("%d", myStackTop(st));
	myStackFree(st);
}

测试:

int main()
{
	MyStack* st;
	st = myStackCreate();
	myStackPush(st, 1);
	myStackPop(st);
	myStackPush(st, 2);
	printf("%d", myStackTop(st));
	myStackFree(st);
}

栈结构体用队列实体

队列结构与上相同,可以复用

用队列实现栈

typedef struct
{
	Queue q1;
	Queue q2;
} MyStack;


MyStack* myStackCreate()
{
	MyStack* st = (MyStack*)malloc(sizeof(MyStack));
	assert(st);
	QueueInit(&st->q1);
	QueueInit(&st->q2);
	return st;
}
void myStackPush(MyStack* obj, int x)
{
	assert(obj);
	if (!QueueEmpty(&obj->q1))
	{
		QueuePush(&obj->q1, x);
	}
	else
	{
		QueuePush(&obj->q2, x);
	}
}

int myStackPop(MyStack* obj)
{
	assert(obj);
	Queue* empty = &obj->q1;
	Queue* noEmpty = &obj->q2;
	if (!QueueEmpty(&obj->q1))
	{
		noEmpty = &obj->q1;
		empty = &obj->q2;
	}
	while (QueueSize(noEmpty)>1)
	{
		QueuePush(empty, QueueFront(noEmpty));
		QueuePop(noEmpty);
	}
	QDataType top = QueueBack(noEmpty);
	QueuePop(noEmpty);
	return top;
}
int myStackTop(MyStack* obj)
{
	assert(obj);
	if (!QueueEmpty(&obj->q1))
	{
		return QueueBack(&obj->q1);
	}
	else
	{
		return QueueBack(&obj->q2);
	}
}
bool myStackEmpty(MyStack* obj)
{
	assert(obj);
	return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj)
{
	assert(obj);
	QueueDestroy(&obj->q1);
	QueueDestroy(&obj->q2);
	free(obj);
}

测试函数:

int main()
{
	MyStack* st;
	st = myStackCreate();
	myStackPush(st, 1);
	myStackPop(st);
	myStackPush(st, 2);
	printf("%d", myStackTop(st));
	myStackFree(st);
}

用栈实现队列

有了前车之鉴,我自然是没有在这里用指针实现了,如果哪个宝宝感兴趣,我也就推荐你多试试哈哈哈哈哈。

栈的结构

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;//栈顶位置
	int capacity;//容量
}ST;
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = -1;
}
void StackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->capacity = 0;
	ps->top = -1;
}
void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top + 1 == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		ps->a = (STDataType*)realloc(ps->a, newCapacity * sizeof(STDataType));
		assert(ps->a);
		if (ps->a == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
	}
	ps->top++;
	ps->a[ps->top] = x;
}
void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top >= 0);
	ps->top--;
}
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == -1;
}
int StackSize(ST* ps)
{
	assert(ps);
	return ps->top + 1;
}
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(ps->top >= 0);
	return ps->a[ps->top];
}

用栈实现队列

typedef struct 
{
	ST st1;
	ST st2;
} MyQueue;

MyQueue* myQueueCreate()
{
	MyQueue* newQue = (MyQueue*)malloc(sizeof(MyQueue));
	assert(newQue);
	StackInit(&newQue->st1);
	StackInit(&newQue->st2);
	return newQue;
}

void myQueuePush(MyQueue* obj, int x) 
{
	assert(obj);
	if (!StackEmpty(&obj->st2))
	{
		while (StackSize(&obj->st2) > 0)
		{
			StackPush(&obj->st1, StackTop(&obj->st2));
			StackPop(&obj->st2);
		}
	}
	StackPush(&obj->st1, x);
}

int myQueuePop(MyQueue* obj) 
{
	assert(obj);
	if (!StackEmpty(&obj->st1))
	{
		while (StackSize(&obj->st1) > 1)
		{
			StackPush(&obj->st2, StackTop(&obj->st1));
			StackPop(&obj->st1);
		}
	}
	int headOfQue;
	if (!StackEmpty(&obj->st1))//如果上一行还剩一个,则他就是队列头也是要删除的
	{
		headOfQue = StackTop(&obj->st1);
		StackPop(&obj->st1);
	}
	else if(StackEmpty(&obj->st1)&&!StackEmpty(&obj->st2))//如果上一行已经没了,则说明全在下一行,则直接从下一行开始删
	{
		headOfQue = StackTop(&obj->st2);
		StackPop(&obj->st2);
	}
	else
	{
		assert(0);
	}
	return headOfQue;
}

int myQueuePeek(MyQueue* obj) 
{
	assert(obj);
	if (!StackEmpty(&obj->st1))
	{
		while (StackSize(&obj->st1) > 0)
		{
			StackPush(&obj->st2, StackTop(&obj->st1));
			StackPop(&obj->st1);
		}
	}
	return StackTop(&obj->st2);
}

bool myQueueEmpty(MyQueue* obj) 
{
	assert(obj);
	return StackEmpty(&obj->st1) && StackEmpty(&obj->st2);
}

void myQueueFree(MyQueue* obj)
{
	printf("LLL");
	assert(obj);
	StackDestroy(&obj->st1);
	StackDestroy(&obj->st2);
	free(obj);
}

测试函数:

int main()
{
	MyQueue* que = myQueueCreate();
	myQueuePush(que, 1);
	myQueuePush(que, 2);
	myQueuePeek(que);
	myQueuePop(que);
	myQueueEmpty(que);
	myQueueFree(que);
}

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值