数据结构(JS实现)

news2024/12/22 14:46:19

目录

  • 链表
    • 链表的特点
    • 链表中的常见操作
    • 单链表
      • append(data)尾部追加新节点
      • toString()输出链表的节点数据
      • 插入节点insert(position,data)
      • get(position)获取链表指定位置节点的数据
      • indexOf(data)查找对应数据节点的位置
      • update(position, newData)更新指定位置节点数据
      • removeAt(position)删除指定位置的节点
      • remove(data)删除第一个数据为data的节点
      • isEmpty()判断链表是否为空
      • size()返回链表长度
      • 单链表构造函数完整实现
    • 经典相关算法题
      • 链表反转
  • 数组
  • 哈希表/散列表
    • 完美二叉树(Perfect Binary Tree)/满二叉树(Full Binary Tree)
    • 完全二叉树(Compelete Binary Tree)
    • 二叉搜索树/二叉查找树/二叉排序树(Binary Search Tree,简称BST)

链表

与数组不同,我们无法在常量时间内访问单链表中的随机元素。 如果我们想要获得第 i 个元素,我们必须从头结点逐个遍历。 我们按索引来访问元素平均要花费 O(N) 时间,其中 N 是链表的长度。

  • 查找时间复杂度:O(n)

创建单向链表类

// 封装链表的构造函数
function LinkedList() {
    //封装一个Node类,用于保存每个节点信息
    function Node(data,next) {
        this.data = data
        this.next = (next===undefined ? null : next)
    }
    // 链表中的属性
    this.length = 0 // 链表的长度
    this.head = null //链表的第一个节点
}

ES6

class LinkedList{
	constructor Node(data,next) {
        this.data = data
        this.next = (next===undefined ? null : next)
        // 链表中的属性
    	this.length = 0 // 链表的长度
    	this.head = null //链表的第一个节点
    }
}

链表的特点

链表和数组一样,可以用于存储一系列的元素,但是链表和数组的实现机制完全不同。链表的每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(有的语言称为指针或连接)组成。类似于火车头,一节车厢载着乘客(数据),通过节点连接另一节车厢。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • head属性指向链表的第一个节点;
  • 链表中的最后一个节点指向null;
  • 当链表中一个节点也没有的时候,head直接指向null;

数组存在的缺点:
数组的创建通常需要申请一段连续的内存空间(一整块内存),并且大小是固定的。所以当原数组不能满足容量需求时,需要扩容(一般情况下是申请一个更大的数组,比如2倍,然后将原数组中的元素复制过去)。
在数组的开头或中间位置插入数据的成本很高,需要进行大量元素的位移。

链表的优势:
链表中的元素在内存中不必是连续的空间,可以充分利用计算机的内存,实现灵活的内存动态管理。
链表不必在创建时就确定大小,并且大小可以无限地延伸下去。
链表在插入和删除数据时,时间复杂度可以达到O(1),相对数组效率高很多。

链表的缺点:
链表访问任何一个位置的元素时,都需要从头开始访问(无法跳过第一个元素访问任何一个元素)。
无法通过下标值直接访问元素,需要从头开始一个个访问,直到找到对应的元素。
虽然可以轻松地到达下一个节点,但是回到前一个节点是很难的(单链表比较困难,双链表简单)。

链表中的常见操作

函数名是自定义的
append(element):向链表尾部添加一个新的项;
insert(position,element):向链表的特定位置插入一个新的项;
get(position):获取对应位置的元素;
indexOf(element):返回元素在链表中的索引。如果链表中没有该元素就返回-1;
update(position,element):修改某个位置的元素;
removeAt(position):从链表的特定位置移除一项;
remove(element):从链表中移除一项;
isEmpty():如果链表中不包含任何元素,返回trun,如果链表长度大于0则返回false;
size():返回链表包含的元素个数,与数组的length属性类似;
toString():由于链表项使用了Node类,就需要重写继承自JavaScript对象默认的toString方法,让其只输出元素的值;

单链表

append(data)尾部追加新节点

