Priority Queue实现栈和队列

在排序算法中,堆排序利用了完全二叉树形式的堆结构,结合了插入排序与合并排序的优点,能够以 O ( n log ⁡ n ) O(n\log{n}) O(nlogn)的时间完成排序。优先级队列是可基于堆结构进行实现的一种数据结构,在计算机系统中可以用来记录不同作业的相对优先级关系,从而进行作业调度。本文将介绍什么是优先级队列,以及使用优先级队列实现栈和队列的C语言算法。

1. 什么是优先级队列

优先级队列(Priority Queue)是一个具有有限元素的线性结构,其中每个元素都有一个数值key标识其优先级。优先级队列又可分为最大优先级队列最小优先级队列

1.1 最大优先级队列

一个最大优先级队列支持以下操作:

  • INSERT(S, x):把元素x插入集合S中;
  • MAXIMUM(S):返回集合S中具有最大优先级的元素;
  • EXTRACT-MAX(S):去掉并返回S中具有最大优先级的元素;
  • INCREASE-KEY(S, x, k):将元素x的优先级增加到k,这里假设k值不能小于x的原始关键字的值。

1.2 最小优先级队列

一个最小优先级队列支持以下操作:

  • INSERT(S, x):把元素x插入集合S中;
  • MINIMUM(S):返回集合S中具有最小优先级的元素;
  • EXTRACT-MIN(S):去掉并返回S中具有最小优先级的元素;
  • DECREASE-KEY(S, x, k):将元素x的优先级减小到k,这里假设k值不能大于x的原始关键字的值。

可以发现最大优先级队列与最小优先级队列的区别仅在于后三个操作针对的元素优先级不同。

2. 设计思路

在具体底层实现上,最大优先级队列可用大顶堆实现,最小优先级队列可用小顶堆实现。以大顶堆为例,它支持以下操作:

  • MAX-HEAPIFY:运行时间为 O ( log ⁡ n ) O(\log{n}) O(logn),保持最大堆性质;
  • BUILD-MAX-HEAP:以线性时间运行,将无序的输入数组转换为最大堆;
  • MAX-HEAP-INSERT, HEAP-EXTRACT-MAX, HEAP-INCREASE-KEYHEAP-MAXIMUM过程的运算时间为 O ( log ⁡ n ) O(\log{n}) O(logn) , 可以让堆结构作为优先队列使用。

小顶堆支持操作类似。在使用最大优先级队列实现栈和队列过程中,我将元素入栈(或队)的序号作为元素的优先级。在使用最小优先级队列实现队列的过程中,我将元素入队的序号的相反数作为元素的优先级。具体代码可见第3节。

3. 程序代码

以下C语言程序代码分别实现了:

  • 最大优先队列实现后进先出栈(进栈元素优先级递增),见stack.cpp
  • 最小优先队列实现先进先出队列(进队元素优先级递增),见queue_min_priority.cpp
  • 最大优先队列实现先进先出队列(进队元素优先级递减),见queue_max_priority.cpp

3.1 最大优先队列实现栈

stack.cpp代码如下,在stack.cpp中首先构建最大堆,实现最大优先队列,然后利用最大优先队列实现栈。

#include <stdio.h>
#include <stdlib.h>

#define MIN -1000000  //定义最小的优先级 

//最大优先级队列实现后进先出栈:1.利用最大堆实现最大优先队列,2.利用最大优先队列实现栈,进栈的元素优先级递增 
typedef struct Node {
    int elem;    //储存栈中的元素值 
    int key;     //为每一个进栈的元素赋一个优先级值 
} Node;

typedef struct Stack {
	int length;  //栈的长度 
	Node *data;  //栈中的元素 
} Stack;

/*************************************Part1.利用最大堆实现最大优先队列*************************************/ 
void swap(Node *a, Node *b) { //交换元素a与元素b 
	Node tmp;
	tmp.elem = (*a).elem;
	tmp.key = (*a).key;
	(*a).elem = (*b).elem;
	(*a).key = (*b).key;
	(*b).elem = tmp.elem;
	(*b).key = tmp.key;
}

void max_heapify(Node *a, int size, int i) { //使元素的优先级满足最大堆的性质 
    int left = 2 * i;         //i的左孩子 
    int right = 2 * i + 1;    //i的右孩子 
    int largest;              //选出具有最大优先级的元素,下标存在largest中 
    if (left <= size && a[left].key > a[i].key) {
    	largest = left;
	}
    else {
    	largest = i;
	}    
    if (right <= size && a[right].key > a[largest].key) {
    	largest = right;
	}
    if (largest != i) { //具有最大优先级的元素是i的某个孩子结点 
    	swap(&a[i], &a[largest]);
    	max_heapify(a, size, largest); //递归调用 
	}
}

