温故而知新 -> 数据结构 ->利用 队列 实现 栈 -> 程序实现1_利用结构体

温故而知新 -> 数据结构 ->利用 队列 实现 栈 -> 程序实现1_利用结构体

本篇博客是基于 温故而知新 -> 数据结构 -> 线性表 ->队列 && 栈 中利用 队列 实现 栈 的理论知识进行程序实现!

其中结合了 温故而知新->数据结构->队列->程序实现1_利用结构体 中的代码,实现了 栈 的 (入栈)(出栈)(栈顶元素)改(没写(~ ̄▽ ̄)~),判空,打印等操作!并附带了上述 队列 与 利用其所实现的栈 的对比实例以及对应的运行结果!

注意1:在利用队列实现栈的时候,分别采用了 一个队列两个队列 的实现方式进行实现,该内容在下述程序中会有对比说明!

注意2:其中代码有很大冗余,且未考虑性能最优,读者有兴趣可进一步精简!

具体内容如下
(1)newQStack.h

#ifndef __NEWQSTACK_H_
#define __NEWQSTACK_H_

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
//队列:带有尾指针的单链表

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

typedef struct Queue
{
	//头尾指针
	struct QNode * _head;
	struct QNode * _tail;
	int _size;
}Queue;

/* 方法一:利用一个队列实现时的 stack 结构体 */
//typedef struct{
//	//队列成员
//	struct Queue q;
//
//}MyStack;

/* 方法二:利用2个队列实现时的 stack 结构体 */
typedef struct{
	//队列成员
	struct Queue q1;
	struct Queue q2;

}MyStack;

#endif

(2)main.c

#include"newQStack.h"

/* 实现队列 */
void initQueue(Queue * q)
{
	if (q == NULL)
		return;
	q->_head = NULL;
	q->_tail = NULL;
	q->_size = 0;
}

struct QNode* creatNode(QDataType val)
{
	struct QNode * newNode = (struct QNode*)malloc(sizeof(struct QNode));
	newNode->_data = val;
	newNode->_next = NULL;
}

void queuePush(Queue * q, QDataType val)
{
	if (q == NULL)
		return;
	//尾插
	struct QNode*node = creatNode(val);
	//第一个节点
	if (q->_head == NULL)
		q->_head = q->_tail = node;
	else
	{
		q->_tail->_next = node;
		q->_tail = node;
	}
	++q->_size;
}

void queuePop(Queue * q)
{
	//头删
	if (q == NULL || q->_head == NULL)
		return;
	struct QNode * next = q->_head->_next;
	free(q->_head);
	q->_head = next;//q的头指向next
	--q->_size;
	if (q->_head == NULL)
		q->_tail = NULL;//只有一个节点头删后,空队列
}

QDataType queueFront(Queue *q)//获得队首元素
{
	return q->_head->_data;
}

QDataType queueRear(Queue *q)//获得队尾元素
{
	return q->_tail->_data;
}

int queueEmpty(Queue *q)
{
	return q->_head == NULL;
}

int queueSize(Queue *q)
{
	if (q == NULL)
		return 0;
	return q->_size;

}

void queueDestory(Queue *q)
{
	QNode *cur = q->_head;
	while (cur)
	{
		QNode *next = cur->_next;
		free(cur);
		cur = next;
	}
	q->_head = q->_tail = NULL;
}

void queuePrint(Queue *q)
{
	if (q == NULL || q->_head == NULL)
		return;
	QNode *cur = q->_head;
	printf("队列元素数据:");
	while (cur != NULL)
	{
		printf("%d ", cur->_data);
		cur = cur->_next;
	}printf("\n");
}