// 封装链表的构造函数
function LinkedList() {
    //封装一个Node类,用于保存每个节点信息
    function Node(data,next) {
        this.data = data
        this.next = (next===undefined ? null : next)
    }
    // 链表中的属性
    this.length = 0 // 链表的长度
    this.head = null //链表的第一个节点
    //链表中的方法
    // 1.追加节点的方法append,追加是指在链表的末尾添加节点
    LinkedList.prototype.append = function (data) {
        // 首先创建节点
        let newNode = new Node(data)
        // 然后找到末尾的节点,将新创建的节点添加到末尾
        // 如果是空链,直接让头指针指向新节点
        if (this.length == 0) {
            this.head = newNode
        } else {
            // 从头开始查找,用current标记当前查找的位置
            let current = this.head
            // if(current==null) current=newNode // 也可以这样判断链表目前是否是空链
            // 否则查找链表的最后一个节点
            while (current.next) {
                current = current.next
            }
            // 最后一个节点的current.next==null,所以会跳出while循环
            // 让最后一个节点指向新节点
            current.next = newNode
        }
        // 链表长度加一
        this.length += 1
    }
}

过程详解:

  1. 首先让current指向第一个节点:
    在这里插入图片描述
  2. 通过while循环使current指向最后一个节点,最后通过current.next = newNode,让最后一个节点指向新节点newNode
    在这里插入图片描述
    测试代码
    //测试代码
    //1.创建LinkedList
    let list = new LinkedList()
    
    //2.测试append方法
    list.append('aaa')
    list.append('bbb')
    list.append('ccc')
    console.log(list);  

结果
在这里插入图片描述

toString()输出链表的节点数据

代码实现:

LinkedList.prototype.toString =function(){
    let current=this.head
    // listString存储链表的节点数据
    let listString=''
    // 空链表不会进入该循环,content为空
    while(current){
        listString += current.data+' '// 每个节点数据后加个空格,便于阅读
        current=current.next
    }
    return listString
}

测试代码

    //测试代码
    //1.创建LinkedList
    let list = new LinkedList()
    
    //2.插入数据
    list.append('aaa')
    list.append('bbb')
    list.append('ccc')
    
    //3.测试toString方法
    console.log(list.toString());

结果
在这里插入图片描述

插入节点insert(position,data)

代码

            // position的有效范围是整数[0,length]
            LinkedList.prototype.insert=function(position,data){
                let newNode=new Node(data)
                if(position<0|| position>=this.length){
                    // false表示插入失败
                    return false;
                }else if(position==0){//newNode成为头结点的情况
                    // 注意顺序不能颠倒
                    newNode.next=this.head
                    this.head=newNode
                }else{
                    // 包含newNode成为最后一个节点的情况,与插入在中间位置一样的操作
                    let current=this.head
                    // 找到newNode要插入位置的前一个节点,跳出循环后current指向该节点
                    for(let i=0;i<position;i++){
                        current=current.next
                    }
                    // 顺序不能颠倒
                    newNode.next=current.next
                    current.next=newNode
                }
                this.length+=1
                // true表示插入成功
                return true
            }

过程详解:
position是节点插入链表后所处的位置,其有效范围是整数[0,length],根据插入节点位置的不同可分为多种情况:
情况1:position = 0:
通过: newNode.next = this.head,建立连接1;
通过: this.head = newNode,建立连接2;(不能先建立连接2,否则this.head不再指向Node1)
image-20200306103312580
情况2:position > 0:
在这里插入图片描述

                    // 包含newNode成为最后一个节点的情况,与插入在中间位置一样的操作
                    let current=this.head
                    // 找到newNode要插入位置的前一个节点,跳出循环后current指向该节点
                    for(let i=0;i<position;i++){
                        current=current.next
                    }
                    // 顺序不能颠倒
                    newNode.next=current.next
                    current.next=newNode

测试代码

    //1.创建LinkedList
    let list = new LinkedList()
    
    //2.插入数据
    list.append('aaa')
    list.append('bbb')
    list.append('ccc')
    
    //3.测试insert方法
    list.insert(0, '在链表最前面插入节点');
    list.insert(2, '在链表中第二个节点后插入节点');
    list.insert(5, '在链表最后插入节点');
    alert(list)// alert会自动调用参数的toString方法
    console.log(list);

结果
在这里插入图片描述
在这里插入图片描述

