当前位置: 首页 > news >正文

数据结构(一)顺序表和链表

目录

1. 时间复杂度和空间复杂度

2. 顺序表

3. 链表


1. 时间复杂度和空间复杂度

         如何估算一个算法的效率高低一般就是使用到时间复杂度和空间复杂度; 时间复杂度是评价一个算法运行快慢的, 而空间复杂度是算法额外需要空间大小.

1.1 时间复杂度的计算:

        准确来说时间复杂度是一个函数, 如何计算有对应的规则的(大o渐进法).

大o渐进法:只要求计算大概运行次数即可, (1)对于常数直接取o(1);  (2)只保留最高阶项

(3) 乘数前面的常数直接省略. 而且一般都是算最坏的运行情况.

 1.2 计算练习:

 下面计算时间复杂度: f(N) =  N*N + 2*N + M --> N^2 + 2N + 10

使用上面的规则: f(N) = N^2 + N 运用(1)+(3)  ---> f(N) = N^2 运用(2);

#include <stdio.h>void Func1(int N)
{int count = 0;for (int i = 0; i < N; ++i){for (int j = 0; j < N; ++j){++count;}}for (int k = 0; k < 2 * N; ++k){++count;}int M = 10;while (M--){++count;}printf("%d\n", count);
}

计算: F(N) = 2*N + M ---> F(N) = N;

void Func2(int N)
{int count = 0;for (int k = 0; k < 2 * N; ++k){++count;}int M = 10;while (M--){++count;}printf("%d\n", count);
}

F(N) = M + N; M和N大小未知.

void Func3(int N, int M)
{int count = 0;for (int k = 0; k < M; ++k){++count;}for (int k = 0; k < N; ++k){++count;}printf("%d\n", count);
}

F(N) = 100  ---> F(N) = 1;

void Func4(int N)
{int count = 0;for (int k = 0; k < 100; ++k){++count;}printf("%d\n", count);
}

计算:  F(N) = N; 可能执行一次或者N次.

const char * strchr ( const char * str, int character );

 计算: F(n) = n * ((n-1) + (n-2) + (n-3) + ... + 1))  ----> n * (n-1) ---> n^ 2;

void BubbleSort(int *a, int n)
{assert(a);for (size_t end = n; end > 0; --end){int exchange = 0;for (size_t i = 1; i < end; ++i){if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);exchange = 1;}}if (exchange == 0)break;}
}

计算折半查找, 设数据总量为x, x/2/2/2/2.../2 =  --->x = 2 * 2 * 2 * ... * 2; ---> x = 2 * N;

N = log2 ^ x --> F(N) = logN;

int BinarySearch(int *a, int n, int x)
{assert(a);int begin = 0;int end = n - 1;// [begin, end]:begin和end是左闭右闭区间,因此有=号while (begin <= end){int mid = begin + ((end - begin) >> 1);if (a[mid] < x)begin = mid + 1;else if (a[mid] > x)end = mid - 1;elsereturn mid;}return -1;
}

计算: F(N) = (N-1) + (N-2) + (N-3) + ... + 1 ---> F(N) = N;

long long Fac(size_t N)
{if (0 == N)return 1;return Fac(N - 1) * N;
}

计算: F(N) = 2^N

long long Fib(size_t N)
{if (N < 3)return 1;return Fib(N - 1) + Fib(N - 2);
}

1.3空间复杂度:

计算: 没有使用额外空间: F(N) = 1;

void BubbleSort(int *a, int n)
{assert(a);for (size_t end = n; end > 0; --end){int exchange = 0;for (size_t i = 1; i < end; ++i){if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);exchange = 1;}}if (exchange == 0)break;}
}

计算: F(N) = n + 1 -> F(N) = n;

long long *Fibonacci(size_t n)
{if (n == 0)return NULL;long long *fibArray = (long long *)malloc((n + 1) * sizeof(long long));fibArray[0] = 0;fibArray[1] = 1;for (int i = 2; i <= n; ++i){fibArray[i] = fibArray[i - 1] + fibArray[i - 2];}return fibArray;
}

计算: F(N) = N  因为调用了n次函数栈帧.

long long Fac(size_t N)
{if (N == 0)return 1;return Fac(N - 1) * N;
}

2. 顺序表

2.1 线性表:

        n个具有同种性质的数据元素的有限序列, 例如顺序表, 链表, 栈, 队列, 字符串等....

2.2 顺序表概念:

        一段物理地址连续的存储单元一次存储数据元素的线性结构, 一般用数组存储. 而且一般采用动态增长空间的顺序表.

 2.3 顺序表实现:

(1) 顺序表结构:

        a使用来进行顺序表的动态扩容的, size是记录顺序表的个数, capacity是记录顺序表的容量不够进行扩容.

typedef int SLDataType;typedef struct SeqList
{SLDataType* a;int size;int capacity;
}SeqList;
(2) 顺序表初始化: 

        将SqlList里面的元素进行全部初始化.

