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

【数据结构】双向链表 C++

一、什么是双向链表

1、定义

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

双向链表的结构如图(图片来源于网络):

2、时空复杂度

双向链表的空间复杂度是 O ( n ) O(n) O(n) 的,其时间复杂度如下:

操作时间复杂度
遍历 O ( n ) O(n) O(n)
访问指定节点 O ( 1 ) O(1) O(1)
删除指定编号节点 O ( n ) O(n) O(n)
删除指定位置节点 O ( 1 ) O(1) O(1)
在指定编号的节点后插入节点 O ( n ) O(n) O(n)
在指定位置的节点后插入节点 O ( 1 ) O(1) O(1)
查询前驱、后继 O ( 1 ) O(1) O(1)
修改指定编号节点的值 O ( n ) O(n) O(n)
修改指定位置节点的值 O ( 1 ) O(1) O(1)
交换两个 list 容器 O ( 1 ) O(1) O(1)

二、双向链表的基本操作

1. 定义双向链表节点

每个节点有三个值:

  1. val:存储每个节点的权值;
  2. last:指向每个节点的前面的第一个节点;
  3. next:指向每个节点的后面的第一个节点;

代码如下:

template<typename T>
struct ListNode{T value;ListNode<T>* last;ListNode<T>* next;ListNode():value(0){last=NULL,next=NULL;}ListNode(const T &x):value(x){last=NULL,next=NULL;}~ListNode(){value=0;delete last;delete next;}
};

2. 创建双向链表类

类里面包含两个节点和一个变量:

  1. headnode:头节点,初始时前驱后继均为空,值为 − 1 -1 1
  2. endnode:尾节点,初始时前驱后继均为空,值为 − 1 -1 1
  3. listsize:记录双向链表的节点个数,不包含头尾节点;

代码如下:

template<typename T>
class list{private:unsigned listsize;ListNode<T>* headnode;ListNode<T>* endnode;
};

3. 初始化双向链表类

共有四种初始化方式:

  1. list<类型名> a;:此时创建一个空的双向链表;
  2. list<类型名> a(n);:此时创建一个大小为 n n n 的双向链表,并将所有点的初始值赋为 0 0 0
  3. list<类型名> a(n,m):此时创建一个大小为 n n n 的双向链表,并将所有点的初始值赋为 m m m
  4. list<类型名> a={a1,a2,a3,...,an};:此时创建一个大小为 n n n 的双向链表,并将第 i i i 个节点的初始值赋为 a i a_i ai

第一种初始化方式代码如下:

list():listsize(0){headnode=new ListNode<T>(-1);endnode=new ListNode<T>(-1);
}

第二种初始化方式代码如下:

list(const int &size_t):listsize(size_t) {headnode=new ListNode<T>(-1);endnode=new ListNode<T>(-1);ListNode<T>* now=headnode;for(int i=0;i<listsize;++i){ListNode<T>* newnode=new ListNode<T>(0);endnode->last=newnode;newnode->next=endnode;newnode->last=now;now->next=newnode;now=now->next;}
}

第三种初始化方式代码如下:

list(const int &size_t,const int &val
):listsize(size_t){headnode=new ListNode<T>(-1);endnode=new ListNode<T>(-1);ListNode<T>* now=headnode;for(int i=0;i<listsize;++i){ListNode<T>* newnode=new ListNode<T>(val);endnode->last=newnode;newnode->next=endnode;newnode->last=now;now->next=newnode;now=now->next;}
}

第四种初始化方式代码如下:

typedef std::initializer_list<T> lisval;
list(lisval vals){listsize=0;headnode=new ListNode<T>(-1);endnode=new ListNode<T>(-1);ListNode<T>* now=headnode;for(auto val:vals){ListNode<T>* newnode=new ListNode<T>(val);endnode->last=newnode;newnode->next=endnode;newnode->last=now;now->next=newnode;now=now->next; ++listsize;}
}