get(position)获取链表指定位置节点的数据

	//测试代码
    //1.创建LinkedList
    let list = new LinkedList()
    
    //2.插入数据
    list.append('aaa')
    list.append('bbb')
    list.append('ccc')	

	//3.测试get方法
    console.log(list.get(0));
    console.log(list.get(1));

在这里插入图片描述

indexOf(data)查找对应数据节点的位置

代码

// 根据数据查询数据所在链表位置
LinkedList.prototype.indexOf=function(data){
    let current= this.head
    let index=0
    // 从头结点开始逐个查找数据等于data的节点
    while(current){
        if(current.data==data){
            return index
        }
        current=current.next
        index+=1
    }
    // 没有查找到就返回-1
    return -1
}

测试代码

	//测试代码
    //1.创建LinkedList
    let list = new LinkedList()
    
    //2.插入数据
    list.append('aaa')
    list.append('bbb')
    list.append('ccc')	
    
    //3.测试indexOf方法
    console.log(list.indexOf('aaa'));
    console.log(list.indexOf('ccc'));

测试结果
在这里插入图片描述

update(position, newData)更新指定位置节点数据

代码

LinkedList.prototype.update=function(position,newData){
    // position有效取值是[0,this.length-1]间的整数,修改失败返回false
    if(position<0|| position>=this.length) return false;
    let current=this.head
    let i=0
    // 遍历至处于position位置的节点
    while(i++<position){
        current=current.next
    }
    // console.log(i); //position=2时,i=3,说明跳出循环i还是会自增1,因为自增运算符比比较运算符优先级高
    // 跳出循环时,current已经指向处于position位置的节点
    current.data=newData
    return true
}

测试代码

	//1.创建LinkedList
    let list = new LinkedList()
    
    //2.插入数据
    list.append('aaa')
    list.append('bbb')
    list.append('ccc')	
    
    //3.测试update方法
    console.log(list.update(0, '修改第0个节点'))
    console.log(list.update(2, '修改第2个节点'))
    console.log(list.update(3, '超出范围无法修改'));
    console.log(list.toString());

测试结果
在这里插入图片描述

removeAt(position)删除指定位置的节点

情况1:position = 0,即移除第一个节点(Node1)。通过:this.head = this.head.next,改变指向1即可;虽然Node1的next仍指向Node2,但是没有引用指向Node1,则Node1会被垃圾回收器自动回收,所以不用处理Node1指向Node2的引用next。
在这里插入图片描述
情况2:positon > 0,比如pos = 2即移除第三个节点(Node3)。
首先,定义两个变量previous和curent分别指向需要删除位置pos = x的前一个节点和当前要删除的节点;
然后,通过:previous.next = current.next,改变指向1即可;
随后,没有引用指向Node3,Node3就会被自动回收,至此成功删除Node3 。
在这里插入图片描述
代码

            LinkedList.prototype.removeAt=function(position){
                // 超出范围的删除不了
                if(position<0|| position>=this.length) return false;
                let current =this.head
                // 如果删除第一个节点
                if(position==0){
                    this.head=this.head.next
                }else{
                    let i=0;
                    let previous=this.head
                    while(i++<position){
                        previous=current
                        current=current.next
                    }
                    previous.next=current.next
                    this.length--;
                }
                return current.data
            }

测试代码

    let list = new LinkedList()
    
    //2.插入数据
    list.append('aaa')
    list.append('bbb')
    list.append('ccc')
  
  //3.测试removeAt方法
    console.log(list.removeAt(0));
    console.log(list.removeAt(1));
    console.log(list);

测试结果
在这里插入图片描述

remove(data)删除第一个数据为data的节点

LinkedList.prototype.remove=function(data){
    let current= this.head
    let index=0
    let previous=this.head
    // 从头结点开始逐个查找数据等于data的节点
    while(current){
        if(current.data==data){
            // 如果删除的是头节点
            if(index==0){
                this.head=this.head.next
            }else{
                previous.next=current.next
            }
            this.length--;
            return index
        }
        // previous和current指向下一个节点
        previous=current
        current=current.next
        index+=1
    }
    // 没有查找到就返回false
    return false
}

测试代码

    let list = new LinkedList()
    
    //2.插入数据
    list.append('aaa')
    list.append('bbb')
    list.append('ccc')

