python之数组,链表,栈,队列

1.数组

优点:

  • 索引操作速度快:通过索引可以直接访问元素,因此索引操作的时间复杂度是 $O(1)$,即常数级

缺点:

  • 插入、删除元素慢: 如果需要在中间或开始位置插入或删除元素,可能需要移动大量元素,因此这样的操作的时间复杂度是$O(n)$
  • 预先设置空间大小: 数组通常需要预先设置空间大小,这意味着在创建时需要估计数据的大小,并为其分配足够的内存空间。如果数组大小不够,可能需要重新分配内存并复制数据,这会带来额外的开销。如果数组太多,浪费空间

需要的参数:数组名称,大小,采用索引进行各种操作

2.链表

优点:

  • 不需要预先知道数据大小,实现灵活的内存动态管理
  • 插入、删除指定数据速度快

缺点:

  • 读取指定位置数据速度慢
  • 空间开销比较大

分类

单向链表

链表中最简单的一种是单向链表,它包含两个域,一个信息域和一个指针域。这个链接指向列表中的下一个节点,而最后一个节点则指向一个空值

需要的参数:节点的值,节点的后一个节点

循环链表(环形链表)

在一个循环链表中, 首节点和末节点被连接在一起,要遍历一个循环链表,可以开始于任意一个节点然后沿着列表的任一方向直到返回开始的节点

双向链表

一种更复杂的链表是"双向链表"或"双面链表",每个节点有两个连接:一个指向前一个节点,(当此"连接"为第一个"连接"时,指向空值或者空列表);而另一个指向下一个节点, (当此“连接”为最后一个“连接”时,指向空值或者空列表)

需要的参数:节点的值,节点的前一个节点,节点的后一个节点

3.栈

特点:

  1. 先入后出,后入先出
  2. 除头尾节点之外,每个元素有一个前驱,一个后继

栈的结构是先进后出,类似于子弹的弹夹, 计算机结构如图:

4.队列

特点:

队列(queue)是一种遵循先入先出规则的线性数据结构,只允许在有序的线性结构集合的一端(队尾)进行加入数据(push)和 另一端(队首)移除数据(pop)的运算。

  1. 先入先出,后入后出
  2. 除头尾节点之外,每个元素有一个前驱,一个后继

5.双向对列

双向队列 ,就是在队列的基础上增加一个双端操作的功能。允许在头部和尾部执行元素的添加或删除操作

栈,队列,双向队列都可以用数组和链表表示

6.各种实现代码

6.1单链表

class ListNode:
    
    def __init__(self,val:int):
        self.val=val
        self.next=None
class MyLinkNode:
    def __init__(self):
        self.size=0
        self.head=ListNode(0)
    def add_index(self,val:int,index:int):
        if index>self.size:
            return -1
        index=max(0,index)
        add_node=ListNode(val)
        pre=self.head
        for _ in range(index):
            pre=pre.next
        add_node.next=pre.next
        pre.next=add_node
        self.size+=1
    def add_head(self,val:int):
        self.add_index(val,0)
    def add_tail(self,val:int):
        self.add_index(val,self.size)
    def get(self,index:int):
        if index<0 or index>=self.size:
            return -1
        pred=self.head
        for _ in range(index+1):
            pred=pred.next
        return pred.val
    def delete(self,index:int):
        if index<0 or index>=self.size:
            return -1
        pred=self.head
        for _ in range(index):
            pred=pred.next
        pred.next=pred.next.next
        self.size-=1
    def traverse(self):
        cur=self.head.next
        while cur:
            print(cur.val)
            cur=cur.next
if __name__=='__main__':
    link=MyLinkNode()
    link.add_tail(1)
    link.add_tail(2)
    link.add_tail(3)
    link.add_tail(4)
    link.add_index(8,2)
    link.delete(3)
    link.traverse()

6.2双向链表

class ListNode:
    def __init__(self,val):
        self.val=val
        self.next=None
        self.pre=None
