数据结构和算法

数据结构和算法是编程的核心,它们决定了程序的效率和资源利用率。数据结构如数组、链表、栈和队列等,影响数据的存储和访问方式。算法则是解决问题的步骤,如字符串替换、栈的入栈出栈、队列的先进先出等。理解这些概念,能优化程序设计,提高计算速度。
摘要由CSDN通过智能技术生成

数据结构和算法

编程好比是一台笔记本电脑,数据结构和算法就是电脑的内部的CPU,内存。

学习数据结构,可以让我们明白数据在计算机中的存储的方式,从而可以选择更加合理的结构来存储数据,从而提高程序的执行效率,节约资源。

数据结构和算法的重要性

  1. 算法是程序的灵魂,优秀的程序可以在海量数据计算时,依然保持高速计算
  2. 一般来说,程序会使用内存计算框架和缓存技术来优化程序。核心框架的主要功能是通过算法来实现

数据结构和算法的关系

数据结构是一门研究组织数据方式的学科,在编程语言中,使用良好的结构可以大幅度提升程序的效率

要学好数据结构 就需要多考虑如何将生活中遇到问题 用程序思维区解决解决

程序= 数据结构 + 算法

数据结构是算法的基础

    public static void main(String[] args) {
        String str = "Java ,Java   ,hello , world";
        String newStr = str.replaceAll("Java","中国");//算法
        System.out.println(newStr);
    }

基本的概念和专业术语

  1. 数据(data):所有能输入到计算机中的描述客观事物的符号
  2. 数据元素(data element) 数据的基本单位也称为结点或记录
  3. 数据项(data item) 有独立含义的数据的最小单位 也称为域

三者之间的关系: 数据> 数据元素> 数据项

  1. 数据对象 相同特性的数据元素的集合 是数据的一个子集

整数数据对象 N = {0,1,2,3,4,…}

学生数据对象 学生记录的集合 :学生表 > 个人记录>学号 姓名,年龄

  1. 数据结构(data Structure) 是相互存在的数据元素之间通过一种或多种特定关系组织在一起的集合

数据结构是带“结构”的数据元素的集合,“结构”就是值数据元素之间存在的关系

数据的逻辑结构

数据元素间的这种抽象关系,是与存储无关的 是从具体问题抽象出来的数学模型

划分方法一:

​ 1. 线性结构

​ 线性结构作为最常见一种数据结构,特点是数据元素之间存在一对一的线性关系

​ 线性结构有两种不同的存储结构:

  • 顺序的存储结构:顺序表 存储的元素是连续的

  • 链式存储结构:链表 链表中的元素不一定是连续的。元素结点中存放数据元素和相邻元素的地址信息

​ 线性结构常见:数组 栈 队列 链表

​ 2. 非线性结构

​ 二维数组 多维数组 树结构 图结构

数据的存储结构

存储结构就是物理结构,数据元素以及相互的关系在计算机中存储的方式

顺序存储结构-- 借助于元素在存储容器中的相对位置来表示元素间的逻辑关系

链式存储结构–借助于元素存储地址的指针表示元素间的逻辑关系

常见的数据结构

线性结构

数组

数组:Array,是有序的元素序列,数组是在内存中开辟一段连续的空间,并在此空间存放元素。

特点

  • 查找元素快:通过索引,可以快速访问指定位置的元素

  • 增删元素慢

  • 指定索引位置增加元素:需要创建一个新数组,将指定新元素存储在指定索引位置,再把原数组元素根据索引,复制到新数组对应索引的位置。如下图

  • 指定索引位置删除元素:需要创建一个新数组,把原数组元素根据索引,复制到新数组对应索引的位置,原数组中指定索引位置元素不复制到新数组中。如下图

栈(stack)

  • stack,又称堆栈,它是运算受限的线性表,其限制是仅允许在标的一端进行插入和删除操作,不允许在其他任何位置进行添加、查找、删除等操作。

栈结构的特点:

  1. 对于元素的操作只能从一端开始
  2. 先进后出,后进先出

  • 压栈:就是存元素。即,把元素存储到栈的顶端位置,栈中已有元素依次向栈底方向移动一个位置。
  • 弹栈:就是取元素。即,把栈的顶端位置元素取出,栈中已有元素依次向栈顶方向移动一个位置。

