数据结构(期末)

目录

逻辑结构

存储结构

算法有以下五个特性

算法+数据结构 = 程序

时间复杂度

空间复杂度

数据元素是数据的基本单位

数据项是数据的最小单位

数据结构是带有结构的各数据元素的集合

时间复杂度例题

线性表

关于带头节点的单链表及不带头节点的单链表

栈和队列

栈和队列的定义和特点

队列

二叉树:先序,中序,后序

哈夫曼树

构造

编程

普里姆算法

归并排序

直插排序


逻辑结构

集合结构,线性结构,树形结构,图形结构

存储结构

顺序结构(地址连续)

链式结构(任意存储单元)(可连续,可不连续)

算法有以下五个特性

  1. 有穷性

  2. 确定性

  3. 可行性

  4. 输入

  5. 输出

算法+数据结构 = 程序

时间复杂度

x++ 
时间复杂度:O(1)
    
for(i=1;i<=n;i++){
    x++;   
}
时间复杂度:O(n)
   
for(i=1;i<=n;i++){
    for(j=1;j<=n;i++){
        x++;
    }
}
时间复杂度:O(n^2)
    

空间复杂度

int i = 1;
int j = 2;
++i;
j++;
int m = i+j
空间复杂度:O(1)
    
int m[] = new int[n];
for(i=1;i<=n;i++){
    j=i;
    j+1;
}
空间复杂度O(n)
    

数据元素是数据的基本单位

数据项是数据的最小单位

数据结构是带有结构的各数据元素的集合

时间复杂度例题

i < 1;
whiel(i<=n){
    i = i * 3;
}
时间复杂度O(log3n)
解释:设i = i * 3 执行了x次,则 3^x = n;故x=log3n
    
    
x = 0
for(i=1;i<n;i++){
    for(j=1;j<=n-1;j++){
        x++
    }
}
时间复杂度O(n^2)
    
x = n;
y = 0;
while(x >= (y+1)*(y+1)){
    y++;
}
时间复杂度O(更号n)
    

线性表

关于带头节点的单链表及不带头节点的单链表

  1. 首元结点: 是指链表中存储第一个数据元素的结点。

  2. 头结点: 是在首元素结点之间附设的一个结点,其指针指向首元结点。

  3. 头指针: 是指链表中第一个结点的指针。若链表没有头节点,则头节点指针为线性表的头结点;若链表不设头节点,则头指针所指的结点为该线性表的首元结点。

栈和队列

栈和队列的定义和特点

  1. 栈:受约束的线性表,只允许栈顶元素入栈和出栈

  2. 对栈来说,表尾端称为栈顶,表头端称为栈底,不含元素的空表称为空栈

  3. 先进后出,后进先出

队列

  1. 队列:收约束的线性表,只允许在队尾插入,在队头删除

  2. 先进先出,后进后出

二叉树:先序,中序,后序

先序:根,左,右

中序:左,根,右

后序:左,右,根

哈夫曼树

哈夫曼树(Huffman Tree),又称最优二叉树,是一种带权路径长度最短的二叉树。它常用于数据压缩,通过构建一个树形结构来表示一系列元素的频率,频繁出现的元素用较短的编码表示,不频繁出现的元素用较长的编码表示。下面是哈夫曼树的构造过程以及一个简单的编程实现思路。

构造

  1. 统计每个字符的频率:首先,统计需要编码的所有字符出现的次数。

  2. 创建节点集合:为每个字符创建一个叶子节点,节点的权值为该字符的频率。

  3. 构建哈夫曼树:

    • 将所有叶子节点加入一个最小堆(优先队列),按照节点的权值进行排序。

    • 取出权值最小的两个节点。

    • 创建一个新的内部节点,其权值为这两个节点权值之和,新节点的左右子节点分别是这两个权值最小的节点。

    • 将新节点加入到最小堆中。

    • 重复上述过程,直到堆中只剩下一个节点,这个节点就是哈夫曼树的根节点。