void build_max_heap(Node *a, int size) { //构建最大堆 
    int i;
    for(i = size / 2; i >= 1; i--) {
    	max_heapify(a, size, i);
	}     
}

Node heap_maximum(Node *a) { //返回最大优先级队列中优先级最大的元素,即最大堆的顶 
	return a[1];
}

void heap_increase_key(Node *a, int i, int key) { //将元素a[i]的优先级增加到 key 
	if (key < a[i].key) {
		printf("New key is smaller than current key!(Error from heap_increase_key)\n");
		exit(0);
	}
	a[i].key = key;
	while (i > 1 && a[i / 2].key < a[i].key) {
		swap(&a[i], &a[i / 2]);
		i = i / 2;
	}
}

Node heap_extract_max(Node *a, int *size) { //去掉并返回最大优先队列中具有最大优先级的元素 
	if (*size < 1) {
		printf("Heap underflow!(Error from heap_extract_max)\n");
		exit(-1);
	}
    Node max = a[1];
	a[1] = a[*size];
	(*size)--;
    max_heapify(a, *size, 1);
    return max;
}

void max_heap_insert(Node *a, int *size, int key, int elem) { //向最大优先队列中插入元素,即扩展最大堆 
	(*size)++;
	a[*size].key = MIN;
	a[*size].elem = elem;
	heap_increase_key(a, *size, key);
}
/************************************************Part1 ends************************************************/

/*************************************Part2.利用最大优先队列实现栈操作*************************************/
bool is_stack_empty(Stack *s) { //判断栈是否为空 
	if ((*s).length == 0) return true;
	return false;
}

void stack_push(Stack *s, int elem) { //入栈 
	Node *old = (*s).data;
	(*s).data = (Node *)malloc(((*s).length + 2) * sizeof(Node)); //开创新的空间 
	int i;
	for (i = 1; i <= (*s).length; i++) {
		(*s).data[i] = old[i];
	}
	free(old); //释放旧的空间 
	max_heap_insert(s->data, &s->length, s->length + 1, elem);
}

int stack_getTop(Stack *s) { //获取栈顶元素 
	return heap_maximum(s->data).elem;
}

int stack_pop(Stack *s) { //出栈 
	return heap_extract_max(s->data, &s->length).elem;
}

int main() {
    Stack s;
    printf("Input the length of the stack:\n");
    scanf("%d", &s.length);
	s.data = (Node *)malloc((s.length + 1) * sizeof(Node));
    printf("Input the element:\n");
    int i;
    for(i = 1; i <= s.length; i++){
        s.data[i].key = i;
        scanf("%d", &s.data[i].elem);
    }
    printf("Build the heap for the stack!\n");
    build_max_heap(s.data, s.length);
    printf("The result of the heap:\n");
    for(i = 1; i <= s.length; i++)
        printf("%d(Priority:%d) ", s.data[i].elem, s.data[i].key);
    printf("\n");

    int push_elem;
    printf("Input the element you want to push into the stack:\n");
    scanf("%d", &push_elem);
	stack_push(&s, push_elem);

	printf("Now the top of the stack is: %d\n", stack_getTop(&s));

	printf("Output the stack:\n");
	while (!is_stack_empty(&s)) {
		printf("pop: %d\n", stack_pop(&s));
	}
    return 0;
}

3.2 最小优先队列实现队列

queue_min_priority.cpp中首先构建最小堆,实现最小优先队列,然后利用最小优先队列实现队列,代码如下:

#include <stdio.h>
#include <stdlib.h>

#define MAX 1000000  //定义最大的优先级 

//最小优先级队列实现先进先出队列:1.利用最小堆实现最小优先队列,2.利用最小优先队列实现队列,进队的元素优先级递增 
typedef struct Node {
    int elem;    //储存队列中的元素值 
    int key;     //为每一个进队的元素赋一个优先级值 
} Node;

typedef struct Queue {
	int length;  //队列的长度 
	Node *data;  //队列中的元素 
} Queue;