/*---------------其他方法测试----------------*/
  	//remove方法
  	console.log(list.remove('aaa'));
  	console.log(list)

结果
在这里插入图片描述

isEmpty()判断链表是否为空

代码

// 判断链表是否为空
LinkedList.prototype.isEmpty=function(){
    return this.length==0
}

size()返回链表长度

代码

// 返回链表的长度
LinkedList.prototype.size=function(){
    return this.length
}

测试代码

    let list = new LinkedList()
    
    //2.插入数据
    list.append('aaa')
    list.append('bbb')
    list.append('ccc')

/*---------------其他方法测试----------------*/
  	//remove方法
  	console.log(list.isEmpty());
    console.log(list.size())

结果
在这里插入图片描述

单链表构造函数完整实现

        // 封装链表的构造函数
        function LinkedList() {
            //封装一个Node类,用于保存每个节点信息
            function Node(data) {
                this.data = data
                this.next = null
            }
            // 链表中的属性
            this.length = 0 // 链表的长度
            this.head = null //链表的第一个节点
            //链表中的方法
            // 1.追加节点的方法append,追加是指在链表的末尾添加节点
            LinkedList.prototype.append = function (data) {
                // 首先创建节点
                let newNode = new Node(data)
                // 然后找到末尾的节点,将新创建的节点添加到末尾
                // 如果是空链,直接让头指针指向新节点
                if (this.length == 0) {
                    this.head = newNode
                } else {
                    // 从头开始查找,用current标记当前查找的位置
                    let current = this.head
                    // if(current==null) current=newNode // 也可以这样判断链表目前是否是空链
                    // 否则查找链表的最后一个节点
                    while (current.next) {
                        current = current.next
                    }
                    // 最后一个节点的current.next==null,所以会跳出while循环
                    // 让最后一个节点指向新节点
                    current.next = newNode
                }
                // 链表长度加一
                this.length += 1
            }
            // 2.返回链表各个节点的内容的方法
            LinkedList.prototype.toString = function () {
                let current = this.head
                let content = ''
                // 空链表不会进入该循环,content为空
                while (current) {
                    content += current.data + ' '// 每个节点数据后加个空格,便于阅读
                    current = current.next
                }
                return content
            }
            // position的有效范围是整数[0,length-1]
            LinkedList.prototype.insert=function(position,data){
                let newNode=new Node(data)
                if(position<0|| position>this.length){
                    // false表示插入失败
                    return false;
                }else if(position==0){//newNode成为头结点的情况
                    // 注意顺序不能颠倒
                    newNode.next=this.head
                    this.head=newNode
                }else{
                    // 包含newNode成为最后一个节点的情况,与插入在中间位置一样的操作
                    let current=this.head
                    // 找到newNode要插入位置的前一个节点,跳出循环后current指向该节点
                    for(let i=0;i<position-1;i++){
                        current=current.next
                    }
                    // 顺序不能颠倒
                    newNode.next=current.next
                    current.next=newNode
                }
                this.length+=1
                // true表示插入成功
                return true
            }
            LinkedList.prototype.get=function(position){
                // position有效取值是[0,this.length-1]间的整数
                if(position<0|| position>=this.length) return null;
                let current=this.head
                let i=0
                // 遍历至处于position位置的节点
                while(i++<position){
                    current=current.next
                }
                // console.log(i); //position=2时,i=3,说明跳出循环i还是会自增1,因为自增运算符比比较运算符优先级高
                // 跳出循环时,current已经指向处于position位置的节点
                return current.data    
            }
            // 根据数据查询数据所在链表位置
            LinkedList.prototype.indexOf=function(data){
                let current= this.head
                let index=0
                // 从头结点开始逐个查找数据等于data的节点
                while(current){
                    if(current.data==data){
                        return index
                    }
                    current=current.next
                    index+=1
                }
                // 没有查找到就返回-1
                return -1
            }

            LinkedList.prototype.update=function(position,newData){
                // position有效取值是[0,this.length-1]间的整数,修改失败返回false
                if(position<0|| position>=this.length) return false;
                let current=this.head
                let i=0
                // 遍历至处于position位置的节点
                while(i++<position){
                    current=current.next
                }
                // console.log(i); //position=2时,i=3,说明跳出循环i还是会自增1,因为自增运算符比比较运算符优先级高
                // 跳出循环时,current已经指向处于position位置的节点
                current.data=newData
                return true
            }
            LinkedList.prototype.removeAt=function(position){
                // 超出范围的删除不了
                if(position<0|| position>=this.length) return false;
                let current =this.head
                // 如果删除第一个节点
                if(position==0){
                    // 在JS中,垃圾回收机制会清理未被指向的对象
                    this.head=this.head.next
                }else{
                    let i=0;
                    let previous=this.head
                    while(i++<position){
                        previous=current
                        current=current.next
                    }
                    // 在JS中,垃圾回收机制会清理未被指向的对象
                    previous.next=current.next
                }
                this.length--;
                return current.data
            }
            LinkedList.prototype.remove=function(data){
                let current= this.head
                let index=0
                let previous=this.head
                // 从头结点开始逐个查找数据等于data的节点
                while(current){
                    if(current.data==data){
                        // 如果删除的是头节点
                        if(index==0){
                            this.head=this.head.next
                        }else{
                            previous.next=current.next
                        }
                        this.length--;
                        return index
                    }
                    // previous和current指向下一个节点
                    previous=current
                    current=current.next
                    index+=1
                }
                // 没有查找到就返回false
                return false
            }
            // 判断链表是否为空
            LinkedList.prototype.isEmpty=function(){
                return this.length==0
            }
            // 返回链表的长度
            LinkedList.prototype.size=function(){
                return this.length
            }
        }