编程

import java.util.*;
​
class HuffmanNode implements Comparable<HuffmanNode> {
    int frequency; // 频率
    char data;
    HuffmanNode left, right;
​
    HuffmanNode(int freq, char data) {
        this.frequency = freq;
        this.data = data;
        left = right = null;
    }
​
    // 重写compareTo方法,用于优先队列的排序
    public int compareTo(HuffmanNode node) {
        return this.frequency - node.frequency;
    }
}
​
public class HuffmanCoding {
​
    // 构建哈夫曼树
    static HuffmanNode buildHuffmanTree(Map<Character, Integer> freqMap) {
        PriorityQueue<HuffmanNode> pq = new PriorityQueue<>();
​
        // 将每个字符及其频率添加到优先队列中
        for (Map.Entry<Character, Integer> entry : freqMap.entrySet()) {
            pq.add(new HuffmanNode(entry.getValue(), entry.getKey()));
        }
​
        // 合并节点直到只剩下一个节点(即哈夫曼树的根)
        while (pq.size() != 1) {
            HuffmanNode left = pq.poll();
            HuffmanNode right = pq.poll();
​
            HuffmanNode newNode = new HuffmanNode(left.frequency + right.frequency, '\0');
            newNode.left = left;
            newNode.right = right;
​
            pq.add(newNode);
        }
​
        return pq.peek(); // 返回哈夫曼树的根节点
    }
​
    // 生成哈夫曼编码(这里简化处理,未实现编码的具体生成逻辑)
    static void printCodes(HuffmanNode root, String str) {
        if (root == null)
            return;
​
        // 如果是叶子节点,则输出字符和编码
        if (root.data != '\0') {
            System.out.println(root.data + ": " + str);
            return;
        }
​
        // 非叶节点,递归生成左子树和右子树的编码
        printCodes(root.left, str + "0");
        printCodes(root.right, str + "1");
    }
​
    public static void main(String[] args) {
        Map<Character, Integer> freq = new HashMap<>();
        freq.put('A', 5);
        freq.put('B', 9);
        freq.put('C', 12);
        freq.put('D', 13);
        freq.put('E', 16);
        freq.put('F', 45);
​
        HuffmanNode root = buildHuffmanTree(freq);
        System.out.println("哈夫曼编码:");
        printCodes(root, "");
    }
}

普里姆算法

普里姆算法是一种用于寻找加权图的最小生成树的算法。下面是一个使用Java实现的普里姆算法的例子。在这个例子中,我们假设图是以邻接矩阵的形式存储的,其中INF表示两个顶点之间没有边。

import java.util.Arrays;
​
public class PrimAlgorithm {
    final int V = 5; // 图的顶点数
    final int INF = Integer.MAX_VALUE; // 代表无穷大
​
    // 用来存储图的邻接矩阵
    int[][] graph = new int[][]{
            {0, 2, 0, 6, 0},
            {2, 0, 3, 8, 5},
            {0, 3, 0, 0, 7},
            {6, 8, 0, 0, 9},
            {0, 5, 7, 9, 0}
    };
​
    // 用于选择顶点的数组,如果selected[i]为true,则顶点i已包含在最小生成树中
    boolean[] selected = new boolean[V];
​
    // 用于存储最小生成树的边的权重
    int[] edgeWeight = new int[V];
​
    // 用于存储最小生成树中各顶点的父顶点
    int[] parent = new int[V];
​
    // 普里姆算法的主要实现
    void prim() {
        Arrays.fill(edgeWeight, INF);
        Arrays.fill(parent, -1);
        edgeWeight[0] = 0;
        parent[0] = -1; // 第一个顶点是没有父顶点的
​
        for (int i = 0; i < V; i++) {
            int u = minVertex();
            selected[u] = true;
​
            for (int v = 0; v < V; v++) {
                if (!selected[v] && graph[u][v] != 0 && graph[u][v] < edgeWeight[v]) {
                    parent[v] = u;
                    edgeWeight[v] = graph[u][v];
                }
            }
        }
    }
​
    // 找出未被选中的顶点中edgeWeight值最小的顶点
    int minVertex() {
        int min = INF;
        int minIndex = -1;
​
        for (int v = 0; v < V; v++) {
            if (!selected[v] && edgeWeight[v] <= min) {
                min = edgeWeight[v];
                minIndex = v;
            }
        }
​
        return minIndex;
    }
​
    // 打印最小生成树的边和权重
    void printMST() {
        System.out.println("边 \t 权重");
        for (int i = 1; i < V; i++) {
            System.out.println(parent[i] + " - " + i + "\t" + graph[i][parent[i]]);
        }
    }
​
    public static void main(String[] args) {
        PrimAlgorithm prim = new PrimAlgorithm();
        prim.prim();
        prim.printMST();
    }
}

