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;
}

得到

相关推荐
Zwawa3 小时前
C语言函数指针与宏实战:从回调、表驱动菜单到X-Macro,讲透嵌入式代码解耦
c语言·单片机·嵌入式
David猪大卫6 小时前
【C++修炼】map 和 set 的使用
c语言·开发语言·数据结构·c++·经验分享·笔记·学习
HPtiger6 小时前
C++ 入门笔记:从 C 到 C++ 的核心过渡(命名空间、输入输出、缺省参数、重载、引用、内联)
c语言·c++·学习
fengci.7 小时前
CTF2MISC中等部分
开发语言·前端·学习
xys_6789 小时前
JavaEE通关手册:初识Java
java·开发语言
安妮细水长流10 小时前
ad7124
c语言·单片机
ShineWinsu10 小时前
对于Qt:QTableWidget常见属性以及QTableWidgetItem类的解析
开发语言·c++·qt·gui·客户端·表格·qtablewidget
ShineWinsu11 小时前
对于Qt:QListWidget常见属性以及QListWidgetItem类的解析
开发语言·c++·qt·客户端·列表·qlistwidget·qlistwidgetitem
吴名氏.11 小时前
Java转AI Agent教程(第十二周)检索与切分
java·开发语言·人工智能·ai·ai agent
瑞雪兆丰年兮12 小时前
JavaWeb-day10-SpringBootWeb案例
java·开发语言·javaweb·web