链表节点实现
Java

// Definition for singly-linked list.
public class SinglyListNode {
    int val;
    SinglyListNode next;
    SinglyListNode(int x) { val = x; }
}

C++

// Definition for singly-linked list.
struct SinglyListNode {
    int val;
    SinglyListNode *next;
    SinglyListNode(int x) : val(x), next(NULL) {}
};

JS

//封装一个Node类,用于保存每个节点信息
function Node(element){
	this.element=element
	this.next=null
}

经典相关算法题

链表反转

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表
示例 1:
在这里插入图片描述
示例2
在这里插入图片描述
示例3
空链表反转后仍为空
题解

  1. 遍历节点,将每个节点的指向反转
/**
 * 定义单链表节点
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */

var reverseList = function(head) {
	// cur指向当前遍历的节点,pre指向前一个节点,
    let next=undefined,pre=null,cur=head;
    while(cur){
    	// 顺序不能颠倒
    	// next存储当前遍历节点的下一个结点的引用
        next=cur.next
        // 反转指向
        cur.next=pre
        // pre指向后移一位
        pre=cur;
        // cur指向后移一位
        cur=next
    }
    // 最终的pre成为新的头指针
    head=pre
    return head
};

复杂度分析
时间复杂度:O(n),其中 n 是链表的长度。需要遍历链表一次。
空间复杂度:O(1)

  1. 递归
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
    let pre=head,cur=head.next;
    // 考虑空链表和只有一个节点的情况
    if(pre==null || cur==null){
        head.next=null
        return pre
    };
    cur.next=pre
    return reverseList(cur)// 此时cur就相当于head
};

数组

  • 查找时间复杂度:O(1),因为可以直接根据索引查找
  • 插入或删除时间复杂度O(n),因为要移动删除或插入位置后面的数组元素

哈希表/散列表

用哈希函数确定键的存储位置
特点

  • 键不一样相应的存储位置也不一样
  • 键相同得到的存储位置相同
    在这里插入图片描述

因为所有树都可以转换成二叉树的形式,所以这里就只介绍二叉树数据结构的实现方式

完美二叉树(Perfect Binary Tree)/满二叉树(Full Binary Tree)

完全二叉树(Compelete Binary Tree)

二叉搜索树/二叉查找树/二叉排序树(Binary Search Tree,简称BST)

二叉搜索树构造函数实现如下

        function BinarySearchTree(){
            this.root=null
            // 节点构造函数
            function Node(key){
                this.key=key
                this.left=null
                this.right=null
            }
        }