3. 一些基础的函数

这些函数是除了加点删点之外最常见的几个函数。

  1. size():获取链表的大小,返回一个 unsigned 值,表示当前链表中普通节点(非头尾节点)的个数。

    代码如下:

    unsigned size() const {return listsize;
    }
    
  2. empty():返回当前链表是否为空,如果是,返回 true,否则返回 false。

    代码如下:

    bool empty() const {return listsize==0;
    }
    
  3. begin():返回第一个普通节点。

    代码如下:

    ListNode<T>* begin(
    ) const {return headnode->next;
    }
    
  4. end():返回尾指针。

    代码如下:

    ListNode<T>* end(
    ) const {return endnode;
    }
    
  5. rbegin():返回最后一个普通节点。

    代码如下:

    ListNode<T>* rbegin(
    ) const {return endnode->last;
    }
    
  6. rend():返回头指针。

    代码如下:

    ListNode<T>* rend(
    ) const {return headnode;
    }
    
  7. front():返回第一个普通节点的值。

    代码如下:

    T front() const {return begin()->value;
    }
    
  8. back():返回最后一个普通节点的值。

    代码如下:

    T back() const {return rbegin()->value;
    }
    
  9. print():遍历并输出链表中每个普通节点的值,结尾换行。

    代码如下:

    void print(
    ) const {if(empty()) return;ListNode<T>* now=headnode->next;while(now->next!=NULL){printf("%d ",now->value);now=now->next;} putchar('\n');
    }
    
  10. swap(list<类型名> &b):交换两个 list 容器,实际上是交换头尾指针和 l i s t s i z e listsize listsize

    代码如下:

    void swap(list<T> &b){ListNode<T>* temp;temp=headnode;headnode=b.headnode;b.headnode=temp;temp=endnode;endnode=b.endnode;b.endnode=temp;unsigned size_t=listsize;listsize=b.listsize;b.listsize=size_t;
    }
    

5. 插入节点

共四种方法,代码如下:

void push_back(const T &val
){ ++listsize;if(endnode->last==NULL){ListNode<T>* newnode=new ListNode<T>(val);endnode->last=newnode;newnode->next=endnode;headnode->next=newnode;newnode->last=headnode;return;}ListNode<T>* pre=endnode->last;ListNode<T>* newnode=new ListNode<T>(val);pre->next=newnode;newnode->last=pre;newnode->next=endnode;endnode->last=newnode;
}
void push_front(const T &val
){ ++listsize;if(headnode->next==NULL){ListNode<T>* newnode=new ListNode<T>(val);endnode->last=newnode;newnode->next=endnode;headnode->next=newnode;newnode->last=headnode;return;}ListNode<T>* suf=headnode->next;ListNode<T>* newnode=new ListNode<T>(val);headnode->next=newnode;newnode->last=headnode;newnode->next=suf;suf->last=newnode;
}
void insert(const T &pos,const T &val
){  int nowpos=0;if(pos==0){push_front(val);++listsize; return;} else if(pos>=listsize){push_back(val);++listsize; return;}ListNode<T>* now=headnode->next;while(now->next!=NULL){++nowpos;if(nowpos==pos){ListNode<T>* newnode=new ListNode<T>(val);ListNode<T>* suf=now->next;newnode->next=suf;suf->last=newnode;newnode->last=now;now->next=newnode;++listsize; return;}now=now->next;}
}
void insert(ListNode<T>* now,const T &val
){if(now==endnode){push_back(val); return;}ListNode<T>* newnode=new ListNode<T>(val);ListNode<T>* suf=now->next;newnode->next=suf;suf->last=newnode;newnode->last=now;now->next=newnode;++listsize; return;
}

6. 修改指定位置的值

两种方法,代码如下:

void reassign(const T &pos,const T &val
){if(pos>listsize) return;if(empty()||!pos) return;ListNode<T>* now=headnode->next;int nowpos=0;while(now->next!=NULL){++nowpos;if(nowpos==pos){now->value=val;return;} now=now->next;}
}
void reassign(ListNode<T>* now,const int &val
) const {now->value=val;
}

7.删除节点

和插入一样,共有四种,代码如下:

void pop_back(){if(empty()) return;ListNode<T>* now=endnode->last;ListNode<T>* pre=now->last;if(pre==headnode){endnode->last=NULL;headnode->last=NULL;--listsize; return;}endnode->last=pre;pre->next=endnode;--listsize;
}
void pop_front(){if(empty()) return;ListNode<T>* now=headnode->next;ListNode<T>* suf=now->next;if(suf==endnode){endnode->last=NULL;headnode->last=NULL;--listsize; return;}headnode->next=suf;suf->last=headnode;--listsize;
}
void erase(const int &pos
) {if(pos>listsize) return;if(empty()||!pos) return;ListNode<T>* now=headnode->next;int nowpos=0;while(now!=endnode){++nowpos;if(nowpos==pos){ListNode<T>* pre=now->last;ListNode<T>* suf=now->next;if(pre==headnode||suf==endnode){endnode->last=NULL;headnode->next=NULL;delete now;--listsize; return;}pre->next=suf;suf->last=pre;delete now;--listsize; return;}now=now->next;}
}
void erase(ListNode<T>* now
){  if(now==headnode) return;if(now==endnode) return;if(empty()) return;ListNode<T>* pre=now->last;ListNode<T>* suf=now->next;if(pre==headnode||suf==endnode){endnode->last=NULL;headnode->last=NULL;--listsize; return;}pre->next=suf;suf->last=pre;--listsize; return;
}

8. 注销双向链表类

遍历一遍,然后将每个节点都删除就可以了。

代码如下:

~list(){ListNode<T>* now=headnode->next;while(now!=NULL){ListNode<T>* nxt=now->next;delete now;now=nxt;} delete headnode; listsize=0;
}

三、完整代码

我知道你们只看这个

码风丑陋,不喜勿喷