class MyListNode:
    def __init__(self):
        self.head=ListNode(0)
        self.tail=ListNode(0)
        self.head.next=self.tail
        self.tail.pre=self.head
        self.size=0
    def add_index(self,index:int,val:int):
        if index>self.size:
            return -1
        else:
            if index<self.size-index:
                pred=self.head
                for _ in range(index):
                    pred=pred.next
                succ=pred.next
            else:
                succ=self.tail
                for _ in range(self.size-index):
                    succ=succ.pre
                pred=succ.pre
            add_node=ListNode(val)
            add_node.next=succ
            add_node.pre=pred
            pred.next=add_node
            succ.pre=add_node
            self.size+=1
    def add_head(self,val):
        self.add_index(0,val)
    def add_tail(self,val):
        self.add_index(self.size,val)
    def get(self,index):
        if index<0 or index>=self.size:
            return -1
        else:
            if index<self.size-index:
                cur=self.head
                for _ in range(index+1):
                    cur=cur.next
                return cur.val
            else:
                cur=self.tail
                for _ in range(self.size-index+1):
                    cur=cur.pre
                return cur.val
    def delete(self,index):
        if index<0 or index>=self.size:
            return -1
        else:
            if index<self.size-index:
                pred=self.head
                for _ in range(index):
                    pred=pred.next
                succ=pred.next.next
            else:
                succ=self.tail
                for _ in range(self.size-index-1):
                    succ=succ.pre
                pred=succ.pre.pre
            pred.next=succ
            succ.pre=pred
        self.size-=1
        
    def print_all(self):
        cur=self.head
        while cur:
            print(cur.val)
            cur=cur.next
if __name__=='__main__':
    link=MyListNode()
    link.add_tail(1)
    link.add_tail(2)
    link.add_tail(3)
    link.add_tail(4)
    link.add_tail(5)
    # link.delete(0)
    link.add_index(3,8)
    link.add_index(6,8)
    link.add_tail(11)
    link.add_head(20)
    link.print_all()

6.3循环链表

class ListNode:
    
    def __init__(self,val:int):
        self.val=val
        self.next=None
class MyLinkNode:
    def __init__(self):
        self.size=0
        self.head=ListNode(0)
        self.head.next=self.head
    def add_index(self,val:int,index:int):
        if index>self.size:
            return -1
        index=max(0,index)
        add_node=ListNode(val)
        pre=self.head
        for _ in range(index):
            pre=pre.next
        add_node.next=pre.next
        pre.next=add_node
        self.size+=1
    def add_head(self,val:int):
        self.add_index(val,0)
    def add_tail(self,val:int):
        self.add_index(val,self.size)
    def get(self,index:int):
        if index<0 or index>=self.size:
            return -1
        pred=self.head
        for _ in range(index+1):
            pred=pred.next
        return pred.val
    def delete(self,index:int):
        if index<0 or index>=self.size:
            return -1
        pred=self.head
        for _ in range(index):
            pred=pred.next
        pred.next=pred.next.next
        self.size-=1
    def traverse(self):
        cur=self.head.next
        count=1
        while cur:
            print(cur.val)
            cur=cur.next
            count+=1
            if count>self.size+3:
                break
if __name__=='__main__':
    link=MyLinkNode()
    link.add_tail(1)
    link.add_tail(2)
    link.add_tail(3)
    link.add_tail(4)
    link.traverse()

6.4栈——数组表示

class ArrayStack:
    def __init__(self):
        self.data:list[int]=[]
    def push(self,val):
        self.data.append(val)
    def pop(self):
        if self.is_empty():
            raise Exception('栈为空')
        else:
            return self.data.pop()
    def is_empty(self):
        return len(self.data)==0
    def top(self):
        if self.is_empty():
            raise Exception('栈为空')
        else:
            return(self.data[-1])
    def to_list(self):
        return self.data
if __name__=='__main__':
        stack=ArrayStack()
        stack.push(1)
        stack.push(2)
        stack.push(3)
        stack.push(4)
        print(stack.to_list())
        print(stack.top())
        stack.pop()
        print(stack.to_list())

6.5栈——链表表示

class ListNode:
  def __init__(self,val:int):
    self.val: int = val
    self.next = None