在这个程序中,prim()方法执行普里姆算法,找出图的最小生成树;minVertex()方法找到当前尚未包含在最小生成树中,且具有最小权重的顶点;printMST()方法用于打印最小生成树的边和对应的权重。

归并排序

public class SimpleMergeSort {
    public static void mergeSort(int[] array) {
        if (array == null || array.length <= 1) {
            return;
        }
        mergeSort(array, 0, array.length - 1);
    }
​
    private static void mergeSort(int[] array, int start, int end) {
        if (start < end) {
            int mid = start + (end - start) / 2;
            mergeSort(array, start, mid);
            mergeSort(array, mid + 1, end);
            merge(array, start, mid, end);
        }
    }
​
    private static void merge(int[] array, int start, int mid, int end) {
        int[] temp = new int[end - start + 1];
        int left = start, right = mid + 1, index = 0;
​
        while (left <= mid && right <= end) {
            if (array[left] <= array[right]) {
                temp[index++] = array[left++];
            } else {
                temp[index++] = array[right++];
            }
        }
​
        while (left <= mid) {
            temp[index++] = array[left++];
        }
​
        while (right <= end) {
            temp[index++] = array[right++];
        }
​
        for (int i = 0; i < temp.length; i++) {
            array[start + i] = temp[i];
        }
    }
​
    public static void main(String[] args) {
        int[] testArray = {9, 5, 1, 4, 3};
        mergeSort(testArray);
        for (int i : testArray) {
            System.out.print(i + " ");
        }
    }
}

直插排序

在这个实现中,insertionSort方法遍历数组中的每一个元素(从第二个元素开始,因为单个元素默认是有序的)。对于每一个元素,它会与前面已经排序好的部分进行比较,找到适当的位置并将其插入。这样逐步构建整个有序数组。

main方法提供了一个测试数组,并调用insertionSort方法对其进行排序,最后打印排序后的数组,以验证排序算法的正确性。

public class InsertionSort {
    public static void insertionSort(int[] array) {
        if (array == null || array.length <= 1) {
            return;
        }
        
        for (int i = 1; i < array.length; i++) {
            int current = array[i];
            int j = i - 1;
            
            while (j >= 0 && array[j] > current) {
                array[j + 1] = array[j];
                j--;
            }
            array[j + 1] = current;
        }
    }
​
    public static void main(String[] args) {
        int[] testArray = {9, 5, 1, 4, 3};
        insertionSort(testArray);
        for (int value : testArray) {
            System.out.print(value + " ");
        }
    }
}

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

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

相关文章

RAG 工业落地方案框架(Qanything、RAGFlow、FastGPT、智谱RAG)细节比对!CVPR自动驾驶最in挑战赛赛道,全球冠军被算力选手夺走了