#include<stdio.h>
#include<stdlib.h>
#include<initializer_list>
namespace STL{template<typename T>struct ListNode{T value;ListNode<T>* last;ListNode<T>* next;ListNode():value({}){last=NULL,next=NULL;}ListNode(const T &x):value(x){last=NULL,next=NULL;}~ListNode(){// value={};last=NULL;next=NULL;}};template<typename T>class list{private:unsigned listsize;ListNode<T>* headnode;ListNode<T>* endnode;public:list():listsize(0){headnode=new ListNode<T>(T({-1}));endnode=new ListNode<T>(T({-1}));}list(const int &size_t):listsize(size_t) {headnode=new ListNode<T>(-1);endnode=new ListNode<T>(-1);ListNode<T>* now=headnode;for(int i=0;i<listsize;++i){ListNode<T>* newnode=new ListNode<T>(0);endnode->last=newnode;newnode->next=endnode;newnode->last=now;now->next=newnode;now=now->next;}}list(const int &size_t,const int &val):listsize(size_t){headnode=new ListNode<T>(-1);endnode=new ListNode<T>(-1);ListNode<T>* now=headnode;for(int i=0;i<listsize;++i){ListNode<T>* newnode=new ListNode<T>(val);endnode->last=newnode;newnode->next=endnode;newnode->last=now;now->next=newnode;now=now->next;}}typedef std::initializer_list<T> lisval;list(lisval vals){listsize=0;headnode=new ListNode<T>(-1);endnode=new ListNode<T>(-1);ListNode<T>* now=headnode;for(auto val:vals){ListNode<T>* newnode=new ListNode<T>(val);endnode->last=newnode;newnode->next=endnode;newnode->last=now;now->next=newnode;now=now->next; ++listsize;}}unsigned size() const {return listsize;}bool empty() const {return listsize==0;}ListNode<T>* begin() const {return headnode->next;}ListNode<T>* end() const {return endnode;}ListNode<T>* rbegin() const {return endnode->last;}ListNode<T>* rend() const {return headnode;}T front() const {return begin()->value;}T back() const {return rbegin()->value;}void print() const {if(empty()) return;ListNode<T>* now=headnode->next;while(now->next!=NULL){printf("%lld ",now->value);now=now->next;} putchar('\n');}void push_back(const T &val){ ++listsize;if(endnode->last==NULL){ListNode<T>* newnode=new ListNode<T>(val);endnode->last=newnode;newnode->next=endnode;headnode->next=newnode;newnode->last=headnode;return;}ListNode<T>* pre=endnode->last;ListNode<T>* newnode=new ListNode<T>(val);pre->next=newnode;newnode->last=pre;newnode->next=endnode;endnode->last=newnode;}void push_front(const T &val){ ++listsize;if(headnode->next==NULL){ListNode<T>* newnode=new ListNode<T>(val);endnode->last=newnode;newnode->next=endnode;headnode->next=newnode;newnode->last=headnode;return;}ListNode<T>* suf=headnode->next;ListNode<T>* newnode=new ListNode<T>(val);headnode->next=newnode;newnode->last=headnode;newnode->next=suf;suf->last=newnode;}void insert(const T &pos,const T &val){  int nowpos=0;if(pos==0){push_front(val);++listsize; return;} else if(pos>=listsize){push_back(val);++listsize; return;}ListNode<T>* now=headnode->next;while(now->next!=NULL){++nowpos;if(nowpos==pos){ListNode<T>* newnode=new ListNode<T>(val);ListNode<T>* suf=now->next;newnode->next=suf;suf->last=newnode;newnode->last=now;now->next=newnode;++listsize; return;}now=now->next;}}void insert(ListNode<T>* now,const T &val){if(now==endnode){push_back(val); return;}ListNode<T>* newnode=new ListNode<T>(val);ListNode<T>* suf=now->next;newnode->next=suf;suf->last=newnode;newnode->last=now;now->next=newnode;++listsize; return;}void reassign(const T &pos,const T &val){if(pos>listsize) return;if(empty()||!pos) return;ListNode<T>* now=headnode->next;int nowpos=0;while(now->next!=NULL){++nowpos;if(nowpos==pos){now->value=val;return;} now=now->next;}}void reassign(ListNode<T>* now,const int &val) const {now->value=val;}void pop_back(){if(empty()) return;ListNode<T>* now=endnode->last;ListNode<T>* pre=now->last;if(pre==headnode){endnode->last=NULL;headnode->next=NULL;delete now;--listsize; return;}endnode->last=pre;pre->next=endnode;delete now;--listsize;}void pop_front(){if(empty()) return;ListNode<T>* now=headnode->next;ListNode<T>* suf=now->next;if(suf==endnode){endnode->last=NULL;headnode->next=NULL;delete now;--listsize; return;}headnode->next=suf;suf->last=headnode;delete now;--listsize;}void erase(const int &pos) {if(pos>listsize) return;if(empty()||!pos) return;ListNode<T>* now=headnode->next;int nowpos=0;while(now!=endnode){++nowpos;if(nowpos==pos){ListNode<T>* pre=now->last;ListNode<T>* suf=now->next;if(pre==headnode||suf==endnode){endnode->last=NULL;headnode->next=NULL;delete now;--listsize; return;}pre->next=suf;suf->last=pre;delete now;--listsize; return;}now=now->next;}}void erase(ListNode<T>* now){  if(now==headnode) return;if(now==endnode) return;if(empty()) return;ListNode<T>* pre=now->last;ListNode<T>* suf=now->next;if(pre==headnode||suf==endnode){endnode->last=NULL;headnode->last=NULL;delete now;--listsize; return;}pre->next=suf;suf->last=pre;delete now;--listsize; return;}void swap(list<T> &b){ListNode<T>* temp;temp=headnode;headnode=b.headnode;b.headnode=temp;temp=endnode;endnode=b.endnode;b.endnode=temp;unsigned size_t=listsize;listsize=b.listsize;b.listsize=size_t;}~list(){ListNode<T>* now=headnode->next;while(now!=NULL){ListNode<T>* nxt=now->next;delete now;now=nxt;} delete headnode;listsize=0;}};
}
using STL::list;signed main(){system("pause");
}

给个赞再走吧

相关文章:

【数据结构】双向链表 C++

一、什么是双向链表 1、定义 双向链表也叫双链表&#xff0c;是链表的一种&#xff0c;它的每个数据结点中都有两个指针&#xff0c;分别指向直接后继和直接前驱。所以&#xff0c;从双向链表中的任意一个结点开始&#xff0c;都可以很方便地访问它的前驱结点和后继结点。 双…...

消息队列之-----------------zookeeper机制

目录 一、ZooKeeper是什么 二、ZooKeeper的工作机制 三、ZooKeeper特点 四、ZooKeeper数据结构 五、ZooKeeper应用场景 5.1统一命名服务 5.2统一配置管理 5.3统一集群管理 5.4服务器动态上下线 5.5软负载均衡 六、ZooKeeper的选举机制 6.1第一次启动选举机制 6.2非…...

第十届蓝桥杯大赛个人赛省赛(软件类) CC++ 研究生组2.0

A立方和 #include<iostream> #include<cmath> using namespace std; int main(){int n, t, flag, x;long long ans 0;for(int i 1; i < 2019; i){t i;flag 0;while(t && !flag){x t % 10;if(x 2 || x 0 || x 1 || x 9) flag 1;t / 10;}if(fl…...

vscode开发ESP32问题记录

vscode 开发ESP32问题记录 1. 解决vscode中的波浪线警告 1. 解决vscode中的波浪线警告 参考链接&#xff1a;https://blog.csdn.net/fucingman/article/details/134404485 首先可以通过vscode 中的IDF插件生成模板工程&#xff0c;这样会自动创建.vscode文件夹中的一些json配…...

R语言复现:轨迹增长模型发表二区文章 | 潜变量模型系列(2)

培训通知 Nhanes数据库数据挖掘&#xff0c;快速发表发文的利器&#xff0c;你来试试吧&#xff01;欢迎报名郑老师团队统计课程&#xff0c;4.20直播。 案例分享 2022年9月&#xff0c;中国四川大学学者在《Journal of Psychosomatic Research》&#xff08;二区&#xff0c;I…...

【数据结构】顺序表的实现——动态分配

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;数据结构 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…...

3.3.k8s搭建-rancher RKE2

目录 RKE2介绍 k8s集群搭建 搭建k8s集群 下载离线包 部署rke2-server 部署rke2-agent 部署helm 部署rancher RKE2介绍 RKE2&#xff0c;也称为 RKE Government&#xff0c;是 Rancher 的下一代 Kubernetes 发行版。 官网地址&#xff1a;Introduction | RKE2 k8s集群搭…...

CST电磁仿真软件的设置变更与问题【官方教程】

保存结果的Result Navigator 积累的结果一目了然&#xff01; 用户界面上的Result Navigator 在一个仿真工程中更改变量取值进行仿真分析或者改变设置进行仿真分析时&#xff0c;之前的1DResult会不会消失呢&#xff1f; 1D Result&#xff1a;CST中1D Result指的是Y值取决…...

保研线性代数复习3

一.基底&#xff08;Basis&#xff09; 1.什么是生成集&#xff08;Generating Set&#xff09;&#xff1f;什么是张成空间&#xff08;Span&#xff09;&#xff1f; 存在向量空间V(V&#xff0c;&#xff0c;*)&#xff0c;和向量集&#xff08;xi是所说的列向量&#xff…...

从零开始学Spring Boot系列-集成MyBatis-Plus

在Spring Boot应用开发中&#xff0c;MyBatis-Plus是一个强大且易于使用的MyBatis增强工具&#xff0c;它提供了很多实用的功能&#xff0c;如代码生成器、条件构造器、分页插件等&#xff0c;极大地简化了MyBatis的使用和配置。本篇文章将指导大家如何在Spring Boot项目中集成…...

【云原生篇】k8s之Deployment详解

Kubernetes 的 Deployment 是一种管理声明式更新的资源对象&#xff0c;它允许你描述应用的期望状态&#xff0c;并由 Deployment 控制器自动将当前状态改变为期望状态。Deployment 主要用于无状态应用的部署和扩展&#xff0c;但也可以用于有状态应用。 核心功能 自动化部署…...

linux安装dubboAdmin

1.环境准备&#xff1a; jdk-8u391-linux-x64apache-maven-3.9.6apache-tomcat-8.5.100 2.安装注册中心zookeeper zookeeper的安装看我的另一篇文章&#xff0c;安装完成后保持启动状态 linux安装Zookeeper的详细步骤-CSDN博客 3.安装dubboadmin 源码下载地址&#xff1a;R…...

Android 系统编译 and 应用裁剪

平台应用编译 平台应用demo的Android.mk写法: LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS)LOCAL_MODULE_TAGS := optional# Only compile source java files in this apk. LOCAL_SRC_FILES := $(call all-java-files-under, src)LOCAL_PACKAGE_NAME := TestLOCAL_CER…...

java数组.day16(冒泡排序,稀疏数组)

冒泡排序 冒泡排序无疑是最为出名的排序算法之一&#xff0c;总共有八大排序! 冒泡的代码还是相当简单的&#xff0c;两层循环&#xff0c;外层冒泡轮数&#xff0c;里层依次比较&#xff0c;江湖中人人尽皆知。 我们看到嵌套循环&#xff0c;应该立马就可以得出这个算法的时…...

vue+springboot多角色登录

①前端编写 将Homeview修改为manager Manager&#xff1a; <template><div><el-container><!-- 侧边栏 --><el-aside :width"asideWidth" style"min-height: 100vh; background-color: #001529"><div style"h…...

使用 ADB 查找应用名称和活动名称,并启动指定页面

知识点和难题&#xff1a; 查找应用名称和活动名称&#xff1a; 使用 ADB 命令 adb shell dumpsys window | findstr mCurrentFocus 可以查找当前设备上活动的应用名称和活动名称。 保存输出结果&#xff1a; 将命令的输出结果保存到文件中&#xff0c;方便后续使用。 启动指…...

LangChain - 文档转换

文章目录 一、文档转换器 & 文本拆分器文本拆分器 二、开始使用文本拆分器三、按字符进行拆分四、代码分割 (Split code)1、PythonTextSplitter2、JS3、Markdown4、Latex5、HTML6、Solidity 五、MarkdownHeaderTextSplitter1、动机2、Use case 六、递归按字符分割七、按tok…...

【C++】STL--list

目录 list的介绍 list的使用 list的构造 list iterator的使用 list capacity list modifiers list的迭代器失效 list模拟实现 list的介绍 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 2. list的底层是双向…...

二. CUDA编程入门-双线性插值计算

目录 前言0. 简述1. 执行一下我们的第十个CUDA程序2. Bilinear interpolation3. 代码分析总结参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 Note&#xff1a;关于 CUDA 加速双线程插值的内容博主…...

实时计算平台设计方案:913-基于100G光口的DSP+FPGA实时计算平台

基于100G光口的DSPFPGA实时计算平台 一、产品概述 基于以太网接口的实时数据智能计算一直应用于互联网、网络安全、大数据交换的场景。以DSPFPGA的方案&#xff0c;体现了基于硬件计算的独特性能&#xff0c;区别于X86GPU的计算方案&#xff0c;保留了高带宽特性&…...

Glide系列-自定义ModuleLoader

在当今快速发展的移动应用领域&#xff0c;图片的高效加载和显示对于提供流畅用户体验至关重要。Glide作为一款强大的图片加载库&#xff0c;已经成为Android开发者的首选工具之一。但是&#xff0c;你有没有遇到过Glide默认不支持的模型类型&#xff0c;或者需要对图片加载过程…...

设计模式——责任链模式13

责任链模式 每个流程或事物处理 像一个链表结构处理。场景由 多层部门审批&#xff0c;问题分级处理等。下面体现的是 不同难度的问题由不同人进行解决。 设计模式&#xff0c;一定要敲代码理解 传递问题实体 /*** author ggbond* date 2024年04月10日 07:48*/ public class…...

Linux云计算之Linux基础3——Linux系统基础part-2

1、终端、shell、文件理论 1、终端 终端(terminal)&#xff1a;人和系统交互的必要设备&#xff0c;人机交互最后一个界面&#xff08;包含独立的输入输出设备&#xff09; 物理终端(console)&#xff1a;直接接入本机器的键盘设备和显示器虚拟终端(tty)&#xff1a;通过软件…...

HBase详解(2)

HBase 结构 HRegion 概述 在HBase中&#xff0c;会从行键方向上对表来进行切分&#xff0c;切分出来的每一个结构称之为是一个HRegion 切分之后&#xff0c;每一个HRegion会交给某一个HRegionServer来进行管理。HRegionServer是HBase的从节点&#xff0c;每一个HRegionServ…...

Web后端搭建

目录 一 搭建服务器端 1.1安装服务器软件 1.2检查环境是否配置 1.3安装Tomcat 二 创建并发Web项目 2.1创建一个java项目 三 创建Servlet 前端程序如何才能访问到后端程序呢&#xff0c;这时候我们就需要web服务器来解决&#xff1a;将后端程序部署到服务器中&#xff0c…...

k8s单节点部署,容器运行时使用containerd

环境 系统 &#xff1a; entOS Linux release 7.9.2009 (CoreIP&#xff1a;192.168.44.177 硬件要求&#xff1a;控制平面最少需要 2c2g 安装前环境准备 如果是集群部署还需要配置时间同步 关闭防火墙 systemctl disable firewalld关闭selinux setenforce 0sed -i s/SELI…...

深入浅出 -- 系统架构之性能优化的核心思维

“在当前的互联网开发模式下&#xff0c;系统访问量日涨、并发暴增、线上瓶颈等各种性能问题纷涌而至&#xff0c;性能优化成为了现时代开发过程中炙手可热的名词&#xff0c;无论是在开发、面试过程中&#xff0c;性能优化都是一个常谈常新的话题”。Java语言作为企业应用中的…...

Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066

很奇怪的问题,在使用nifi的时候碰到的,这里是用NIFI,把数据从postgresql中同步到mysql中, 首先postgresql中的源表,中是没有create_time这个字段的,但是同步的过程中报错了. 报错的内容是说,目标表中有个create_time字段,这个字段是必填的,但是传过来的flowfile文件中,的数据没…...

批量删除文件脚本

在工作中我们经常会遇到一些重复性的工作&#xff0c;如批量创建文件&#xff0c;删除文件等等。这种重复性的工作shell脚本往往能给我们带来极大的便利。 将需要删除的文件路径存放在【stt_Files_240410.rpt】随便一个 文档中即可。 下面是一个批量删除文件的一个脚本范例&…...

蓝桥杯物联网竞赛_STM32L071KBU6_我的全部省赛及历年模拟赛源码

我写的省赛及历年模拟赛代码 链接&#xff1a;https://pan.baidu.com/s/1A0N_VUl2YfrTX96g3E8TfQ?pwd9k6o 提取码&#xff1a;9k6o...