/* 利用队列实现栈 */
方法一:用一个队列实现
实现用队列构成栈
//
//MyStack *myStackCreate()
//{
//	//struct MyStack st;//这种方法有问题,因为在函数中创建的是临时变量,
//	//return &st; //函数一结束,该变量就会被销毁
//
//	//动态创建
//	MyStack *st = (MyStack*)malloc(sizeof(MyStack));
//	initQueue(&(st->q));
//	return st;
//}
//
//void myStackPush(MyStack *obj, int x)
//{
//	queuePush(&obj->q, x);
//}
//
//int myStackPop(MyStack *obj)
//{
//	int n = queueSize(&obj->q);
//	while (n > 1)
//	{//出栈是出栈顶元素,对应到队列就是最后一位元素
//		//而队列又是先进先出,所以要出最后一个元素,则需将前面的元素先排出,再放进队列
//		//从而实现栈的先进后出
//		//出队,入队
//		int front = queueFront(&obj->q);
//		queuePop(&obj->q);
//		queuePush(&obj->q, front);
//		--n;
//	}
//	int top = queueFront(&obj->q);
//	queuePop(&obj->q);
//	return top;
//}
//
//int myStackTop(MyStack *obj)
//{
//	return queueRear(&obj->q);//栈的栈顶就是队列的最后一位
//	//因为栈是先进后出,队列是先进先出,徐构成先进后出,所以
//	//栈顶就相当于队列的最后一位
//}
//
//bool myStackEmpty(MyStack *obj)
//{
//	return queueEmpty(&obj->q);
//}
//
//void myStackDestory(MyStack *obj)
//{
//	queueDestory(&obj->q);
//	free(obj);
//}
//
//int myStackSize(MyStack *obj)
//{
//	return queueSize(&obj->q);
//}
//
//void myStackPrint(MyStack *obj)
//{
//	QDataType *data = (QDataType*)malloc(sizeof(QDataType)*queueSize(&obj->q));
//	QNode *cur = obj->q._head;
//	int i = 0;
//	while (cur != NULL)
//	{
//		*(data + i) = cur->_data;
//		cur = cur->_next;
//		i++;
//	}
//	printf("栈内元素:");
//	for (i = queueSize(&obj->q) - 1; i >= 0; i--)
//		printf("%d ", *(data + i));
//	printf("\n");
//	free(data);
//}

//方法二:用二个队列实现
//实现用队列构成栈

MyStack *myStackCreate()
{
	//struct MyStack st;//这种方法有问题,因为在函数中创建的是临时变量,
	//return &st; //函数一结束,该变量就会被销毁

	//动态创建
	MyStack *st = (MyStack*)malloc(sizeof(MyStack));
	initQueue(&(st->q1));
	initQueue(&st->q2);
	return st;
}

void myStackPush(MyStack *obj, int x)
{
	//给非空队列进行入栈操作
	if (!queueEmpty(&obj->q1))
		queuePush(&obj->q1, x);
	else
		queuePush(&obj->q2, x);
}

void myStackPop(MyStack *obj)
{
	int top;
	if (!queueEmpty(&obj->q1))
	{
		int n = queueSize(&obj->q1);
		while (n > 1)
		{//出栈是出栈顶元素,对应到队列就是最后一位元素
			//而队列又是先进先出,所以要出最后一个元素,则需将前面的元素先排出,再放进队列
			//从而实现栈的先进后出
			//出队,入队
			int front = queueFront(&obj->q1);
			queuePop(&obj->q1);
			queuePush(&obj->q2, front);
			--n;
		}
		int top = queueFront(&obj->q1);
		queuePop(&obj->q1);
	}
	else
	{
		int n = queueSize(&obj->q2);
		while (n > 1)
		{//出栈是出栈顶元素,对应到队列就是最后一位元素
			//而队列又是先进先出,所以要出最后一个元素,则需将前面的元素先排出,再放进队列
			//从而实现栈的先进后出
			//出队,入队
			int front = queueFront(&obj->q2);
			queuePop(&obj->q2);
			queuePush(&obj->q1, front);
			--n;
		}
		int top = queueFront(&obj->q2);
		queuePop(&obj->q2);
	}

}

int myStackTop(MyStack *obj)
{
	if (!queueEmpty(&obj->q1))
		return queueRear(&obj->q1);
	else
		return queueRear(&obj->q2);
	//栈的栈顶就是队列的最后一位
	//因为栈是先进后出,队列是先进先出,徐构成先进后出,所以
	//栈顶就相当于队列的最后一位
}

