数据结构 C 代码 链队列&循环队列

 学习目标:学会熟悉操作队列

学习指导:帆神的代码

学习任务:

  1. 抄写代码
  2. 学习成果目录

    1链式队列

    1.1全部代码

    1.2测试结果

    1.3图解队列

     2循环队列

    2.1全部代码

    2.2测试结果

    2.3图解循环队列

代码说明:

        队列链表

  1. 运行过程中,哪些变量分配在相邻的空间?全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
  2. 局部变量的空间能否重复利用?举例说明。可以,循环链表就是。
  3. 指针的地址和值的区别是什么?传递指针指针所指的不容不会被改变,而传递地址则该地址的内容会被改变
  4. 队列的提出, 也是想获得 O(1) 的时间复杂。

    循环队列

  5. 整除的作用.(循环的必要操作)
  6. 想像操场跑道里放一队人, 循环的感觉就出来了.
  7. 为了区分空队列与满队列, 需要留一个空间. 相当于不允许首尾相连. 还是画个图吧, 否则容易进坑.
  8. 用链式结构, 空间的分配与回收由系统做, 用循环队列, 则是自己把控. 想像自己写的是操作系统, 从这个代码可以感受下内存的管理.

学习时间:

2022.5.6

1链式队列

1.1全部代码

#include <stdio.h>
#include <malloc.h>

/**
 * 链队列的节点.
 */
typedef struct LinkNode {
	int data;
	struct LinkNode* next;
}*LinkNodePtr, LinkNode;

/**
 * 链队列.
 */
typedef struct LinkQueue {
	LinkNodePtr front;
	LinkNodePtr rear;
}*LinkQueuePtr, LinkQueue;

/**
 * @brief 初始化队列
 *
 * @return 队列头节点
 */
LinkQueuePtr initQueue() {
	//申请队列
	LinkQueuePtr resultPtr = (LinkQueuePtr)malloc(sizeof(LinkQueue));
	//申请头节点
	LinkNodePtr headerPtr = (LinkNodePtr)malloc(sizeof(LinkNodePtr));
	headerPtr->next = NULL;

	resultPtr->front = headerPtr;
	resultPtr->rear = headerPtr;
	return resultPtr;
}

/**
 * @brief 输出队列
 *
 * @param paraQueuePtr
 */
void outputLinkQueue(LinkQueuePtr paraQueuePtr) {
	LinkNodePtr tempPtr = paraQueuePtr->front->next;
	while (tempPtr != NULL) {
		printf("%d ", tempPtr->data);
		tempPtr = tempPtr->next;
	}
	printf("\n");
}

/**
 * @brief 入队
 *
 * @param paraElement
 * @param paraQueuePtr
 */
void enqueue(LinkQueuePtr paraQueuePtr, int paraElement) {
	//1申请新的节点
	LinkNodePtr tempNodePtr = (LinkNodePtr)malloc(sizeof(struct LinkNode));
	tempNodePtr->data = paraElement;
	tempNodePtr->next = NULL;

	//2加入队列
	paraQueuePtr->rear->next = tempNodePtr;

	//3重置队尾
	paraQueuePtr->rear = tempNodePtr;
	printf("%d 入队\n",paraElement);
}

/**
 * @brief 出队
 *
 * @param paraQueuePtr
 *
 * @return 出队的数据值
 */
int dequeue(LinkQueuePtr paraQueuePtr) {
	int resultValue;
	LinkNodePtr tempNodePtr;

	//1判断队列是否为空
	if (paraQueuePtr->front == paraQueuePtr->rear) {
		printf("出队失败,队列为空.\n");
		return -1;
	}

	//2改变队列
	tempNodePtr = paraQueuePtr->front->next;
	resultValue = tempNodePtr->data;
	paraQueuePtr->front->next = paraQueuePtr->front->next->next;

	if (paraQueuePtr->rear == tempNodePtr) {
		paraQueuePtr->rear = paraQueuePtr->front;
	}

	//3释放出队的节点资源
	free(tempNodePtr);
	tempNodePtr = NULL;

	//4返回出队值
	return resultValue;
}

/**
 * @brief 单元测试
 */