/*************************************Part1.利用最小堆实现最小优先队列*************************************/ 
void swap(Node *a, Node *b) { //交换元素a与元素b 
	Node tmp;
	tmp.elem = (*a).elem;
	tmp.key = (*a).key;
	(*a).elem = (*b).elem;
	(*a).key = (*b).key;
	(*b).elem = tmp.elem;
	(*b).key = tmp.key;
}

void min_heapify(Node *a, int size, int i) { //使元素的优先级满足最小堆的性质 
    int left = 2 * i;         //i的左孩子 
    int right = 2 * i + 1;    //i的右孩子 
    int smallest;              //选出具有最小优先级的元素,下标存在smallest中 
    if (left <= size && a[left].key < a[i].key) {
    	smallest = left;
	}
    else {
    	smallest = i;
	}    
    if (right <= size && a[right].key < a[smallest].key) {
    	smallest = right;
	}
    if (smallest != i) { //具有最小优先级的元素是i的某个孩子结点 
    	swap(&a[i], &a[smallest]);
    	min_heapify(a, size, smallest); //递归调用 
	}
}

void build_min_heap(Node *a, int size) { //构建最小堆 
    int i;
    for(i = size / 2; i >= 1; i--) {
    	min_heapify(a, size, i);
	}     
}

Node heap_minimum(Node *a) { //返回最小优先级队列中优先级最小的元素,即最小堆的顶 
	return a[1];
}

void heap_decrease_key(Node *a, int i, int key) { //将元素a[i]的优先级减少到 key 
	if (key > a[i].key) {
		printf("New key is larger than current key!(Error from heap_decrease_key)\n");
		exit(0);
	}
	a[i].key = key;
	while (i > 1 && a[i / 2].key > a[i].key) {
		swap(&a[i], &a[i / 2]);
		i = i / 2;
	}
}

Node heap_extract_min(Node *a, int *size) { //去掉并返回最小优先队列中具有最小优先级的元素 
	if (*size < 1) {
		printf("Heap underflow!(Error from heap_extract_min)\n");
		exit(-1);
	}
    Node min = a[1];
	a[1] = a[*size];
	(*size)--;
    min_heapify(a, *size, 1);
    return min;
}

void min_heap_insert(Node *a, int *size, int key, int elem) { //向最小优先队列中插入元素,即扩展最小堆 
	(*size)++;
	a[*size].key = MAX;
	a[*size].elem = elem;
	heap_decrease_key(a, *size, key);
}
/************************************************Part1 ends************************************************/

/************************************Part2.利用最小优先队列实现队列操作************************************/
bool is_queue_empty(Queue *q) { //判断队列是否为空 
	if ((*q).length == 0) return true;
	return false;
}

void queue_push(Queue *q, int elem) { //入队 
	Node *old = (*q).data;
	(*q).data = (Node *)malloc(((*q).length + 2) * sizeof(Node)); //开创新的空间 
	int i;
	for (i = 1; i <= (*q).length; i++) {
		(*q).data[i] = old[i];
	}
	free(old); //释放旧的空间 
	min_heap_insert(q->data, &q->length, q->length + 1, elem);
}

int queue_getHead(Queue *q) { //获取队首元素 
	return heap_minimum(q->data).elem;
}

int queue_pop(Queue *q) { //出队 
	return heap_extract_min(q->data, &q->length).elem;
}

int main() {
    Queue q;
    printf("Input the length of the queue:\n");
    scanf("%d", &q.length);
	q.data = (Node *)malloc((q.length + 1) * sizeof(Node));
    printf("Input the element:\n");
    int i;
    for(i = 1; i <= q.length; i++){
        q.data[i].key = i;
        scanf("%d", &q.data[i].elem);
    }
    printf("Build the heap for the Queue!\n");
    build_min_heap(q.data, q.length);
    printf("The result of the heap:\n");
    for(i = 1; i <= q.length; i++)
        printf("%d(Priority:%d) ", q.data[i].elem, q.data[i].key);
    printf("\n");
    
    int push_elem;
    printf("Input the element you want to push into the queue:\n");
    scanf("%d", &push_elem);
	queue_push(&q, push_elem);

	printf("Now the head of the queue is: %d\n", queue_getHead(&q));

	printf("Output the queue:\n");
	while (!is_queue_empty(&q)) {
		printf("pop: %d\n", queue_pop(&q));
	}
    return 0;
}

3.3 最大优先队列实现队列

queue_max_priority.cpp实现过程同stack.cpp,只是优先级不同,代码如下:

#include <stdio.h>
#include <stdlib.h>

#define MIN -1000000  //定义最小的优先级 