RAG 工业落地方案框架&#xff08;Qanything、RAGFlow、FastGPT、智谱RAG&#xff09;细节比对&#xff01;CVPR自动驾驶最in挑战赛赛道&#xff0c;全球冠军被算力选手夺走了。 本文详细比较了四种 RAG 工业落地方案 ——Qanything、RAGFlow、FastGPT 和智谱 RAG&#xff0c;重…

后端之路——最规范、便捷的spring boot工程配置

一、参数配置化 上一篇我们学了阿里云OSS的使用&#xff0c;那么我们为了方便使用OSS来上传文件&#xff0c;就创建了一个【util】类&#xff0c;里面有一个【AliOSSUtils】类&#xff0c;虽然本人觉得没啥不方便的&#xff0c;但是黑马视频又说这样还是存在不便维护和管理问题…

Artificial Intelligence Self-study

Artificial Intelligence Self-study Traditional AI (Symbolic AI) 基于&#xff1a;符号表示 数理逻辑 搜索 - 有明确规则&#xff0c;依靠算力。Appliance &#xff1a; 数学难题(Heuristic Algorithm)&#xff0c;棋牌对抗(围棋)&#xff0c;专家系统(输入病症&#xf…

02-android studio实现下拉列表+单选框+年月日功能

一、下拉列表功能 1.效果图 2.实现过程 1&#xff09;添加组件 <LinearLayoutandroid:layout_width"match_parent"android:layout_height"wrap_content"android:layout_marginLeft"20dp"android:layout_marginRight"20dp"android…

使用Anaconda虚拟环境安装Opencv、pytorch、torchvision踩坑记录

电脑 python 环境版本过高与下载Opencv&#xff08;3.4以下&#xff09;不匹配&#xff0c;因为版本过高部分算法收米&#xff0c; 从而在虚拟环境重新下载python老版本 本文默认您的电脑上已经安装了Anaconda 我是按照这位博文安装的 安装Opencv (详解)安装3.4.1.15版本…

java数据结构集合复习之包装类和泛型

前言: 这是我最一年学习java的一部分的回顾总结 1.包装类 在Java中&#xff0c;由于基本类型不是继承自Object&#xff0c;为了在泛型代码中可以支持基本类型&#xff0c;Java给每个基本类型都对应了一个包装类型。 1.1基本数据类型和对应的包装类 ----—基本数据类型包装类…

14. Revit API: Selection(选择器)

前言 这篇写选择器&#xff0c;经过前面好些篇的讲解&#xff0c;总算把前置内容都写完了。 我们来回忆下都在哪里提到过… 算了&#xff0c;直接进入正文。 一、Selection 命名空间 选择器位于Autodesk.Revit.UI.Selection命名空间下&#xff0c;关系到交互嘛&#xff0c;所…

Dns被莫名篡改的逆向分析定位(笔记)

引言&#xff1a;最近发现用户的多台机器上出现了Dns被莫名修改的问题&#xff0c;从系统事件上看并未能正常确定到是那个具体软件所为&#xff0c;现在的需求就是确定和定位哪个软件具体所为。 解决思路&#xff1a; 首先到IPv4设置页面对Dns进行设置&#xff1a;通过ProcExp…

【Axure高保真原型】中继器表格——移入显示详情卡片案例

今天和大家分享中继器表格——移入显示详情卡片的原型模板&#xff0c;鼠标移入员工号或姓名会弹出员工卡片&#xff0c;可以查看更详细的信息。这个表格是用中继器制作的&#xff0c;所以使用也很方便&#xff0c;只需要维护中继器表格里的信息&#xff0c;即可自动生成交互效…

实操Nginx+Tomcat多实例部署,实现负载均衡和动静分离