void SeqListInit(SeqList* psl)
{assert(psl);psl->a = nullptr;psl->size = 0;psl->capacity = 0;
}
 (3) 顺序表扩容:

        检测顺序表的元素是否需要扩容, 一般采用二倍扩容比较合适, 使用到realloc函数进行将原先顺序表的大小进行物理扩容, 函数细节自行去看cplusplus看看文档.

void SqlCheckCapacity(SeqList* psl)
{if(psl->size == psl->capacity){int newcapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;SLDataType* newA = (SLDataType*)realloc(psl->a, newcapacity * sizeof(SLDataType));if(newA == nullptr){printf("realloc fail!\n");exit(1);}psl->a = newA;psl->capacity = newcapacity;}
}
 (4)尾插:

        在尾部直接插入即可.也可以调用下面函数.

void SeqListPushBack(SeqList* psl, SLDataType x)
{// assert(psl);// SqlCheckCapacity(psl);// psl->a[psl->size] = x;// psl->size++;SeqListInsert(psl, psl->size, x);
}
 (5)尾删:

        将数据数量直接减少即可.

void SeqListPopBack(SeqList* psl)
{// assert(psl);// assert(psl->size > 0);// psl->size--;SeqListErase(psl, psl->size-1);
}
 (6) 头插:

         将数据进行后移动一位, 给头空出来进行插入.也可以调用下面封装好的函数.

void SeqListPushFront(SeqList* psl, SLDataType x)
{// assert(psl);// SqlCheckCapacity(psl);// for(int i = psl->size; i >= 0; i--)// {//     psl->a[i] = psl->a[i-1];// }// psl->a[0] = x;// psl->size++;SeqListInsert(psl, 0, x);
}
 (7) 头删:

        直接覆盖即可, 后面将前面数据进行覆盖, 或者调用函数.

void SeqListPopFront(SeqList* psl)
{// assert(psl);// assert(psl->size > 0);// for(int i = 0; i < psl->size-1; i++)// {//     psl->a[i] = psl->a[i+1];// }// psl->size--;SeqListErase(psl, 0);
}
 (8) 在pos位置插入x:

        将pos之后的数据进行移动后一位, 然后再进行插入.

void SeqListInsert(SeqList* psl,int pos, SLDataType x)
{assert(psl);assert(pos >= 0 && pos <= psl->size);SqlCheckCapacity(psl);for(int i = psl->size; i > pos; i--){psl->a[i] = psl->a[i-1];}psl->a[pos] = x;psl->size++;
}
 (9) 在pos位置删除x:

        也是将pos后面的数据直接向前覆盖即可.

void SeqListErase(SeqList* psl, int pos)
{assert(psl);assert(psl->size > 0);assert(pos >= 0 && pos < psl->size);for(int i = pos; i < psl->size-1; i++){psl->a[i] = psl->a[i+1];}psl->size--;
}
 (10)查找: 

        遍历即可.

int SeqListFind(SeqList* psl, SLDataType x)
{assert(psl);for(int i = 0; i < psl->size; i++){if(psl->a[i] == x)return i;}return -1;
}
 (11) 销毁: 

        将SqlList里面的元素进行销毁以及size和capacity进行置零.

void SqlListDestory(SeqList* psl)
{assert(psl);free(psl->a);psl->a = nullptr;psl->size = psl->capacity = 0;
}
 (12) 打印:

        循环打印顺序表中的数据元素.

void SqlListPrint(SeqList* psl)
{assert(psl);for(int i =  0; i < psl->size; i++){printf("%d ", psl->a[i]);}printf("\n");
}
(13) 修改: 
void SeqListModify(SeqList* psl, int pos, SLDataType x)
{assert(psl);assert(pos >= 0 && pos < psl->size);psl->a[pos] = x;
}

2.4 C++版本:

        上面是C语言版本, 现在用C++版本写一些.

template<class T>
class SeqList
{
public://使用构造函数和析构函数进行初始化和销毁SeqList():_a(nullptr), _size(0), _capacity(0){}~SeqList(){delete(_a);_a = nullptr;_size = _capacity = 0;}void CheckCapacity(SeqList* psl){if (psl->_size == psl->_capacity){int newcapacity = psl->_capacity == 0 ? 4 : psl->_capacity * 2;T* newA = new[newcapacity];for (int i = 0; i < psl->_size; i++){newA[i] = psl->_a[i];}psl->_a = newA;delete newA;newA = nullptr;psl->_capacity = newcapacity;}}void SqlListPrint(SeqList* psl){assert(psl);for (int i = 0; i < psl->_size; i++){cout << psl->_a[i] << " ";}cout << "\n";}void SeqListInsert(SeqList* psl, int pos, T x){assert(psl);assert(pos >= 0 && pos <= psl->_size);for (int i = psl->_size; i > pos; i--){psl->_a[i] = psl->a[i - 1];}psl->_a[pos] = x;psl->_size++;}void SeqListPushFront(SeqList* psl, T x){SeqListInsert(psl, 0, x);}void SeqListPushBack(SeqList* psl, T x){SeqListInsert(psl, psl->_size, x);}void SeqListErase(SeqList* psl, int pos){assert(psl);assert(psl->_size > 0);assert(pos >= 0 && pos < psl->_size);for (int i = pos; i < psl->_size - 1; i++){psl->_a[i] = psl->_a[i + 1];}psl->_size--;}void SeqListPopFront(SeqList* psl){SeqListErase(psl, 0);}void SeqListPopBack(SeqList* psl){SeqListErase(psl, psl->_size - 1);}int SeqListFind(SeqList* psl, T x){assert(psl);for (int i = 0; i < psl->_size; i++){if (psl->_a[i] == x)return i;}return -1;}void SeqListModify(SeqList* psl, int pos, T x){assert(psl);assert(pos >= 0 && pos < psl->_size);psl->_a[pos] = x;}
private:T* _a;int _size;int _capacity;
};

 2.5 链表问题以及思考:

(1) 除了尾部删除/插入为0(1), 中间或者头部删除/插入效率为0(N);

(2) 扩容时候需要将原先数据拷贝新容器中并且释放旧空间, 消耗较多;

(3) 扩容2倍可能到一定程度会有很多使用不完, 浪费了.

3. 链表:

3.1 概念:

        物理存储结构不连续, 但是逻辑存储结构是连续的, 采用指针链接起来的结构.

包含单向/双向; 带头/不带头; 循环/不循环这几种链表;

3.2 结构:

        就是由数据和指向下一个链表的指针组成的.

3.3 实现:

(1) 打印:

        结点遍历即可打印每个结点的值.

void SListPrint(SListNode* plist)
{SListNode* cur = plist;while(cur != nullptr){printf("%d-> ", cur->data);cur = cur->next;}printf("NULL\n");
}
(2) 增加结点:

        申请创建一个结点, 然后添加数据.

SListNode* BuySListNode(SLTDataType x)
{SListNode* node = (SListNode*)malloc(sizeof(SListNode));if(node == nullptr){printf("malloc fail\n");exit(-1);}node->data = x;node->next = nullptr;return node;
}
(3) 单链表头插:

        为啥要SListNode**类型做形参呢? 要修改头指针的指向, 所以使用到二级指针.

void SListPushFront(SListNode** pplist, SLTDataType x)
{SListNode* newnode = BuySListNode(x);newnode->next = *pplist;*pplist = newnode;
}
(4) 单链表尾插:

        找到尾部, 然后进行插入即可.

void SListPushBack(SListNode** pplist, SLTDataType x)
{SListNode* newnode = BuySListNode(x);if(*pplist == nullptr){*pplist = newnode;}else{SListNode* tail = *pplist;while(tail->next != nullptr){tail = tail->next;}tail->next = newnode;}
}
 (5) 给定位置之后插入:

        先将pos->next的那个结点用newnode指向, 再改变pos的指向newnode.

void SListInsertAfter(SListNode* pos, SLTDataType x)
{assert(pos);SListNode* newnode = BuySListNode(x);newnode->next = pos->next;pos->next = newnode;
}
(6) 在给定位置之前插入:

        先找到指定位置的之前位置, 然后改变之前结点的下一个结点指向, 在插入newnode结点. 如果插入是头结点的话也要注意头结点处理.

void SListInsertBefore(SListNode** pplist, SListNode* pos, SLTDataType x)
{assert(pos);SListNode* newnode = BuySListNode(x);if(pos == *pplist){newnode->next = pos;*pplist = newnode;}else{SListNode* prev = *pplist;while(prev->next != pos){prev = prev->next;}newnode->next = prev->next;prev->next = newnode;}
}
(7) 头删:

        将头结点先变成头的下一个结点, 然后再释放结点.

void SListPopFront(SListNode** pplist)
{if(*pplist == nullptr){return;}else{SListNode* tmp = *pplist;*pplist = (*pplist)->next;free(tmp);tmp = nullptr;}
}
(8) 尾删:

        先找到尾结点, 和次尾结点, 之后就将结点进行尾删除, 然后将次尾结点下一个结点置空. 