//最大优先级队列实现先进先出队列:1.利用最大堆实现最大优先队列,2.利用最大优先队列实现队列,进队的元素优先级递减 
typedef struct Node {
    int elem;    //储存队列中的元素值 
    int key;     //为每一个进队的元素赋一个优先级值 
} Node;

typedef struct Queue {
	int length;  //队列的长度 
	Node *data;  //队列中的元素 
} Queue;

/*************************************Part1.利用最大堆实现最大优先队列*************************************/ 
void swap(Node *a, Node *b) { //交换元素a与元素b 
	Node tmp;
	tmp.elem = (*a).elem;
	tmp.key = (*a).key;
	(*a).elem = (*b).elem;
	(*a).key = (*b).key;
	(*b).elem = tmp.elem;
	(*b).key = tmp.key;
}

void max_heapify(Node *a, int size, int i) { //使元素的优先级满足最大堆的性质 
    int left = 2 * i;         //i的左孩子 
    int right = 2 * i + 1;    //i的右孩子 
    int largest;              //选出具有最大优先级的元素,下标存在largest中 
    if (left <= size && a[left].key > a[i].key) {
    	largest = left;
	}
    else {
    	largest = i;
	}    
    if (right <= size && a[right].key > a[largest].key) {
    	largest = right;
	}
    if (largest != i) { //具有最大优先级的元素是i的某个孩子结点 
    	swap(&a[i], &a[largest]);
    	max_heapify(a, size, largest); //递归调用 
	}
}

void build_max_heap(Node *a, int size) { //构建最大堆 
    int i;
    for(i = size / 2; i >= 1; i--) {
    	max_heapify(a, size, i);
	}     
}

Node heap_maximum(Node *a) { //返回最大优先级队列中优先级最大的元素,即最大堆的顶 
	return a[1];
}

void heap_increase_key(Node *a, int i, int key) { //将元素a[i]的优先级增加到 key 
	if (key < a[i].key) {
		printf("New key is smaller than current key!(Error from heap_increase_key)\n");
		exit(0);
	}
	a[i].key = key;
	while (i > 1 && a[i / 2].key < a[i].key) {
		swap(&a[i], &a[i / 2]);
		i = i / 2;
	}
}

Node heap_extract_max(Node *a, int *size) { //去掉并返回最大优先队列中具有最大优先级的元素 
	if (*size < 1) {
		printf("Heap underflow!(Error from heap_extract_max)\n");
		exit(-1);
	}
    Node max = a[1];
	a[1] = a[*size];
	(*size)--;
    max_heapify(a, *size, 1);
    return max;
}

void max_heap_insert(Node *a, int *size, int key, int elem) { //向最大优先队列中插入元素,即扩展最大堆 
	(*size)++;
	a[*size].key = MIN;
	a[*size].elem = elem;
	heap_increase_key(a, *size, key);
}
/************************************************Part1 ends************************************************/

/************************************Part2.利用最大优先队列实现队列操作************************************/
bool is_queue_empty(Queue *q) { //判断队列是否为空 
	if ((*q).length == 0) return true;
	return false;
}

void queue_push(Queue *q, int elem) { //入队 
	Node *old = (*q).data;
	(*q).data = (Node *)malloc(((*q).length + 2) * sizeof(Node)); //开创新的空间 
	int i;
	for (i = 1; i <= (*q).length; i++) {
		(*q).data[i] = old[i];
	}
	free(old); //释放旧的空间 
	max_heap_insert(q->data, &q->length, -1 * (q->length + 1), elem);
}

int queue_getHead(Queue *q) { //获取队首元素 
	return heap_maximum(q->data).elem;
}

int queue_pop(Queue *q) { //出队 
	return heap_extract_max(q->data, &q->length).elem;
}

int main() {
    Queue q;
    printf("Input the length of the queue:\n");
    scanf("%d", &q.length);
	q.data = (Node *)malloc((q.length + 1) * sizeof(Node));
    printf("Input the element:\n");
    int i;
    for(i = 1; i <= q.length; i++){
        q.data[i].key = (-1) * i;
        scanf("%d", &q.data[i].elem);
    }
    printf("Build the heap for the Queue!\n");
    build_max_heap(q.data, q.length);
    printf("The result of the heap:\n");
    for(i = 1; i <= q.length; i++)
        printf("%d(Priority:%d) ", q.data[i].elem, q.data[i].key);
    printf("\n");

    int push_elem;
    printf("Input the element you want to push into the queue:\n");
    scanf("%d", &push_elem);
	queue_push(&q, push_elem);

	printf("Now the top of the queue is: %d\n", queue_getHead(&q));

	printf("Output the queue:\n");
	while (!is_queue_empty(&q)) {
		printf("pop: %d\n", queue_pop(&q));
	}
    return 0;
}