栈的常见操作:以下 方法也是栈操作的规范

  1. 入栈

  2. 出栈

  3. 判断栈是否为空

  4. 判断栈是否已满

  5. 返回栈顶元素

  6. 返回元素在栈中的位置

  7. 返回栈的实际长度

  8. 返回栈的容量

  9. 打印栈

栈接口

public interface IStack {
    //1 入栈
     boolean  push(Object obj);
    //	2 出栈
    Object pop();
    //	3 判断栈是否为空
     boolean isEmpty();
    //	4 判断栈是否已满
     boolean isFull();
    //	5 返回栈顶元素
     Object peek();
    //	6 返回元素在栈中的位置
    int getIndex(Object obj);
    //	7 返回栈的实际长度
    int size();
    //	8 返回栈的容量
    int getStatckSize();
    //	9  打印栈
    void  display();
}

栈的实现:

用数组模拟栈的结构

public class StackImpl  implements IStack {
    //定义栈的属性
    private  Object[] data = null;
    private int top = -1;// 栈顶
    private int maxSize = 0 ;// 表示栈的容量
    public StackImpl(){// 默认初始化一个容量为10的栈
        this(10);
    }
    // 创建一个栈结构 并对栈进行初始化
    public StackImpl(int initialSize){
        if(initialSize >= 0){
            this.data = new Object[initialSize];
            this.maxSize = initialSize;
            this.top=-1;
        }
    }
    @Override
    public boolean push(Object obj) {
        if(isFull()){//如果栈已满
            System.out.println("栈已满,入栈失败!");
            return  false;
        }
        top++;// 更新栈顶指针
        data[top] = obj;//将元素保存到栈中
        return true;
    }

    @Override
    public Object pop() {
        if(isEmpty()){
            System.out.println("栈为空,没有可出栈的元素");
            return null;
        }
       Object topObj =  data[top];// 获取栈顶元素
        top--;
        return topObj;
    }

    @Override
    public boolean isEmpty() {
        return top == -1 ? true:false;
    }

    @Override
    public boolean isFull() {
        return  top >= maxSize -1? true:false;
    }

    @Override
    public Object peek() {
        if(isEmpty()){
            System.out.println("栈为空,没有可出栈的元素");
            return null;
        }
        return data[top];
    }

    @Override
    public int getIndex(Object obj) {
        // 需要不断的获取栈顶和目标元素进行比较
        while(top != -1){
            if( peek().equals(obj)){
                return  top;
            }
            top--;
        }
        return -1;// 表示元素不存在
    }

    @Override
    public int size() {
        return 0;
    }

    @Override
    public int getStatckSize() {
        return this.top +1;
    }

    @Override
    public void display() {
        while(top != -1){
            System.out.println(data[top]);
            top--;
        }
    }

    public static void main(String[] args) {
        // 创建一个栈
        IStack stack = new StackImpl();
        // 入栈
        for(int i = 0 ; i < 10 ;i++){
            stack.push(i);
        }
        stack.push("aa");
        stack.display();
    }
}

练习:利用栈实现字符串逆序

思路:将字符串转换为字符数组 在将字符数组中的字符逐个入栈, 然后再出栈

队列

  • 队列queue,简称队,它同堆栈一样,也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除。

  • 先进先出(即,存进去的元素,要在后它前面的元素依次取出后,才能取出该元素)。例如,小火车过山洞,车头先进去,车尾后进去;车头先出来,车尾后出来。

  • 队列的入口、出口各占一侧。例如,下图中的左侧为入口,右侧为出口。

实现:

在这里插入图片描述

解决假溢出:

在这里插入图片描述

这种队列称为循环队列。

如何判断循环队列究竟是空还是满:

方法一:

​ 设置一个标志flag 初始的时候 falg = 0 ;每当入队一次 就让flage =1;每当出队一次 就让flag = 0;则队列为空的判断条件:flag == 0 && front == rear;队列为满的条件: flag ==1 && front == rear

方法二: 预留一个元素的存储空间,此时 队列未满的判断条件 (rear + 1 )% maxSize == front

队列为空 front == rear

方法三: 设计一个计数器 count 统计队列中元素的个数

​ 队列满的条件 cout > 0 && front==rear

​ 队列为空的条件: count == 0

入队:rear = (rear +1) % maxSize

出队 : front = (front + 1) % maxSize

使用方式三实现循环队列