二叉搜索树的常见操作:
insert(key):向树中插入一个新的键;
search(key):在树中查找一个键,如果节点存在,则返回true;如果不存在,则返回false;
inOrderTraverse:通过中序遍历方式遍历所有节点;
preOrderTraverse:通过先序遍历方式遍历所有节点;
postOrderTraverse:通过后序遍历方式遍历所有节点;
min:返回树中最小的值/键;
max:返回树中最大的值/键;
remove(key):从树中移除某个键;

按照这个算法,在相同的顺序下最终所形成的二叉搜索树应该是一样的

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity | NGO网络框架

目录 一、相关属性及变量 1.ServerRpc属性 2.ClientRpc属性 3.NetworkVariable变量 二、相关组件 1.NetworkManager 2.Unity Transport 3.Network Object 4.NetworkBehaviour&#xff1a; 5.NetworkTransform Syncing(Synchronizing) Thresholds Interpolation 三…

windows通过ssh连接Liunx服务器并实现上传下载文件

连接ssh 输入&#xff1a;ssh空格用户名ip地址&#xff0c;然后按Enter 有可能出现下图提示&#xff0c;输入yes 回车即可 输入 password &#xff0c;注意密码是不显示的&#xff0c;输入完&#xff0c;再按回车就行了 以上是端口默认22情况下ssh连接&#xff0c;有些公司它…

【VSCode】CMake Language Support 总是下载 .NET 超时,但又不想升级dotnet

错误信息 Error: Could not resolve dotnet path!An error occurred while installing .NET (6.0): .NET Acquisition Failed: Installation failed: Error: .NET installation timed out. You may need to change the timeout time if you have a slow connection. Please se…

VuePress部署到GitHub Pages

一、git push自动部署 1、创建用于工作流的文件 在项目根目录下创建一个用于 GitHub Actions 的工作流 .yml 文件 name: docson:# 每当 push 到 main 分支时触发部署push:branches: [main]# 手动触发部署workflow_dispatch:jobs:docs:runs-on: ubuntu-lateststeps:- uses: a…

湖仓架构的演进

1.数据仓库架构的历史演进 起初&#xff0c;业界数据处理首选方式是数仓架构。通常数据处理的流程是把一些业务数据库&#xff0c;通过ETL的方式加载到Data Warehouse中&#xff0c;再在前端接入一些报表或者BI的工具去展示。 数据仓库概念是 Inmon 于 1990 年提出并给出了完…

Spark Streaming的容错性与高可用性

在实时数据处理领域&#xff0c;容错性和高可用性是至关重要的。Apache Spark Streaming是一个强大的工具&#xff0c;用于实时数据处理和分析&#xff0c;具备卓越的容错性和高可用性。本文将深入探讨Spark Streaming的容错性机制&#xff0c;以及如何实现高可用性的实时数据处…

docker 部署haproxy cpu占用特别高

在部署mysql 主主高可用时&#xff0c;使用haproxy进行负载&#xff0c;在服务部使用的情况下发现服务器cpu占比高&#xff0c;负载也高&#xff0c;因此急需解决这个问题。 1.解决前现状 1.1 部署配置文件 cat > haproxy.cfg << EOF globalmaxconn 4000nbthrea…

【FPGA/verilog -入门学习16】fpga状态机实现

需求&#xff1a; 用两段式状态机设计序列码检测机。这个序列码检测机用于检索连续输入的 1bit 数据 &#xff08;每个时钟周期输入 1bit&#xff09;&#xff0c;当检测到一串“101100”的输入数据时&#xff0c;产生一个时钟周期的 高脉冲指示信号 状态图 //实现状态机切…

OSI 模型和 TCP/IP 模型的异同

开放式系统互联模型&#xff08;OSI&#xff09;是一个参考标准&#xff0c;解释协议相互之间应该如何相互作用。TCP/IP协议是美国国防部发明的&#xff0c;是让互联网成为了目前这个样子的标准之一 OSI&#xff1a;物理层&#xff0c;数据链路层&#xff0c;网络层&#xff0…

【2023 CCF 大数据与计算智能大赛】基于TPU平台实现超分辨率重建模型部署 基于Real-ESRGAN的TPU超分模型部署

2023 CCF 大数据与计算智能大赛 《基于TPU平台实现超分辨率重建模型部署》 洋洋很棒 李鹏飞 算法工程师 中国-烟台 2155477673qq.com 团队简介 本人从事工业、互联网场景传统图像算法及深度学习算法开发、部署工作。其中端侧算法开发及部署工作5年时间。 摘要 本文是…