class LinkedListStack:
  def __init__(self):
    self.flag: ListNode|None = None
    self._size: int = 0


  def size(self) -> int:
    '''
     获取栈中元素的个数
     '''
    return self._size
  
  def is_empty(self) -> bool:
    '''
     判断栈是否为空
     '''
    return self._size == 0
  
  def push(self, val: int) -> None:
    '''
     入栈
     '''
    # 创建节点
    node = ListNode(val)
    # 将新节点的next指向原来的栈顶元素
    node.next = self.flag
    # 将栈顶指针指向新节点
    self.flag = node
    # 栈中元素个数+1
    self._size += 1
  def pop(self) -> int:
    '''
     出栈
     '''
    # 获取栈顶元素的值
    data = self.top()
    #  将栈顶指针指向栈顶元素的下一个元素
    self.flag = self.flag.next
    # 栈中元素个数-1
    self._size -= 1


    return data
  def top(self)-> int:
    '''
     获取栈顶元素
     '''
    if self.is_empty():
      raise Exception('Stack is empty')
    return self.flag.val
  def to_list(self):
    '''
     将栈转换为列表
     '''
    result = []
    # 获取栈顶元素
    node = self.flag
    # 判断栈顶元素是否为空
    while node:
      result.append(node.val)
      node = node.next
    return result


if __name__ =='__main__':
  stack = LinkedListStack()
  stack.push(1)
  stack.push(2)
  stack.push(3)


  print(stack.to_list())
  print(f'获取栈顶元素:{stack.top()}')
  print(stack.to_list())
  print(f'出栈:{stack.pop()}')
  print(f'栈的元素个数:{stack.size()}')
  print(f'栈是否为空:{stack.is_empty()}')

6.6队列——数组表示

class MyQueue:
  def __init__(self):
    self.items = []
  
  def push(self,val:int) ->None:
    '''
     入队
     '''
    self.items.append(val)


  def pop(self) ->int:
    '''
     出队
     '''
    return self.items.pop(0)
  
  def size(self) ->int:
    '''
     队列大小
     '''
    return len(self.items)
  
  def is_empty(self) ->bool:
    '''
     队列是否为空
     '''
    return self.size() == 0
  
  def peek(self) ->int:
    '''
     获取队首元素
     '''
    return self.items[0]
  
  def to_list(self) ->list:
    '''
     转换为列表
     '''
    return self.items




if __name__ == '__main__':
  queue = MyQueue()
  queue.push(1)
  queue.push(2)
  queue.push(3)
  print(f'转成列表后:{queue.to_list()}')
  print(f'出队:{queue.pop()}')
  print(f'转成列表后:{queue.to_list()}')
  print(f'访问队首元素:{queue.peek()}')
  print(f'转成列表后:{queue.to_list()}')
  print(f'队列是否为空:{queue.is_empty()}')
  print(f'队列是元素个数:{queue.size()}')

6.7队列——链表表示

class MyQueue:
  def __init__(self):
    self.items = []
  
  def push(self,val:int) ->None:
    '''
     入队
     '''
    self.items.append(val)


  def pop(self) ->int:
    '''
     出队
     '''
    return self.items.pop(0)
  
  def size(self) ->int:
    '''
     队列大小
     '''
    return len(self.items)
  
  def is_empty(self) ->bool:
    '''
     队列是否为空
     '''
    return self.size() == 0
  
  def peek(self) ->int:
    '''
     获取队首元素
     '''
    return self.items[0]
  
  def to_list(self) ->list:
    '''
     转换为列表
     '''
    return self.items




if __name__ == '__main__':
  queue = MyQueue()
  queue.push(1)
  queue.push(2)
  queue.push(3)
  print(f'转成列表后:{queue.to_list()}')
  print(f'出队:{queue.pop()}')
  print(f'转成列表后:{queue.to_list()}')
  print(f'访问队首元素:{queue.peek()}')
  print(f'转成列表后:{queue.to_list()}')
  print(f'队列是否为空:{queue.is_empty()}')
  print(f'队列是元素个数:{queue.size()}')

6.8双向队列-数组表示