public interface IQueue {
    //入队
     void  append(Object obj);
    // 出队
    Object delete();
    //获得对头元素
    Object getFront();
    // 判断队列是否为空
    boolean isEmpty();
}
public class CircleQueue  implements IQueue {
    // 定义队列相关的成员属性
    int  front;//对头
    int rear;//队尾
    int count;//统计元素个数
    int maxSize;//队列的最大长度
    Object[] queue;//队列
    public CircleQueue(int initalSize){
        front=rear=0;
        count = 0;
        maxSize = initalSize;
        queue = new Object[initalSize];
    }
    public CircleQueue(){
        this(10);
    }
    @Override
    public void append(Object obj) throws Exception {
        if(count>0 && front == rear){
            throw  new Exception("队列已满  ,入队失败");
        }
        queue[rear] = obj;
        rear = (rear +1 )% maxSize;
        count++;
    }

    @Override
    public Object delete() throws Exception {
        if(isEmpty()){
            throw  new Exception("队列为空 ,入队失败");
        }
        Object obj = queue[front];
        front = (front+1)%maxSize;
        count--;
        return obj;
    }

    @Override
    public Object getFront() throws Exception {
        if(!isEmpty()){
            Object obj = queue[front];
            return  obj;
        }else{
            return  null;
        }
    }

    @Override
    public boolean isEmpty() {
        return count==0;
    }
}

测试

    public static void main(String[] args) throws Exception {
        CircleQueue queue = new CircleQueue(5);
        queue.append("a");
        queue.append("b");
        queue.append("c");
        queue.append("d");
        queue.append("e");
        //queue.append("f");
      Object o1=   queue.delete();
        Object o2=   queue.delete();
//        Object o3=   queue.delete();
//        Object o4=   queue.delete();
        System.out.println(o1);
        System.out.println(o2);
        queue.append("g");
        System.out.println("---------------");
        while(!queue.isEmpty()){
            System.out.println(queue.delete());
        }
    }

链表