mysql5.7安装-windows安装版本

下载地址 官网地址:https://www.mysql.com/官网下载地址:https://dev.mysql.com/downloads/mysql/阿里云镜像站下载:https://mirrors.aliyun.com/mysql/华为云镜像站地址:https://mirrors.huaweicloud.com/home华为云镜像站下载:https://mirrors.huaweicloud.com/mysql/Downlo…

【go语言】select多路选择

select基础知识 select 是 Go 语言中用于处理通道操作的控制结构&#xff0c;它类似于 switch 语句&#xff0c;但专门用于通道的选择。select 语句使得一个 goroutine 可以等待多个通道操作&#xff0c;当其中任意一个通道操作可以进行时&#xff0c;就会执行相应的 case 分支…

TS学习笔记一:认识TS及环境准备

本次学习笔记是具有一定js基础的情况下从头开始学习ts相关内容。 视频信息 TS学习笔记一&#xff1a;认识TS及环境准备 B站视频 TS学习笔记一&#xff1a;认识TS及环境准备 西瓜视频 https://www.ixigua.com/7320049274006274560 1.1.目的 通过本次学习&#xff0c;学习并…

Linux第13步_安装“vim编辑器”及应用介绍

学习“磁盘重新分区”后&#xff0c;嵌入式Linux系统环境搭建进入安装“vim编辑器”这个环节。vim编辑器可以用来修改文件&#xff0c;在后期使用中&#xff0c;会经常用到。 1、安装“vim编辑器” 输入“sudo apt-get install vim回车”&#xff0c;就可以执行安装“vim编辑…

【AI视野·今日Sound 声学论文速览 第三十七期】Tue, 31 Oct 2023

AI视野今日CS.Sound 声学论文速览 Tue, 31 Oct 2023 Totally 11 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers DCHT: Deep Complex Hybrid Transformer for Speech Enhancement Authors Jialu Li, Junhui Li, Pu Wang, Youshan Zhang当前大多数基于深…

运维系列:此站点的连接不安全,使用不受支持的协议。ERR_SSL_VERSION_OR_CIPHER_MISMATCH(不支持的协议 客户端和服务器不支持常用的 SSL 协议版本或密码套件。)

此站点的连接不安全&#xff0c;使用不受支持的协议。ERR_SSL_VERSION_OR_CIPHER_MISMATCH&#xff08;不支持的协议 客户端和服务器不支持常用的 SSL 协议版本或密码套件。&#xff09; 前言一、解决方法一1.Microsoft Edge浏览器→点击右上角的三个点→选择设置2.选择外观→打…

【代码随想录】刷题笔记Day46

前言 刚考完自辩&#xff0c;Chat回答举例什么的真方便。早上做组会PPT去了&#xff0c;火速来刷题&#xff01; 139. 单词拆分 - 力扣&#xff08;LeetCode&#xff09; 单词是物品&#xff0c;字符串s是背包&#xff0c;单词能否组成字符串s&#xff0c;就是问物品能不能把…

智云影院CMS程序PHP源码V3.0 无需数据库

本程序无需数据库&#xff0c;直接上传源码即可访问&#xff0c;&#xff08;服务器或虚拟主机空间&#xff09;都可以搭建使用&#xff01;模板自适应端&#xff0c;浏览体验更佳&#xff01;安装操作简单&#xff01;无需繁琐的操作&#xff0c;即可快速拥有一个视频看片资源…

transforms图像增强(一)

一、数据增强 数据增强&#xff08;Data Augmentation&#xff09;是一种常用的数据预处理技术&#xff0c;通过对训练集进行各种变换和扩增操作&#xff0c;可以增加训练数据的多样性和丰富性&#xff0c;从而提高模型的泛化能力。 数据增强的目的是通过对训练集中的图像进行…

JVM工作原理与实战(七):类的生命周期-初始化阶段

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、类的生命周期 1.加载&#xff08;Loading&#xff09; 2.连接&#xff08;Linking&#xff09; 3.初始化&#xff08;Initialization&#xff09; 4.使用&#xff08;Using&…