void testLinkQueue() {
	printf("---- testLinkQueue 测试开始 ----\n");
	LinkQueuePtr tempQueuePtr;
	tempQueuePtr = initQueue();
	enqueue(tempQueuePtr, 10);
	enqueue(tempQueuePtr, 30);
	enqueue(tempQueuePtr, 50);

	printf("入队后队列为:\n");
	outputLinkQueue(tempQueuePtr);

	printf("出队 得到 %d\n", dequeue(tempQueuePtr));
	printf("出队 得到 %d\n", dequeue(tempQueuePtr));
	printf("出队 得到 %d\n", dequeue(tempQueuePtr));
	printf("出队 得到 %d\n", dequeue(tempQueuePtr));

	enqueue(tempQueuePtr, 8);
	printf("入队后队列为:\n");
	outputLinkQueue(tempQueuePtr);
	printf("\n---- testLinkQueue 测试结束 ----\n");
}

/**
 * @brief 主函数
 *
 * @return
 */
int main() {
	testLinkQueue();
	return 1;
}

1.2测试结果

---- testLinkQueue 测试开始 ----
10 入队
30 入队
50 入队
入队后队列为:
10 30 50
出队 得到 10
出队 得到 30
出队 得到 50
出队失败,队列为空.
出队 得到 -1
8 入队
入队后队列为:
8

---- testLinkQueue 测试结束 ----

1.3图解队列

 2循环队列

2.1全部代码

#include <stdio.h>
#include <malloc.h>

#define TOTAL_SPACE 5

typedef struct CircleIntQueue{
	int data[TOTAL_SPACE];
	
	int head;
	
	int tail;
}*CircleIntQueuePtr;

/**
 * @brief 初始化队列
 * 
 * @return 
 */
CircleIntQueuePtr initQueue() {
	CircleIntQueuePtr resultPtr = (CircleIntQueuePtr)malloc(sizeof(struct CircleIntQueue));
	resultPtr->head = 0;
	resultPtr->tail = 0;
	
	return resultPtr;
}

/**
 * @brief 入队
 * 
 * @param paraPtr 
 * @param paraValue 
 */
void enqueue(CircleIntQueuePtr paraPtr, int paraValue) {
	if ((paraPtr->tail + 1) % TOTAL_SPACE == paraPtr->head) {
		printf("入队失败,队满.\n");
		return;
	}
	
	paraPtr->data[paraPtr->tail % TOTAL_SPACE] = paraValue;
	paraPtr->tail++;
}

/**
 * @brief 出队
 * 
 * @param paraPtr 
 * 
 * @return 
 */
int dequeue(CircleIntQueuePtr paraPtr) {
	int resultValue;
	if (paraPtr->head == paraPtr->tail) {
		printf("出队失败,队空.\r\n");
		return -1;
	}
	
	resultValue = paraPtr->data[paraPtr->head % TOTAL_SPACE];
	paraPtr->head++;
	
	return resultValue;
}

/**
 * @brief 打印队列
 * 
 * @param paraPtr 
 */
void outputLinkQueue(CircleIntQueuePtr paraPtr){
	int i;
	if (paraPtr->head == paraPtr->tail) {
		printf("打印队列失败,队空");
		return;
	}
	
	printf("队中元素有: ");
	for (i = paraPtr->head; i < paraPtr->tail; i++) {
		printf("%d ", paraPtr->data[i % TOTAL_SPACE]);
	}
	
	printf("\n");
}

/**
 * @brief 单元测试
 */
void testLinkQueue(){
	printf("---- testLinkQueue 测试开始 ----\n");
	int i = 10;
	CircleIntQueuePtr tempPtr = initQueue();
	for (; i < 16; i ++) {
		enqueue(tempPtr, i);
	}
	
	outputLinkQueue(tempPtr);
	
	for (i = 0; i < 6; i ++) {
		int flag=dequeue(tempPtr);
		if(flag==-1){
			break;
		}else printf("出队 得到%d\n", flag);
	}
	
	enqueue(tempPtr, 8);
	outputLinkQueue(tempPtr);
	printf("---- testLinkQueue 测试结束 ----\n");
}

int main(){
	testLinkQueue();
	return 1;
}

2.2测试结果

---- testLinkQueue 测试开始 ----
入队失败,队满.
入队失败,队满.
队中元素有: 10 11 12 13
出队 得到10
出队 得到11
出队 得到12
出队 得到13
出队失败,队空.
队中元素有: 8
---- testLinkQueue 测试结束 ----

2.3图解循环队列

猜你喜欢

转载自blog.csdn.net/qq_61649579/article/details/124807701