链表:linked list,由一系列结点node(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

链表是一种线性表,但是并不会按照线性的顺序存储数据,而是在每一个结点里存放下一个结点的指针。

特点

  • 多个结点之间,通过地址进行连接。例如,多个人手拉手,每个人使用自己的右手拉住下个人的左手,依次类推,这样多个人就连在一起了。

  • 查找元素慢:想查找某个元素,需要通过连接的节点,依次向后查找指定元素

  • 增删元素快:

    • 增加元素:只需要修改连接下个元素的地址即可。

  • 删除元素:只需要修改连接下个元素的地址即可。

单向链表

单向链表 一个单链表的结点分为两部分,第一部分保存结点的数据,第二部分保存下一个结点的地址。最后一个节点存储地址的部分指向空值。

单向链表只可以向一个方向遍历,查找一个结点的时候,都需要从一个节点开始每次访问下一个结点,一直到需要的位置

在这里插入图片描述

public class SingleLinkedList {
    // 链表的结点的个数
    private int size;
    //头结点
    private Node head;
    public  SingleLinkedList(){
        size = 0;a
        head= null;
    }
    // 链表的结点类
    private class Node{
        private Object data;//结点的数据域
        private Node next;//下一个结点的指针
        public Node(Object data){
            this.data = data;
        }
    }
    // 给链表添加元素  C->B->A
    public Object addHead(Object data){
        Node newHead = new Node(data);// 创建一个新的结点
        if(size == 0 ){
            head = newHead;
        }else{
            newHead.next = head;//新结点的指针指向原来的头结点
            head = newHead;//头结点指向新的结点
        }
        size++;
        return data;
    }
    // 删除结点  在链表头不删除结点
    public  Object deleteHead(){
        Object obj = head.data;
        head = head.next;
        size--;
        return obj;
    }
    //在链表中查找指定的元素,找到了返回结点Node,没找到则返回null
    public Node find(Object data){
        Node current = head;//定义一个指针,指向当前比较的结点
        int tempSize = size;// 获取当前链表中元素的个数
        while(tempSize > 0 ){
            if(data.equals(current.data)){
                return  current;
            }else{
                current = current.next;
            }
            tempSize--;
        }
        return  null;
    }
    // 删除指定的元素  删除成功返回true   否则返回false
    public  boolean delete(Object data){
        if(size == 0 ){
            return  false;
        }
        // 获取删除结点的前一个结点和他的后一个结点
        Node current = head;
        Node previous = head;
        while(!current.data.equals(data)){
            if (current.next == null){// 判断是否到达链表的结尾
                return  false;
            }else{// 当前结点不是我们要删除的结点 并且没有到达结点的末尾
                previous = current;//移动前一个结点的指针
                current = current.next;//移动当前结点的指针指向下一个
            }
        }
        // 此时表明找到了要删除的结点, 判断 删除的结点是否是头结点
        if(current == head){
            head = current.next;
            size--;
        }else{//不是头结点
            previous.next =current.next;
            size--;
        }
        return  true;
    }
    // 判断结点是否为空
    public  boolean isEmpty(){
        return  size==0;
    }
    // 遍历链表
    public  void  display(){
        if(size > 0 ){
            Node node = head;
            int tempSize = size;
            if(tempSize == 1){// 如果当前链表只有一个头结点
                System.out.println("[" + node.data+"]");
                return;
            }
            while(tempSize >0 ){
                if(node.equals(head)){
                    System.out.print("[" + node.data+"->");
                }else if(node.next == null){
                    System.out.print( node.data+"]");
                }else{
                    System.out.print(node.data+"->");
                }
                node= node.next;
                tempSize--;
            }
            System.out.println();
        }else{// 链表没有结点
            System.out.println("[]");
        }
    }
}

测试

public class SingleLinkListTest {
    public static void main(String[] args) {
        SingleLinkedList sls = new SingleLinkedList();
        sls.addHead("A");
        sls.addHead("B");
        sls.addHead("C");
        sls.addHead("D");
        sls.display();
        //测试删除元素 删除C
        sls.delete("C");
        sls.display();
        //查找B
        System.out.println(sls.find("C"));
    }
}

双向链表

双向链表的

在这里插入图片描述

循环链表:

栈 队列 链表的区别

栈 队列是线性表,操作受限。

区别:在于运算规则不同

链表和数组

  1. 占用的内存空间:链表存放的内存空间可以是连续的,也可以是不连续的,数组一定是连续的。

  2. 长度的可变性:链表的长度可以根据实际需要 自定伸缩。数组长度一旦定义 则不能改变。

  3. 数据的访问:

    链表的访问:需要移动访问,访问不便捷

    数组的访问:数组方问更加便捷

  4. 使用场景:

    数组更加适合数据量大 ,而且需要进行频繁的访问元素

    链表更加适合删除,插入等操作

栈的特点:

  • 逻辑结构:一对一
  • 存储结果:顺序栈 链栈
  • 运算规则:后进先出 先进后出

队列的特点:

  • 逻辑结构:一对一
  • 存储结果:顺序队 链队
  • 运算规则:先进先出

链表的特点:

  • 逻辑结构:一对一
  • 存储结果:顺序表 链表
  • 运算规则:随机 顺序存放

非线性结构

树结构

二叉树
  • 二叉树binary tree ,是每个结点不超过2的有序树(tree)

在这里插入图片描述

每一个元素称为结点

A 根节点

B C D 父节点

叶子结点: 没有子节点的节点(H E F G)

树的高度:最大的层数

子树

森林 多颗子树构成森林

每个结点最多只有两个子节点的形式的树称为二叉树

如果所有的二叉树的叶子结点都在最后一次。节点数 = 2^n - 1 n就是他的层数 将这样的二叉树称为满二叉树

二叉树的遍历

前序遍历:先输出父节点 再遍历左子树和右子树

中序遍历:先遍历左子树 在输出父节点 最后遍历右子树

后序遍历:先遍历左子树 再遍历右子树 最后输出父节点

层序遍历:按照层级逐层遍历

在这里插入图片描述

红黑树

红黑树本身就是一颗二叉查找树,将结点插入后,该树仍然是一颗二叉查找树。也就意味着,树的键值仍然是有序的。

红黑树是一种含有红黑结点并能自平衡的二叉树。他必须满足一下的性质:

红黑树的约束:

  1. 节点可以是红色的或者黑色的
  2. 根节点是黑色的
  3. 叶子节点(特指空节点)是黑色的
  4. 每个红色节点的子节点都是黑色的
  5. 任何一个节点到其每一个叶子节点的所有路径上黑色节点数相同

在这里插入图片描述

红黑树的特点:

速度特别快,趋近平衡树,查找叶子元素最少和最多次数不多于二倍

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值