192.168.10.10 192.168.10.20 192.168.10.30 location ~ \.jsp$ {proxy_pass http://192.168.10.50:8080;} location ~ \.(jsp|html)$ {root /usr/share/nginx/html;}192.168.10.40和192.168.10.50用脚本完成搭建此处安装附上脚本&#xff1a; #!/bin/bash# 定义变量 JDK_PACKA…

生态系统NPP及碳源、碳汇模拟技术教程

原文链接&#xff1a;生态系统NPP及碳源、碳汇模拟技术教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247608293&idx3&sn2604c5c4e061b4f15bb8aa81cf6dadd1&chksmfa826602cdf5ef145c4d170bed2e803cd71266626d6a6818c167e8af0da93557c1288da21a71&a…

nginx 搭理禅道

1.安装nginx。 2.安装禅道。 3.nginx 配置文件 location /zentao/ { proxy_pass http://192.168.100.66/zentao/;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-F…

边界无限陈佩文:红蓝对抗安全演练常态化的各方分析

虽然常态化演练尚未正式开始&#xff0c;但我们仍然希望对各方的表现进行一些分析和预测&#xff0c;以辅助我们对市场的判断和决策。同时&#xff0c;也希望通过这些初步的见解&#xff0c;抛砖引玉&#xff0c;引发更多有价值的讨论和观点。 “船停在码头是最安全的&#xf…

【数据库】E-R图、E-R模型到关系模式的转换、关系代数表达式、范式

一、E-R图 1、基本概念 2、实体集之间的联系 3、E-R图要点 &#xff08;1&#xff09;实体&#xff08;型&#xff09;的表示 &#xff08;2&#xff09;E-R图属性的表示 &#xff08;3&#xff09;联系的表示 4、E-R模型的例题 二、E-R模型到关系模式的转换 1、实体型的转换…

pytorch-时间序列

目录 1. 时间序列2. word embedding2.1 one hot2.2 word2vec2.3 GloVe 1. 时间序列 具有时间相关性的序列叫做时间序列&#xff0c;比如&#xff1a;语音、文本句子 2. word embedding 2.1 one hot 针对句子来说&#xff0c;可以用[seq_len, vector_len] 有多少个单词vecto…

因为文件共享不安全,所以你不能连接到文件共享。此共享需要过时的SMB1协议,而此协议是不安全的 解决方法

目录 1. 问题所示2. 解决方法3. 解决方法1. 问题所示 输入共享文件地址的时候,出现如下信息: 因为文件共享不安全,所以你不能连接到文件共享。此共享需要过时的SMB1协议,而此协议是不安全的,可能会是你的系统遭受攻击。你的系统需要SMB2或更高版本截图如下所示: 2. 解决…

竞赛 深度学习+opencv+python实现车道线检测 - 自动驾驶

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络3.1卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV56 数据集处理7 模型训练8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &am…

【Linux】Linux常用指令合集精讲,一篇让你彻底掌握(万字真言)

文章目录 一、文件与目录操作1.1 ls - 列出目录内容1.2 cd - 切换目录1.3 pwd - 显示当前目录1.4 mkdir - 创建目录1.5 rmdir - 删除空目录1.6 rm - 删除文件或目录1.7 cp - 复制文件或目录1.8 mv - 移动或重命名文件或目录1.9 touch - 创建空文件或更新文件时间戳 二、文件内容…

朗新天霁eHR GetFunc_code.asmx SQL注入致RCE漏洞复现

0x01 产品简介 朗新天霁人力资源管理系统(LongShine eHR)是一款由北京朗新天霁软件技术有限公司研发的人力资源管理系统,该产品融合了国外先进的人力资源管理理念和国内大量人力资源管理实践经验,是国内功能较为全面、性价比较高的人力资源管理系统之一,系统凭借其集成化…

@amap/amap-jsapi-loader实现高德地图嵌入React项目中,并且做到点击地图任意一处,获得它的经纬度

1.第一步要加入项目package.json中或者直接yarn install它都可以 想必大家应该都会 "amap/amap-jsapi-loader": "0.0.7"2.加入项目中 关于接口获取key的接口 大家改成自己对应的项目请求方法 import React, { PureComponent } from react; import { Input…