4. 运行结果

4.1 stack.cpp

  1. 首先用户需要输入stack的长度,然后为其输入栈中的元素。程序会给出栈中元素按优先级构造的最大堆结果。
  2. 之后程序会提示用户再次输入一个想要入栈的元素,按下回车,程序输出现在的栈顶元素,并将栈中的所有元素弹出。
    在这里插入图片描述

4.2 queue_min_priority.cpp

  1. 首先用户需要输入队列的长度,然后为其输入队列中的元素。程序会给出队列中元素按优先级构造的最小堆结果。
  2. 之后程序会提示用户再次输入一个想要入队的元素,按下回车,程序输出现在的队首元素,并将队列中的所有元素弹出。
    在这里插入图片描述

4.3 queue_max_priority.cpp

  1. 首先用户需要输入队列的长度,然后为其输入队列中的元素。程序会给出队列中元素按优先级构造的最大堆结果。
  2. 之后程序会提示用户再次输入一个想要入队的元素,按下回车,程序输出现在的队首元素,并将队列中的所有元素弹出。
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/484729.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【现代C++】可变参数模板

现代C中的可变参数模板是C11引入的一个功能&#xff0c;允许模板接受可变数量的参数&#xff0c;使得模板编程更加灵活和强大。 1. 基本用法 可变参数模板允许您创建接受任意数量参数的函数或类模板。 template<typename... Args> void func(Args... args) {// 处理参…

C++ 基本运算

何谓运算符和操作数 基本运算 1、双目运算 2、单目运算 3、赋值表达式 表达形式&#xff1a; <变量><表达式>; 表达式是指各种运算符把常量、变量&#xff0c;函数等运算对象连接起来的具有实际意义并符合C语法规则的式子。赋值是指表达式的值赋给一个变量。 …

基于SSM的NEUQ宿舍管理系统的设计与实现

基于SSM的NEUQ宿舍管理系统的设计与实现 获取源码——》公主号&#xff1a;计算机专业毕设大全 获取源码——》公主号&#xff1a;计算机专业毕设大全

LabVIEW电动汽车直流充电桩监控系统

LabVIEW电动汽车直流充电桩监控系统 随着电动汽车的普及&#xff0c;充电桩的安全运行成为重要议题。通过集成传感器监测、单片机技术与LabVIEW开发平台&#xff0c;设计了一套电动汽车直流充电桩监控系统&#xff0c;能实时监测充电桩的温度、电压和电流&#xff0c;并进行数…

PMP适合哪些人?考试PMP有什么职业要求吗?

威班PMP 3A路过拿证学员 。PMP认证没听说过有啥职业的要求&#xff0c;也没听说过限制在哪些行业可用&#xff0c;根据我考后经验所了解&#xff0c;它并不只作用在某一个领域&#xff0c;知识点也是项目管理相关的工作都能用到&#xff0c;毕竟这些都是通用的专业实践。如果非…

linux命令学习——sort

sort可以对文本文件进行“排序”&#xff0c;比如-n可以对文本&#xff0c;按照首行字母数字顺序排序 -r参数可以对排序结果进行反转 -u参数可以对查看结果去重

3.18_C++_day6_作业

作业要求&#xff1a; 程序代码&#xff1a; #include <iostream>using namespace std;class Animal { private:string name;string color;int *age; public://无参构造函数Animal(){cout << "Animal::无参构造函数" << endl;}//有参构造函数Anim…

基于深度学习的生活垃圾智能分类系统(微信小程序+YOLOv5+训练数据集+开题报告+中期检查+论文)

摘要 本文基于Python技术&#xff0c;搭建了YOLOv5s深度学习模型&#xff0c;并基于该模型研发了微信小程序的垃圾分类应用系统。本项目的主要工作如下&#xff1a; &#xff08;1&#xff09;调研了移动端垃圾分类应用软件动态&#xff0c;并分析其优劣势&#xff1b;…

附近最小 单调队列 滑动窗口 蓝桥杯

