队列及笔试题

队列

先进先出

使用单链表进行队尾插入 队头删除

其中带头结点直接尾插,不带头结点第一次操作要判断一下

但是带头结点需要malloc和free

函数传需要修改的参数方法

1、二级指针

2、带哨兵位的头结点

3、返回值

4、如果有多个值,用结构体封装起来

可以把头指针和尾指针放到结构体里面,就不用二级指针了。

他们是结构体成员,想要改变就可以用结构体指针

Queue.h

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>

typedef int QDataType;

typedef struct QueueNode {
	QDataType val;
	struct QueueNode* next;
}QNode;

typedef struct Queue {
	QNode* phead;
	QNode* ptail;
	int size;
}Queue;

void QInit(Queue* pq);
void QDestroy(Queue* pq);
void QPush(Queue* pq, QDataType x);
void QPop(Queue* pq);

//取队头的数据
QDataType QFront(Queue* pq);

//取队尾的数据
QDataType QBack(Queue* pq);

//判断链表是否为空
bool QEmpty(Queue* pq);

//求队长度
int QSize(Queue* pq);

Queue.c

#define  _CRT_SECURE_NO_WARNINGS
#include"Queue.h"

void QInit(Queue* pq) {
	assert(pq);

	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

void QDestroy(Queue* pq) {
	assert(pq);

	QNode* cur = pq->phead;
	while (cur) {
		pq->phead = pq->phead->next;
		free(cur);
		cur = pq->phead;
		pq->size --;
	}
	pq->ptail = NULL;
}

void QPush(Queue* pq, QDataType x) {
	assert(pq);

	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL) {
		perror("malloc");
		return;
	}
	newnode->next = NULL;
	newnode->val = x;

	if (pq->phead == NULL) {
		pq->phead = newnode;
		pq->ptail = newnode;
	}
	else {
		pq->ptail->next = newnode;
		pq->ptail = pq->ptail->next;
	}
	pq->size++;
}

void QPop(Queue* pq) {
	assert(pq);
	assert(pq->phead);

	QNode* del = pq->phead;
	pq->phead = pq->phead->next;
	free(del);
	del = NULL;

	if (pq->phead == NULL) {
		pq->ptail = NULL;
	}
	pq->size--;
}

//取队头的数据
QDataType QFront(Queue* pq) {
	assert(pq);
	assert(pq->phead);

	return pq->phead->val;
}

//取队尾的数据
QDataType QBack(Queue* pq) {
	assert(pq);
	assert(pq->phead);

	return pq->ptail->val;
}

//判断链表是否为空
bool QEmpty(Queue* pq) {
	assert(pq);

	return pq->phead == NULL;
}

//求队长度
int QSize(Queue* pq) {
	assert(pq);

	return pq->size;
}

Test.c

#define  _CRT_SECURE_NO_WARNINGS
#include"Queue.h"

int main() {
	Queue q;
	QInit(&q);
	QPush(&q, 1);
	QPush(&q, 2);
	QPush(&q, 3);
	QPush(&q, 4);
	QPush(&q, 5);

	int size = QSize(&q);
	printf("%d\n", size);

	while (!QEmpty(&q)) {
		printf("%d ", QFront(&q));
		QPop(&q);
	}
	printf("\n");

	size = QSize(&q);
	printf("%d\n", size);

	QDestroy(&q);
}

练习:

用队列实现栈

这里有typedef,MyStack就是类型

没有typedef,MyStack就是变量,且这个结构体只能创建这一个变量

思路:

空的队列用来出仅存的那一个数据

满的队列用来存剩下的全部数据

如果直接free(obj),则相当于只free了这个结构体,但是链表里可能还有数据,所以要先分别Destroy一下

用栈实现队列

思路:

1、建立两个栈,一个用来存放数据(pushst),一个用来改变成正确的顺序然后出栈(popst)

      等popst出空了再倒过来数据,效率更高

2、凡是看到这样一个返回值,都需要malloc,否则只是创建了局部变量,出了作用域就被销毁了

3、此处可以手动初始化栈,也可以调用之前写好的完整的一套函数去初始化(推荐)

访问结构体里的变量用 . 

4、内部实现

STInit需要传的是栈的地址,对栈进行操作

5、结构体 和 结构体的指针 是有区别的,结构体的指针只是一个地址。

如果定义结构体时定义成了上面这样

则相当于malloc了pushst和popst这两个指针,但是这两个指针没有具体只的内容和空间,如果没有初始化就是野指针。同时还需要malloc栈的空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值