class ArrayDeque:
  def __init__(self,capacity:int=8):
    self._data = [0] * capacity # 存储数据的数组
    self._head = 0       # 队头元素的下标
    self._size = 0       # 队列中元素的个数
  
  def capacity(self):
    '''返回队列的容量'''
    return len(self._data)
  
  def is_empty(self) -> bool:
    '''判断队列是否为空'''
    return self._size == 0
  
  def index(self,i:int) -> int:
    '''获取指定正确的索引'''
    return (i+self.capacity())%self.capacity()
  def peek_first(self) -> int:
    '''查看队头元素'''
    if self.is_empty():
      raise Exception("Deque is empty")
    return self._data[self._head]
  
  def peek_last(self) -> int:
    '''查看队尾元素'''
    if self.is_empty():
      raise Exception("Deque is empty")
    # 获取队尾元素的下标
    i = self.index(self._head + self._size - 1)
    return self._data[i]
  
  def push_last(self,val:int):
    '''增加队尾元素'''
    # 判断队列是否已满
    if self._size == self.capacity():
      raise Exception("Deque is full")
    # 获取队尾元素的下标
    i = self.index(self._head + self._size)
    # 将元素添加到队尾
    self._data[i] = val
    # 队列中元素的个数加1
    self._size += 1
  def push_first(self,val:int):
    '''增加队头元素'''
    # 判断队列是否已满
    if self._size == self.capacity():
      raise Exception("Deque is full")
    # 获取队头元素的下标
    i = self.index(self._head - 1)
    # 将元素添加到队头
    self._data[i] = val
    # 队列中元素的个数加1
    self._size += 1
    # 修改队头元素的下标
    self._head = i
  def pop_first(self) -> int:
    '''删除队头元素'''
    if self.is_empty():
      raise Exception("Deque is empty")
    # 获取队头元素的值
    val = self.peek_first()
    # 修改队头元素的下标
    self._head = self.index(self._head + 1)
    # 队列中元素的个数减1
    self._size -= 1
    return val
  def pop_last(self) -> int:
    '''删除队尾元素'''
    if self.is_empty():
      raise Exception("Deque is empty")
    # 获取队尾元素的值
    val = self.peek_last()
    # 队列中元素的个数减1
    self._size -= 1
    return val


  def to_list(self):
    '''转换为列表'''
    res = []
    for i in range(self._size):
      tmp_index = self.index(self._head + i)
      res.append(self._data[tmp_index])
    return res


if __name__ == "__main__":
  deque = ArrayDeque(5)
  deque.push_last(1)
  deque.push_last(2)
  deque.push_last(3)
  deque.push_last(4)
  deque.push_last(5)
  print(deque.to_list())   #  [1,2,3,4,5]
  deque.pop_first()      #  1
  deque.push_last(6)     #  [2,3,4,5,6]
  print(deque.to_list())   #  [2,3,4,5,6]
  print(f'队尾拿到数据:{deque.pop_last()}')  #  6
  deque.push_first(7)     # [7,2,3,4,5]
  print(deque.to_list())   # [7,2,3,4,5]

6.9双向队列-链表表示

class ArrayDeque:
  def __init__(self,capacity:int=8):
    self._data = [0] * capacity # 存储数据的数组
    self._head = 0       # 队头元素的下标
    self._size = 0       # 队列中元素的个数
  
  def capacity(self):
    '''返回队列的容量'''
    return len(self._data)
  
  def is_empty(self) -> bool:
    '''判断队列是否为空'''
    return self._size == 0
  
  def index(self,i:int) -> int:
    '''获取指定正确的索引'''
    return (i+self.capacity())%self.capacity()
  def peek_first(self) -> int:
    '''查看队头元素'''
    if self.is_empty():
      raise Exception("Deque is empty")
    return self._data[self._head]
  
  def peek_last(self) -> int:
    '''查看队尾元素'''
    if self.is_empty():
      raise Exception("Deque is empty")
    # 获取队尾元素的下标
    i = self.index(self._head + self._size - 1)
    return self._data[i]
  
  def push_last(self,val:int):
    '''增加队尾元素'''
    # 判断队列是否已满
    if self._size == self.capacity():
      raise Exception("Deque is full")
    # 获取队尾元素的下标
    i = self.index(self._head + self._size)
    # 将元素添加到队尾
    self._data[i] = val
    # 队列中元素的个数加1
    self._size += 1
  def push_first(self,val:int):
    '''增加队头元素'''
    # 判断队列是否已满
    if self._size == self.capacity():
      raise Exception("Deque is full")
    # 获取队头元素的下标
    i = self.index(self._head - 1)
    # 将元素添加到队头
    self._data[i] = val
    # 队列中元素的个数加1
    self._size += 1
    # 修改队头元素的下标
    self._head = i
  def pop_first(self) -> int:
    '''删除队头元素'''
    if self.is_empty():
      raise Exception("Deque is empty")
    # 获取队头元素的值
    val = self.peek_first()
    # 修改队头元素的下标
    self._head = self.index(self._head + 1)
    # 队列中元素的个数减1
    self._size -= 1
    return val
  def pop_last(self) -> int:
    '''删除队尾元素'''
    if self.is_empty():
      raise Exception("Deque is empty")
    # 获取队尾元素的值
    val = self.peek_last()
    # 队列中元素的个数减1
    self._size -= 1
    return val


  def to_list(self):
    '''转换为列表'''
    res = []
    for i in range(self._size):
      tmp_index = self.index(self._head + i)
      res.append(self._data[tmp_index])
    return res