bool myStackEmpty(MyStack *obj)
{
	return queueEmpty(&obj->q1) && queueEmpty(&obj->q2);
}

int myStackSize(MyStack *obj)
{
	return queueSize(&obj->q1) + queueSize(&obj->q2);
}

void myStackDestory(MyStack *obj)
{
	queueDestory(&obj->q1);
	queueDestory(&obj->q2);
	free(obj);
}

void myStackPrint(MyStack *obj)
{
	if (queueEmpty(&obj->q1) && queueEmpty(&obj->q2))
		return;

	if (!queueEmpty(&obj->q1))
	{
		QDataType *data = (QDataType*)malloc(sizeof(QDataType)*queueSize(&obj->q1));
		QNode *cur = obj->q1._head;
		int i = 0;
		while (cur != NULL)
		{
			*(data + i) = cur->_data;
			cur = cur->_next;
			i++;
		}
		printf("栈内元素:");
		for (i = queueSize(&obj->q1) - 1; i >= 0; i--)
			printf("%d ", *(data + i));
		printf("\n");
		free(data);
	}
	else if (!queueEmpty(&obj->q2))
	{
		QDataType *data = (QDataType*)malloc(sizeof(QDataType)*queueSize(&obj->q2));
		QNode *cur = obj->q2._head;
		int i = 0;
		while (cur != NULL)
		{
			*(data + i) = cur->_data;
			cur = cur->_next;
			i++;
		}
		printf("栈内元素:");
		for (i = queueSize(&obj->q2) - 1; i >= 0; i--)
			printf("%d ", *(data + i));
		printf("\n");
		free(data);
	}
}

void test()
{
	/* 实验队列操作 */
	printf("实验队列操作:\n");
	Queue q;
	/* 实验入队 先进先出 */
	initQueue(&q);
	queuePush(&q, 1);
	queuePush(&q, 2);
	queuePush(&q, 3);
	queuePush(&q, 4);
	queuePrint(&q);// 1 2 3 4

	/* 实验出队 */
	queuePop(&q);
	queuePrint(&q);// 2 3 4
	queuePop(&q);
	queuePrint(&q);// 3 4
	//queuePop(&q);
	//queuePrint(&q);// 4
	//queuePop(&q);
	//queuePrint(&q);// 空,因为空队列不打印

	/* 实验队头与队尾元素 */
	printf("此时队头元素为:%d \n", queueFront(&q));
	printf("此时队尾元素为:%d \n", queueRear(&q));

	/* 实验队列内元素个数 */
	printf("此时队列元素个数为:%d \n", queueSize(&q));

	/* 实验判空 */
	printf("此时队列状态(0:非空,1:空):%d \n", queueEmpty(&q));
	printf("\n");

	/* 实验上述队列建成的栈 */
	MyStack *s = myStackCreate();
	/* 实验入栈 */
	myStackPush(s, 1);
	myStackPush(s, 2);
	myStackPush(s, 3);
	myStackPush(s, 4);
	myStackPrint(s);// 4 3 2 1 

	/* 实验出栈 */
	myStackPop(s);
	myStackPrint(s);// 3 2 1
	myStackPop(s);
	myStackPrint(s);// 2 1
	//myStackPop(s);
	//myStackPrint(s);// 1
	//myStackPop(s);
	//myStackPrint(s);

	/* 实验栈顶元素 */
	printf("此时栈顶元素:%d \n", myStackTop(s));

	/* 实验栈内元素个数与判空 */
	printf("此时栈内元素个数为:%d \n", myStackSize(s));
	printf("此时栈状态(0:非空,1:空):%d \n", myStackEmpty(s));
	printf("\n");
}

int main()
{
	test();
	system("pause");
	return  0;
}

(3)运行结果
在这里插入图片描述
注意3:在程序中虽然采取了两种栈的实现方式,但两种方式下的运行结果一致,此处就不再分别配图,如上图!

以上为本篇博客内容,若有问题,欢迎与笔者交流!
侵权删~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值