q[t]i 的执行过程如下&#xff1a; 首先&#xff0c;t 的值会先自增 1。然后&#xff0c;新值 i 被赋给 q[t]&#xff0c;即元素 i 被插入到数组 q 的下标为 t 的位置上。 q[t]i 的执行过程如下&#xff1a; 首先&#xff0c;i 的值被赋给 q[t]&#xff0c;即元素 i 被插入到数…

深度学习pytorch——可视化visdom(持续更新)

安装可看&#xff1a;e: Error while finding module specification for ‘visdom.server‘ (ModuleNotFoundError: No module name-CSDN博客 在命令行窗口使用python -m visdom.server&#xff0c;会出现一个web地址&#xff0c;在浏览器中访问&#xff0c;即可看见在python中…

2024年noc指导教师认证测评参考试题题目3-4合集

[noc指导教师认证] 测评参考试题 说明:NOC教师指导认证考试题目是从题库里抽题,因此每位老师每次考试题目都不一样以下题目为测试考试时收集到的一些题目,作为辅助提供给各位老师,老师们可以记住题目及答案的具体内容 (选项顺序会变),以免考试时遇到。2024年的做的题目有的…

C++基础9:继承与派生

此专栏为移动机器人知识体系下的编程语言中的 C {\rm C} C从入门到深入的专栏&#xff0c;参考书籍&#xff1a;《深入浅出 C {\rm C} C》(马晓锐)和《从 C {\rm C} C到 C {\rm C} C精通面向对象编程》(曾凡锋等)。 8.继承与派生 8.1 继承与派生基础 继承与派生举例理解&#…

C++函数参数传递

目录 传值参数 指针形参 传引用参数 使用引用避免拷贝 使用引用形参返回额外信息 const形参和实参 指针或引用形参与const 数组形参 管理指针形参 使用标记指定数组长度 使用标准库规范 显式传递一个表示数组大小的形参 数组形参和const 数组引用形参 传递多维数…

mysql基础1sql分类

mysql基础 [rootvm ~]# docker run -itd -p 3306:3306 -e "MYSQL_ROOT_PASSWORD123456" mysql:5.7.26通用语法 1). SQL语句可以单行或多行书写&#xff0c;以分号结尾。 2). SQL语句可以使用空格/缩进来增强语句的可读性。 3). MySQL数据库的SQL语句不区分大小写…

(ES6)前端八股文修炼Day2

1. let const var 的区别 var&#xff1a; var 是在 ES5 中引入的声明变量的关键字。 具有函数作用域&#xff0c;而不是块作用域&#xff0c;这意味着使用 var 声明的变量在函数内部是可见的。 变量可以被重复声明&#xff0c;而且变量的值可以在声明前使用&#xff0c;这可能…

阿里云服务器租用价格表,2024年1个月和一年优惠价格表

2024年腾讯云服务器优惠价格表&#xff0c;一张表整理阿里云服务器最新报价&#xff0c;阿里云服务器网整理云服务器ECS和轻量应用服务器详细CPU内存、公网带宽和系统盘详细配置报价单&#xff0c;大家也可以直接移步到阿里云CLUB中心查看 aliyun.club 当前最新的云服务器优惠券…

每日一题 --- 反转链表[力扣][Go]

反转链表 题目&#xff1a;206. 反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&a…

AtCoder Regular Contest 174 A~E

A.A Multiply&#xff08;贪心&#xff09; 题意&#xff1a; 给你一个长度为 N N N 、 A ( A 1 , A 2 , … , A N ) A(A_1,A_2,\dots,A_N) A(A1​,A2​,…,AN​) 和整数 C C C 的整数序列。 在进行最多一次以下操作后&#xff0c;求 A A A 中元素的最大可能和&#xff…

为什么安装了4GB的内存条,却显示只有3.8GB?

朋友们&#xff0c;对于计算机而言&#xff0c;其基本包含三部分。 第一&#xff0c;CPU; 第二&#xff0c;存储器&#xff08;内存、物理内存&#xff09;&#xff1b;第三&#xff0c;输入设备、输出设备。 32位的地址总线&#xff0c;其地址范围就是 CPU 访问内存&#xf…

小车倒立摆系统极点配置,LQR闭环控制

在之前直流电机控制仿真里有讲过状态控制的基本架构&#xff0c;有兴趣的同学可以再回去看看&#xff0c;链接如下好玩的直流电机调速实验、PID、极点配置、LQR、观测器&#xff1b;不讲大道理_lqr控制器观测器-CSDN博客 在专栏的前三篇文章 小车倒立摆物理建模与simulink仿真…