if __name__ == "__main__":
  deque = ArrayDeque(5)
  deque.push_last(1)
  deque.push_last(2)
  deque.push_last(3)
  deque.push_last(4)
  deque.push_last(5)
  print(deque.to_list())   #  [1,2,3,4,5]
  deque.pop_first()      #  1
  deque.push_last(6)     #  [2,3,4,5,6]
  print(deque.to_list())   #  [2,3,4,5,6]
  print(f'队尾拿到数据:{deque.pop_last()}')  #  6
  deque.push_first(7)     # [7,2,3,4,5]
  print(deque.to_list())   # [7,2,3,4,5]

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

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

相关文章

漫漫数学之旅036

文章目录 经典格言数学习题古今评注名人小传 - 爱因斯坦 经典格言 纯数学在其领域内是逻辑思想的诗歌。——阿尔伯特爱因斯坦 “纯数学在其领域内是逻辑思想的诗歌”这句话体现了爱因斯坦对数学的深刻理解和热爱。在这句话中&#xff0c;爱因斯坦将纯数学比作诗歌&#xff0c;…

mmdetection如何计算准确率、召回率、F1值

1、训练 python tools/train.py configs/fcos/fcosrdweed3.py 2、测试 这一步要加–outresult.pkl&#xff0c;才能计算准确率和召回率 python tools/test.py configs/fcos/fcosrddweed3.py work_dirs/fcosrddweed3/epoch_300.pth --outresultfcos.pkl3、计算准确率和召回率…

三维GIS的业务导向

的确&#xff0c;目前三维GIS以做特效居多&#xff0c;酷炫、亮眼&#xff0c;从二维转到三维&#xff0c;第一眼就给人眼前一亮的感觉&#xff0c;就凭这一项&#xff0c;很多客户就会买单&#xff0c;GIS的客户以政府、科研院所、特种行业为主&#xff0c;买过一次单后&#…

riscv简单常用汇编指令xv6

文章目录 前言entry.Smretasm volatileread csrwrite csrriscv常见csr寄存器 ecall, 系统调用指令cpu执行异常处理指令的三种事件 异常处理相关寄存器用户态trapsret指令页表切换操作用户态系统调用过程总结 内核态trap缺页异常 中断与设备驱动Locking调度文件系统操作系统拥有…

Docker完整版(一)

Docker完整版&#xff08;一&#xff09; 一、Docker概述1.1、Docker简介1.2、Docker的用途1.3、容器与虚拟机的区别1.4、Docker系统架构1.5、Docker仓库 二、Docker引擎2.1、Docker引擎架构2.2、Docker引擎分类2.3、Docker引擎的安装2.4、Docker镜像加速器 三、Docker镜像3.1、…

Android 完整SDK项目中添加对应的JNI与底层通信

安卓应用发消息给底层 近日需要写一个安卓app和底层发消息&#xff0c;这就涉及到java如何到c层的一个逻辑&#xff0c;app已经写好&#xff0c;就差发个消息了。至于如何对接底层&#xff0c;得和写底层的人进一步沟通&#xff0c;本文笔者只写从java层通信到cpp&#xff0c;…

视频远程监控平台EasyCVR集成后播放只有一帧画面的原因排查与解决

智慧安防视频监控平台EasyCVR能在复杂的网络环境中&#xff08;专网、局域网、广域网、VPN、公网等&#xff09;将前端海量的设备进行统一集中接入与视频汇聚管理&#xff0c;平台可支持的接入协议包括&#xff1a;国标GB28181、RTSP/Onvif、RTMP&#xff0c;以及厂家的私有协议…

C++ 字符串OJ

