C语言用双向链表实现单调递减(递增)队列

参考代码

c 复制代码
#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
	int num;
	int index;
	struct Node* prev;
	struct Node* next;
}Node;

typedef struct MonoDeQueue {
	int size;
	Node* begin;
	Node* end;
}MonoDeQueue;

void Enqueue(MonoDeQueue* q, int value, int index)
{
	Node* node = (Node*)malloc(sizeof(Node));
	node->num = value;
	node->index = index;
	node->prev = NULL;
	node->next = NULL;

	if (q->size == 0) {
		q->begin = node;
		q->end = node;
		q->size++;
		return;
	}

	Node* cur = q->end;
	Node* temp = NULL;
	//只需将循环条件改为下面的条件,即可实现单调递增队列
	// while (cur && cur->num >= value) {
	while (cur && cur->num <= value) {
		if (q->size == 1) {
			free(cur);
			q->begin = NULL;
			q->end = NULL;
			q->size = 0;
			cur = NULL;
			break;
		}

		temp = cur->prev;
		free(cur);
		cur = temp;
		q->size--;
	}
	
	if (cur) {
        cur->next = NULL;
        q->end = cur;
    }

	if (q->size == 0) {
		q->begin = node;
		q->end = node;
	}
	else {
		q->end->next = node;
		node->prev = q->end;
		q->end = node;
	}
	q->size++;
}

void Dequeue(MonoDeQueue* q)
{
	if (q->size == 0) {
		return;
	}

	if (q->size == 1) {
		free(q->begin);
		q->begin = NULL;
		q->end = NULL;
		q->size = 0;
		return;
	}

	Node* temp = q->begin->next;
	free(q->begin);
	q->begin = temp;
	q->begin->prev = NULL;
	q->size--;

}
void freequeue(MonoDeQueue* q)
{
	if (q->size == 0) {
		return;
	}

	Node* cur = q->begin;
	Node* temp = NULL;
	while (cur) {
		temp = cur->next;
		free(cur);
		cur = temp;
	}
	q->begin = NULL;
	q->end = NULL;
	q->size = 0;
}

void iterator(MonoDeQueue* q)
{
	if (q->size == 0) {
		printf_s("The MonoDeQueue is now empty!!!\r\n");
		return;
	}

	Node* cur = q->begin;
	while (cur) {
		printf_s("%d ", cur->num);
		cur = cur->next;
	}
	printf_s("\r\n");
}

int main()
{
	int num[] = { 5,4,3,2,1,7 };
	MonoDeQueue q = { 0, NULL, NULL };
	for (int i = 0; i < sizeof(num)/sizeof(num[0]); ++i) {
		Enqueue(&q, num[i]);
	}
	iterator(&q);
	clear(&q);
	iterator(&q);
	return 0;
}

运行结果

利用上述实现的单调递减队列求解Leetcode 239. 滑动窗口最大值

c 复制代码
int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize) {
    int size = numsSize - k + 1;
    int index = 0;
    int* result = (int*)malloc(sizeof(int) * size);

    MonoDeQueue q = {0, NULL, NULL,};
    for(int i = 0; i < k; i++){
        Enqueue(&q, nums[i], i);
    }
    result[index++] = q.begin->num;

    for(int i = k; i < numsSize; i++){
        if(q.begin->index == i - k){
            Dequeue(&q);
        }
        Enqueue(&q, nums[i], i);
        result[index++] = q.begin->num;
    }

    freequeue(&q);

    *returnSize = size;
    return result;
}

得到

相关推荐
chuan.bai2 小时前
Java RAG 实战(第 11 篇):RAG 知识工作台网页
java·开发语言·人工智能
离陌在学C#4 小时前
C# 事件(Event)详解:从概念到实战
开发语言·c#
Terra.K5 小时前
Java异常学习[特殊字符]
java·开发语言·学习
葡萄城技术团队6 小时前
InfluxDB 2\.x 深度解析:核心架构、Flux 函数与制造业落地指南(三)
java·开发语言·架构
counting money6 小时前
Java IO流详解:从InputStream到文件操作实战
java·开发语言·python
wuyk5557 小时前
98.C语言易混难点:字符数组与字符串指针的底层差异
c语言·开发语言·c++·stm32·嵌入式硬件·算法
峥无7 小时前
从0到1手撕红黑树:封装实现 my_map 与 my_set(SGI-STL 源码级深度解析)
开发语言·c++·笔记·算法·stl
波特率1152007 小时前
C++新特性---属性说明符与标准属性
开发语言·c++
程序员小八7777 小时前
上海百度B端java后端日常实习一面
java·开发语言
wp123_17 小时前
IPX8 防水 Type‑C连接器:安费诺 124018792112A 与 TONEVEE TY48087‑24A 技术梳理
c语言·开发语言