void SListPopBack(SListNode** pplist)
{if(*pplist == nullptr){//头结点为空return;}else if((*pplist)->next == nullptr){//只要一个结点;free(*pplist);*pplist = nullptr;}else{SListNode* prev = *pplist;SListNode* tail = (*pplist)->next;while(tail->next != nullptr){prev = tail;tail = tail->next;}free(tail);tail = nullptr;prev->next = nullptr;}
}
(9) 删除给定位置之后的结点:

        找到pos后面一个结点after, 将pos下一个结点改变, 然后再将after释放.

        

void SListEraseAfter(SListNode* pos)
{assert(pos);if(pos->next == nullptr){return;}SListNode* after = pos->next;pos->next = after->next;free(after);after = nullptr;
}
(10) 删除给定位置的结点:

               先判断pos是否为pplist头结点, 头结点删除置空, 不是就要找到pos前一个结点然后进行结点改变, 删除pos结点.

void SListEraseCur(SListNode** pplist, SListNode* pos)
{assert(pos);if(pos == *pplist){*pplist = pos->next;free(pos);pos = nullptr;}else{SListNode* prev = *pplist;while(prev->next != pos){prev = prev->next;}prev->next = pos->next;free(pos);pos = nullptr;}
}
(11) 查找数据:
SListNode* SListFind(SListNode* plist, SLTDataType x)
{SListNode* cur = plist;while(cur != nullptr){if(cur->data == x)return cur;cur = cur->next;}return nullptr;
}
(12) 修改数据:
void SListModify(SListNode* pos, SLTDataType x)
{pos->data = x;
}

3.4 双链表实现:

(1) 双链表结构:

typedef int LTDataType;typedef struct ListNode
{LTDataType data;struct ListNOde* prev;struct ListNode* next;
}ListNode;
(2) 初始化结点和创建结点:

        初始化一个值为-1的结点, 然后进行结点处理, 由于头结点的前后指针都是指向自己的.

ListNode* BuyListNode(LTDataType x)
{ListNode* node = (ListNode*)malloc(sizeof(ListNode));if(node == nullptr){printf("malloc fail!");exit(-1);}node->data = x;node->prev = nullptr;node->next = nullptr;
}ListNode* ListInit()
{ListNode* phead = BuyListNode(-1);phead->prev = phead;phead->next = phead;return phead;
}
(3) 销毁链表:

        两个结点指针就可以删除, 进行迭代删除.

        

void ListDestory(ListNode* phead)
{assert(phead);ListNode* cur = phead->next;ListNode* next = cur->next;while(cur != phead){free(cur);cur = next;next = next->next;}free(phead);
}
(4) 打印:
void ListPrint(ListNode* phead)
{assert(phead);ListNode* cur = phead->next;while(cur != phead){printf("%d ", cur->data);cur = cur->next;}printf("\n");
}
(5) 查找元素:
ListNode* ListFind(ListNode* phead, LTDataType x)
{assert(phead);ListNode* cur = phead->next;while(cur != phead){if(cur->data == x){return cur;}cur = cur->next;}return nullptr;
}
(6) 头插结点:

        先找到头的后一个结点, 再进行插入;

void ListPushFront(ListNode* phead, LTDataType x)
{assert(phead);ListNode* newnode = BuyListNode(x);ListNode* front = phead->next;phead->next = newnode;newnode->prev = phead;newnode->next = front;front->next = newnode;
}
(7) 尾插结点:

        先找到最后一个结点; 就是第一个结点的prev结点. 

void ListPushBack(ListNode* phead, LTDataType x)
{assert(phead);ListNode* newnode = BuyListNode(x);ListNode* tail = phead->prev;newnode->next = phead;phead->prev = newnode;tail->next = newnode;newnode->prev = tail;
}
(8) 在指定位置插入结点:

        先找到要插入结点的前一个结点, 然后将头一个结点和newnode结点之间连接起来.

void ListInsert(ListNode* pos, LTDataType x)
{assert(pos);ListNode* before = pos->prev;ListNode* newnode = BuyListNode(x);before->next = newnode;newnode->prev = before;newnode->next = pos;pos->prev = newnode;
}
(9) 头删:

        

void ListPopFront(ListNode* phead)
{assert(phead);//这里有哨兵位头结点;assert(phead->next != nullptr);ListNode* front = phead->next;ListNode* newfront = front->next;phead->next = newfront;newfront->prev = phead;free(front);
}
(10) 尾删:
void ListPopBack(ListNode* phead)
{assert(phead);assert(phead->next != nullptr);ListNode* tail = phead->prev;ListNode* newtail = tail->prev;newtail->next = phead;phead->prev = newtail;free(tail);
}
 (11) 删除指定位置结点:

     

void ListErase(ListNode* pos)
{assert(pos);ListNode* before = pos->prev;ListNode* after = pos->next;before->next = after;after->prev = before;free(pos);
}
(12) 链表判空:

        只要当phead->next对于phead那么就只要哨兵位的头结点, 直接为空.

bool ListEmpty(ListNode* phead)
{assert(phead);return phead->next == phead;
}
(13) 记录结点个数:
int ListSize(ListNode* phead)
{assert(phead);int count = 0;ListNode* cur = phead;while(cur != phead){count++;cur = cur->next;}return count;
}

3.5 C++版本单链表和双链表:

3.6 顺序表和链表的区别:

(1) 空间上顺序表的物理内存连续, 但是链表不连续;

(2) 顺序表支持随机访问, 但是链表不支持;

(3) 顺序表在任意插入删除效率比较低需要数据搬离, 但是链表只需要改变指针指向即可;

(4) 扩容顺序表需要空间申请和释放, 链表不需要.

(5) 顺序表主要运用需要大量查询, 链表就是随机删除插入的场景;

(6) 顺序表缓存利用高, 链表低等.

相关文章:

数据结构(一)顺序表和链表

目录 1. 时间复杂度和空间复杂度 2. 顺序表 3. 链表 1. 时间复杂度和空间复杂度 如何估算一个算法的效率高低一般就是使用到时间复杂度和空间复杂度; 时间复杂度是评价一个算法运行快慢的, 而空间复杂度是算法额外需要空间大小. 1.1 时间复杂度的计算: 准确来说时间复杂度是…...

单相可控整流电路——单相桥式全控整流电路

以下是关于单相桥式整流电路的介绍&#xff1a; 电路构成&#xff08;带阻性负载的工作情况&#xff09; - 二极管&#xff1a;是电路0的核心元件&#xff0c;通常采用四个同型号或根据需求选择不同型号的二极管&#xff0c;如1N4001、1N4007等&#xff0c;如图Vt1和Vt4是一对…...

DeepSeek-R1:性能对标 OpenAI,开源助力 AI 生态发展

DeepSeek-R1&#xff1a;性能对标 OpenAI&#xff0c;开源助力 AI 生态发展 在人工智能领域&#xff0c;大模型的竞争一直备受关注。最近&#xff0c;DeepSeek 团队发布了 DeepSeek-R1 模型&#xff0c;并开源了模型权重&#xff0c;这一举动无疑为 AI 领域带来了新的活力。今…...

【Maui】提示消息的扩展

文章目录 前言一、问题描述二、解决方案三、软件开发&#xff08;源码&#xff09;3.1 消息扩展库3.2 消息提示框使用3.3 错误消息提示使用3.4 问题选择框使用 四、项目展示 前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架&#xff0c;用于使用 C# 和 XAML 创建本机移…...

001 mybatis入门

文章目录 mybatis是什么ORM是什么ORM框架和MyBatis的区别#{}和${}的区别编码流程UserDaoImpl.javaUserDao.javaUser.javadb.propertiesSqlMapConfig.xmlUserMapper.xmlMybatisTest.javapom.xmluser.sql 表现层 SpringMVC 业务层 Spring 持久层 Mybatis https://mybatis.org/myb…...

tomcat的accept-count、max-connections、max-threads三个参数的含义

tomcat的accept-count、max-connections、max-threads三个参数的含义 tomcat的accept-count、max-connections、max-threads三个参数的含义 max-connections&#xff1a;最大连接数 最大连接数是指&#xff0c;同一时刻&#xff0c;能够连接的最大请求数 需要注意的是&#x…...

8.2 从看图识字到智能解读:GPT-4 with Vision 开启多模态 AI 新纪元

从看图识字到智能解读:GPT-4 with Vision 开启多模态 AI 新纪元 引言:AI 的多模态跃迁 随着人工智能技术的快速发展,我们正迈入一个新的智能交互时代。传统的 AI 模型主要聚焦于文本处理,而多模态 AI 模型如 GPT-4 with Vision(GPT-4V) 则能够同时处理图像和文本。GPT-4…...

.strip()用法

.strip("") 是 Python 字符串方法 strip() 的一个用法&#xff0c;它会去除字符串两端指定字符集中的字符。 基本语法&#xff1a; string.strip([chars])string: 这是你要操作的字符串。chars: 可选参数&#xff0c;表示你想要去除的字符集&#xff08;默认为空格…...

蓝桥杯例题三

无论前方困难如何重重&#xff0c;我们都要坚定信念&#xff0c;勇往直前。面对挑战和困境&#xff0c;不要退缩&#xff0c;不要放弃&#xff0c;要坚持走下去。当我们感到疲惫时&#xff0c;要告诉自己&#xff1a;“我可以&#xff0c;我一定行&#xff01;”相信自己的实力…...

关于pygame窗口输入法状态异常切换现象的分析报告

一、问题描述 1.1 需求说明 我们准备使用Pygame开发一个键盘输入测试程序&#xff0c;需要确保输入时窗口始终处于英文输入模式&#xff0c;也就是禁止中文输入&#xff1b; 1.2 现象描述 控制台种显示&#xff0c;程序在初始化时&#xff0c;会有两次IMM状态切换操作&…...

【JavaEE进阶】应用分层

目录 &#x1f38b;序言 &#x1f343;什么是应用分层 &#x1f38d;为什么需要应用分层 &#x1f340;如何分层(三层架构) &#x1f384;MVC和三层架构的区别和联系 &#x1f333;什么是高内聚低耦合 &#x1f38b;序言 通过上⾯的练习,我们学习了SpringMVC简单功能的开…...

两数相加:链表操作的基础与扩展

两数相加&#xff1a;链表操作的基础与扩展 引言 链表&#xff08;Linked List&#xff09;是一种灵活且高效的数据结构&#xff0c;特别适用于动态增删操作。无论是初学者还是资深程序员&#xff0c;链表的基本操作都是算法学习中的重要一环。而 “两数相加” 问题则是链表操…...

ChatGPT从数据分析到内容写作建议相关的46个提示词分享!

在当今快节奏的学术环境中&#xff0c;研究人员面临着海量的信息和复杂的研究任务。幸运的是&#xff0c;随着人工智能技术的发展&#xff0c;像ChatGPT这样的先进工具为科研人员提供了强大的支持。今天就让我们一起探索如何利用ChatGPT提升研究效率进一步优化研究流程。 ChatG…...

解析“in the wild”——编程和生活中的俚语妙用

解析“in the wild”——编程和生活中的俚语妙用 看下面的技术文章中遇到 in the wild这个词&#xff0c;想要研究一下&#xff0c;遂产生此文。 Are there ever pointers to pointers to pointers? There is an old programming joke which says you can rate C programmers…...

rocketmq原理源码分析之控制器模式- dledger

简介 RocketMQ 4.5 版本之前&#xff0c;RocketMQ 的broker是 Master/Slave部署架构&#xff0c;一组 broker 有一个 Master &#xff0c;有0到若干Slave&#xff0c;Slave复制Master消息存储&#xff0c;随时替代下线的Master。Master/Slave部署架构提供一定的高可用性&#x…...

Hello Moto

“Hello Moto” 是摩托罗拉&#xff08;Motorola&#xff09;的一句经典广告口号&#xff0c;用于推广其品牌和产品&#xff0c;特别是在手机领域。以下是它的含义和背景&#xff1a; 1. 品牌宣传的标志性语句 直白含义&#xff1a;简单地向摩托罗拉打招呼&#xff08;“Hell…...

存储基础 -- SCSI命令格式与使用场景

SCSI命令格式与使用场景 1. SCSI命令描述符块&#xff08;CDB&#xff09; 1.1 CDB基本概念 SCSI命令通过**命令描述符块&#xff08;CDB, Command Descriptor Block&#xff09;**表示。 CDB长度&#xff1a;SCSI命令根据使用场景有不同长度的CDB&#xff0c;常见的有6字节…...

ceph基本概念,架构,部署(一)

一、分布式存储概述 1.存储分类 存储分为封闭系统的存储和开放系统的存储&#xff0c;而对于开放系统的存储又被分为内置存储和外挂存储。 外挂存储又被细分为直连式存储(DAS)和网络存储(FAS)&#xff0c;而网络存储又被细分网络接入存储(NAS)和存储区域网络(SAN)等。 DAS(D…...

CNN-GRU卷积门控循环单元时间序列预测(Matlab完整源码和数据)

CNN-GRU卷积门控循环单元时间序列预测&#xff08;Matlab完整源码和数据&#xff09; 目录 CNN-GRU卷积门控循环单元时间序列预测&#xff08;Matlab完整源码和数据&#xff09;预测效果基本介绍CNN-GRU卷积门控循环单元时间序列预测一、引言1.1、研究背景与意义1.2、研究现状1…...

Ubuntu 顶部状态栏 配置,gnu扩展程序

顶部状态栏 默认没有配置、隐藏的地方 安装使用Hide Top Bar 或Just Perfection等进行配置 1 安装 sudo apt install gnome-shell-extension-manager2 打开 安装的“扩展管理器” 3. 对顶部状态栏进行配置 使用Hide Top Bar 智能隐藏&#xff0c;或者使用Just Perfection 直…...

React应用深度优化与调试实战指南

一、渲染性能优化进阶 1.1 精细化渲染控制 typescript 复制 // components/HeavyComponent.tsx import React, { memo, useMemo } from react;interface Item {id: string;complexData: {// 复杂嵌套结构}; }const HeavyComponent memo(({ items }: { items: Item[] }) &g…...

Spring中的事件和事件监听器是如何工作的?

目录 一、事件&#xff08;Event&#xff09; 二、事件发布器&#xff08;Event Publisher&#xff09; 三、事件监听器&#xff08;Event Listener&#xff09; 四、使用场景 五、总结 以下是关于Spring中的事件和事件监听器的介绍与使用说明&#xff0c;结合了使用场景&…...

Vue.js组件开发-实现多个文件附件压缩下载

在 Vue 项目中实现多个附件压缩下载&#xff0c;可以借助 jszip 库来创建压缩文件&#xff0c;以及 file-saver 库来保存生成的压缩文件。 步骤 1&#xff1a;安装依赖 首先&#xff0c;在 Vue 项目中安装 jszip 和 file-saver&#xff1a; npm install jszip file-saver步骤…...

基于dlib/face recognition人脸识别推拉流实现

目录 一.环境搭建 二.推拉流代码 三.人脸检测推拉流 一.环境搭建 1.下载RTSP服务器MediaMTX与FFmpeg FFmpeg是一款功能强大的开源多媒体处理工具,而MediaMTX则是一个轻量级的流媒体服务器。两者结合,可以实现将本地视频或者实时摄像头画面推送到RTSP流,从而实现视频…...

qt QNetworkRequest详解

1、概述 QNetworkRequest是Qt网络模块中的一个核心类&#xff0c;专门用于处理网络请求。它封装了网络请求的所有关键信息&#xff0c;包括请求的URL、HTTP头部信息等&#xff0c;使得开发者能够方便地在Qt应用程序中执行网络操作&#xff0c;如文件下载、网页内容获取等。QNe…...

uvm timeout的哪些事

如下图所示&#xff0c;设置timeout并未生效&#xff0c;原因多了一个空格&#xff0c;坑 进一步分析&#xff0c;默认是overidable的 是否加括号呢&#xff0c;如下所示&#xff0c;这两个造型都可以&#xff0c;中间有空格也行 那么&#xff0c;我加上单位可以吗&#xff0c;…...

JavaScript赋能智能网页设计

构建AI驱动的实时风格迁移系统 案例概述 本案例将实现一个基于深度学习的实时图像风格迁移系统&#xff0c;通过浏览器端神经网络推理实现以下高级特性&#xff1a; WebAssembly加速的ONNX模型推理 WebGL Shader实现的风格混合算法 WebRTC实时视频流处理 基于Web Workers的…...

全面了解 Web3 AIGC 和 AI Agent 的创新先锋 MelodAI

不管是在传统领域还是 Crypto&#xff0c;AI 都是公认的最有前景的赛道。随着数字内容需求的爆炸式增长和技术的快速迭代&#xff0c;Web3 AIGC&#xff08;AI生成内容&#xff09;和 AI Agent&#xff08;人工智能代理&#xff09;正成为两大关键赛道。 AIGC 通过 AI 技术生成…...

leetcode_链表 234.回文链表

234.回文链表 给你一个单链表的头节点head&#xff0c;请你判断该链表是否为回文链表。如果是, 返回 true ; 否则, 返回false。思路&#xff1a; 找到中间节点(快慢指针法)反转后半部分的链表比较前半部分和后半部分链表 # Definition for singly-linked list. # class List…...

cloc下载和使用

cloc&#xff08;Count Lines of Code&#xff09;是一个跨平台的命令行工具&#xff0c;用于计算代码行数。以下是下载和使用 cloc 的步骤&#xff1a; 下载 cloc 对于 Windows 用户&#xff1a; 访问 cloc 的 GitHub 仓库&#xff1a;https://github.com/AlDanial/cloc在 …...

在 Windows 系统上,将 Ubuntu 从 C 盘 迁移到 D 盘

在 Windows 系统上&#xff0c;如果你使用的是 WSL&#xff08;Windows Subsystem for Linux&#xff09;并安装了 Ubuntu&#xff0c;你可以将 Ubuntu 从 C 盘 迁移到 D 盘。迁移过程涉及导出当前的 Ubuntu 发行版&#xff0c;然后将其导入到 D 盘的目标目录。以下是详细的步骤…...

【Redis】Redis入门以及什么是分布式系统{Redis引入+分布式系统介绍}

文章目录 介绍redis的引入 分布式系统单机架构应用服务和数据库服务分离【负载均衡】引入更多的应用服务器节点 单机架构 分布式是什么 数据库分离和负载均衡 理解负载均衡 数据库读写分离 引入缓存 数据库分库分表 引入微服务 介绍 The open source, in-memory data store us…...

wow-agent---task4 MetaGPT初体验

先说坑&#xff1a; 1.使用git clone模式安装metagpt 2.模型尽量使用在线模型或本地高参数模型。 这里使用python3.10.11调试成功 一&#xff0c;安装 安装 | MetaGPT&#xff0c;参考这里的以开发模型进行安装 git clone https://github.com/geekan/MetaGPT.git cd /you…...

Leetcode::3432. 统计元素和差值为偶数的分区方案

3432. 统计元素和差值为偶数的分区方案 已解答 简单 相关企业 提示 给你一个长度为 n 的整数数组 nums 。 分区 是指将数组按照下标 i &#xff08;0 < i < n - 1&#xff09;划分成两个 非空 子数组&#xff0c;其中&#xff1a; 左子数组包含区间 [0, i] 内的所…...

linux如何修改密码,要在CentOS 7系统中修改密码

要在CentOS 7系统中修改密码&#xff0c;你可以按照以下步骤操作&#xff1a; 步骤 1: 登录到系统 在登录提示符 localhost login: 后输入你的用户名。输入密码并按回车键。 步骤 2: 修改密码 登录后&#xff0c;使用 passwd 命令来修改密码&#xff1a; passwd 系统会提…...

GIS与相关专业软件汇总

闲来无事突然想整理一下看看 GIS及相关领域 究竟有多少软件或者工具包等。 我询问了几个AI工具并汇总了一个软件汇总&#xff0c;不搜不知道&#xff0c;一搜吓一跳&#xff0c;搜索出来了大量的软件&#xff0c;大部分软件或者工具包都没有见过&#xff0c;不知大家还有没有要…...

云计算架构学习之LNMP架构部署、架构拆分、负载均衡-会话保持

一.LNMP架构部署 1.1. LNMP服务搭建 1.磁盘信息 2.内存 3.负载信息 4.Nginx你们公司都用来干嘛 5.文件句柄(文件描述符 打开文件最大数量) 6.你处理过系统中的漏洞吗 SSH漏洞 7.你写过什么shell脚本 8.监控通过什么告警 zabbix 具体监控哪些内容 9.mysql redis查询 你好H…...

mamba论文学习

rnn 1986 训练速度慢 testing很快 但是很快就忘了 lstm 1997 训练速度慢 testing很快 但是也会忘&#xff08;序列很长的时候&#xff09; GRU实在lstm的基础上改进&#xff0c;改变了一些门 transformer2017 训练很快&#xff0c;testing慢些&#xff0c;时间复杂度高&am…...

uva 1354 Mobile Computing

原题&#xff1a; 房间中有一个天平&#xff0c;房间的宽度为r&#xff0c;有s个砝码&#xff0c;每个砝码的重量是 w i w_i wi​。设计一个尽量宽&#xff0c;但是宽度不能超过r的天平&#xff0c;挂住所有砝码。天平全部由长度为1的木棍组成&#xff0c;木棍的每一端要么挂一…...

理解C++中的右值引用

右值引用&#xff0c;顾名思义&#xff0c;就是对一个右值进行引用&#xff0c;或者说给右值一个别名。右值引用的规则和左值一用一模一样&#xff0c;都是对一个值或者对象起个别名。 1. 右值引用和左值引用一样&#xff0c;在定义的同时必须立即赋值&#xff0c;如果不立即赋…...

约数个数(简单)

给定 nn 个正整数 aiai&#xff0c;请你输出这些数的乘积的约数个数&#xff0c;答案对 10971097 取模。 输入格式 第一行包含整数 nn。 接下来 nn 行&#xff0c;每行包含一个整数 aiai。 输出格式 输出一个整数&#xff0c;表示所给正整数的乘积的约数个数&#xff0c;答…...

Day33:字符串的切片

在 Python 中&#xff0c;**切片&#xff08;Slicing&#xff09;**是对字符串&#xff08;以及其他序列类型&#xff0c;如列表、元组等&#xff09;进行提取部分内容的强大工具。通过切片&#xff0c;你可以非常方便地提取字符串的子字符串、倒序字符串&#xff0c;甚至进行步…...

基于回归分析法的光伏发电系统最大功率计算simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于回归分析法的光伏发电系统最大功率计算simulink建模与仿真。选择回归法进行最大功率点的追踪&#xff0c;使用光强和温度作为影响因素&#xff0c;电压作为输出进行建模。…...

redis离线安装部署详解(包括一键启动)

像上文一样 因为在学习的过程中没有查到一个详细的离线部署方案 所以在自己学习之后想要自己写一个文章 希望可以帮助后续学习redis离线部署的朋友少走一线弯路 首先就是下载安装包 可以自己在本地下载再传到机器上&#xff08;通过xftp或lrzsz都可&#xff09; http://d…...

Coze插件开发之基于已有服务创建并上架到扣子商店

Coze插件开发之基于已有服务创建并上架到扣子商店 在应用开发中&#xff0c;需要调用各种插件&#xff0c;以快速进行开发。但有时需要调用的插件在扣子商店里没有&#xff0c;那怎么办呢&#xff1f; 今天就来带大家快速基于已有服务创建一个新的插件 简单来讲&#xff0c;就是…...

【Unity】 HTFramework框架(五十九)快速开发编辑器工具(Assembly Viewer + ILSpy)

更新日期&#xff1a;2025年1月23日。 Github源码&#xff1a;[点我获取源码] Gitee源码&#xff1a;[点我获取源码] 索引 开发编辑器工具MouseRayTarget焦点视角Collider线框Assembly Viewer搜索程序集ILSpy反编译程序集搜索GizmosElement类找到Gizmos菜单找到Gizmos窗口分析A…...

【Linux】统计文本中每行指定位置出现的字符串的次数

统计文本中每行指定位置出现的字符串的次数 假定情景 某些项目&#xff0c;会把某个特定事件记录到Log中并且落盘&#xff08;保持到硬盘&#xff09;。基于落盘后的日志&#xff0c;要统计这些日志里产生该特定事件的次数 统计脚本 可以写一个sh脚本&#xff0c;来解析某个…...

牛客周赛round78 B,C

B.一起做很甜的梦 题意&#xff1a;就是输出n个数&#xff08;1-n&#xff09;&#xff0c;使输出的序列中任意选连续的小序列&#xff08;小序列长度>2&&<n-1&#xff09;不符合排列&#xff08;例如如果所选长度为2&#xff0c;在所有长度为2 的小序列里不能出…...

【DB】Oracle存储过程

目录 什么是存储过程&#xff1f; 为什么要使用存储过程&#xff1f; 创建存储过程 无参存储过程语法&#xff1a; 带参存储过程语法&#xff1a; 带有输入参数的存储过程 带有输出参数的存储过程 带有输入输出参数的存储过程 带有异常处理的存储过程 存储过程中游标…...

亚博microros小车-原生ubuntu支持系列:14雷达跟踪与雷达守卫

背景知识 激光雷达的数据格式参见&#xff1a; 亚博microros小车-原生ubuntu支持系列&#xff1a;13 激光雷达避障-CSDN博客 本节体验雷达跟踪跟守卫 PID控制 从百度百科摘一段介绍 比例积分微分控制&#xff08;proportional-integral-derivative control&#xff09;&am…...