目录 1、14. 最长公共前缀 2、 5. 最长回文子串 3、 67. 二进制求和 4、43. 字符串相乘 1、14. 最长公共前缀 思路一&#xff1a;两两字符串进行比较&#xff0c;每次比较过程相同&#xff0c;可以添加一个函数辅助比较&#xff0c;查找最长公共前缀。 class Solution { pu…

Vue.set:Vue中的数据绑定利器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【JAVA/Web】数组转对象

一. 需求 数组转对象 数组结构 List:[{id:1,code:phone,value:10101001},{id:2,code:name,value:admin},{id:3,code:address,value:XXXXXX} ]二. 数组转对象&#xff08;键值对映射关系&#xff09; 对象结构 object:{phone:10101001,name:admin,address:XXXXXX }2.1 Java…

Java Socket:飞鸽传书的网络套接字

套接字&#xff08;Socket&#xff09;是一个抽象层&#xff0c;应用程序可以通过它发送或接收数据&#xff1b;就像操作文件那样可以打开、读写和关闭。套接字允许应用程序将 I/O 应用于网络中&#xff0c;并与其他应用程序进行通信。网络套接字是 IP 地址与端口的组合。 01、…

VUE3 使用axios网络请求

1.新建工程 参考&#xff0c;VUE3 环境搭建&#xff1a;https://blog.csdn.net/LQ_001/article/details/136293795&#xff0c;运行命令 vue create vue-demo 2.引入axios 不管何种引用&#xff0c;都要在工程中安装 axios 包。安装命令&#xff1a;npm install --save axio…

linux paddle For C++环境搭建

paddle介绍 Paddle是类似tesseract的文字识别ocr。因为tesseract-ocr的中文识别效果不好。因此才准备安装Paddle。Paddle最方便的安装方式的使用Python的包管理安装。pip3 install paddlepaddle。但我使用了一下感觉还是用C更加方便&#xff0c;QT OpenCV Paddle应当还不错。…

Go语言必知必会100问题-19 浮点数溢出问题

问题呈现 在Go语言中&#xff0c;有两种浮点数类型&#xff08;虚数除外&#xff09;&#xff1a;float32和float64. 浮点数是用来解决整数不能表示小数的问题。我们需要知道浮点数算术运算是实数算术运算的近似&#xff0c;下面通过例子说明浮点数运算采用近似值的影响以及如…

⭐每天一道leetcode:83.删除排序链表中的重复元素(简单;链表遍历、删除经典题目)

⭐今日份题目 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 示例1 输入&#xff1a;head [1,1,2] 输出&#xff1a;[1,2] 示例2 输入&#xff1a;head [1,1,2,3,3] 输出&#xff1a;[1,2,3] …

【R语言爬虫实战】抓取省市级城市常务会议内容

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

enumerate函数的用法

enumerate() 函数是 Python 内置函数之一&#xff0c;用于同时返回可迭代对象的索引和对应的值。 它的语法结构如下&#xff1a; enumerate(iterable, start0) iterable: 表示一个可迭代的对象&#xff0c;如列表、元组、字符串等。start: 可选参数&#xff0c;表示索引起始…

02hadoop伪分布式搭建

3. 环境安装 3.1 安装方式 单机模式 只能启动MapReduce 伪分布式 能启动HDFS、MapReduce 和 YARN的大部分功能 完全分布式 能启动Hadoop的所有功能 3.2 安装JDK 3.2.1 JDK安装步骤 下载JDK安装包&#xff08;下载Linux系统的 .tar.gz 的安装包&#xff09; https://www…

网络协议常见问题

网络协议常见问题 OSI&#xff08;Open Systems Interconnection&#xff09;模型OSI 封装 TCP/IP协议栈IP数据报的报头TCP头格式UDP头格式TCP (3-way shake)三次握手建立连接&#xff1a;为什么三次握手才可以初始化 Socket、序列号和窗口大小并建立 TCP 连接。每次建立TCP连接…

蓝桥杯递推与递归法|斐波那契数列|数字三角形|42点问题|数的计算|数的划分(C++)

递归是用来做dfs&#xff0c;是搜索算法的基础 递推是用来做dp部分&#xff0c;及部分其他算法&#xff0c;复杂度较低&#xff0c;不会出现爆栈问题递推法&#xff1a; 递推法是一种在数学和其他领域广泛应用的重要方法&#xff0c;它在计算机科学中被用作一种关键的数值求解…