数据结构与算法笔记--数据结构与算法基本知识

目录

1--数据结构

2--算法

3--算法分析

4--实例1:普通算法与秦九韶算法的运算效率比较

5--实例2:最大子列和问题

5-1--暴力求解法

5-2--分而治之

5-3--动态规划

5-4--完整代码


1--数据结构

        定义:所有数据元素以及数据元素之间的关系构成的集合;

        数据结果一般包含以下方面:

数据的逻辑结构:由数据元素之间的逻辑关系构成;

数据的存储结构:即物理结构,表示数据元素及其关系在计算机存储器的存储表示;

数据的运算:表示施加在数据元素上的操作;

2--算法

        定义:算法是对特定问题求解步骤的一种描述,其是指令的有限序列;

        算法满足5个特性:有穷性、确定性、可行性、有输入、有输出;

3--算法分析

        分析算法一般从时间复杂度和空间复杂度两方面进行评价与分析;

​​​时间复杂度:

        ① 不同时间复杂度存在以下关系:O(1) < O(log n) < O(n) < O(n logn) < O(n^2) < O(2^n) < O(n!);

空间复杂度:

        ① 定义:一个算法在运行过程中临时占用的存储空间大小;

4--实例1:普通算法与秦九韶算法的运算效率比较

        实例代码:

#include <stdio.h>
#include <math.h>
#include <time.h>

#define MAXN 10
#define MAXK 1e7
clock_t start, stop;

double f1(int n, double a[], double x){
    double p = a[0];
    for(int i = 1; i <= n; i++){
        p += (a[i] * pow(x, i));
    }
    return p;
}

double f2(int n, double a[], double x){
    double p = a[n];
    for(int i = n; i>0; i--){
        p = a[i - 1] + x*p;
    }
    return p;
}

double cal_duration(int N, double *a, double x, int flag = 0){
    double duration;

    if (flag == 0){
        start = clock();
        for(int i = 0; i < MAXK; i++){
            f1(N, a, x);
        }
        stop = clock();
    }
    else if(flag == 1){
        start = clock();
        for(int i = 0; i < MAXK; i++){
            f2(N, a, x);
        }
        stop = clock();
    }
    // duration = ((double)(stop - start)) / CLK_TCK; 
    duration = ((double)(stop - start)) / CLOCKS_PER_SEC / MAXK; // Mac
    return duration;
}

int main(int argc, char* argv[]){
    // 存储多项式的系数
    double a[MAXN];
    for(int i = 0; i < MAXN; i++) a[i] = (double)i;

    double x = 1.1;
    double duration1 = cal_duration(MAXN - 1, a, x, 0); // f1计算
    double duration2 = cal_duration(MAXN - 1, a, x, 1); // f2计算

    printf("duration1 = %6.2e\n", duration1);
    printf("duration1 = %6.2e\n", duration2);
    return 0;
}

        运行结果:分析运行结果可知,秦九韶算法比普通算法的运算效率高一个数量级;

        ​​​​​​​原因分析:

​​​​​​​         ​衡量算法效率一般采用时间复杂度进行比较;在上面的实例中,加减法的运算时间远低于乘除法,因此可以忽略;

        ​​​​​​​对于普通算法而言,其乘法的运算次数为 (1+2+……n) = (n^2 + n) / 2,即T(n) = C1*n^2 + C2*n;

        对于秦九韶算法而言,其乘法的运算次数为 n,即T(n) = C1*n;

        对比两个算法的T(n),很明显普通算法的时间复杂度高于秦九韶算法;

5--实例2:最大子列和问题

        问题描述:给定 N 个整数的序列{{A_1, A_2, \cdots, A_N}},求解连续子序列和的最大值;

5-1--暴力求解法

        方法①:

// Method1:暴力求解
int Method1(int *a, int N){
    int Sum, MaxSum = 0;
    for(int i = 0; i < N; i++){
        for(int j = i; j < N; j++){
            Sum = 0; // 计算所有子序列的和
            for(int k = i; k <= j; k++){
                Sum += a[k];
            }
            if(Sum > MaxSum) MaxSum = Sum;
        }
    }
    return MaxSum;
}

        方法②:

// Method2:暴力求解
int Method2(int *a, int N){
    int Sum, MaxSum = 0;
    for(int i = 0; i < N; i++){
        Sum = 0;
        for(int j = i; j < N; j++){
            Sum += a[j];
            if(Sum > MaxSum) MaxSum = Sum;
        }
    }
    return MaxSum;
}

5-2--分而治之

// Method3:分而治之
int my_Max( int A, int B, int C ){ 
    return A > B ? A > C ? A : C : B > C ? B : C;
}
int Method3(int *a, int left, int right){
    int MaxLSum = 0, MaxRSum = 0;
    int center, i;
    int MaxLBSum = 0, MaxRBSum = 0;
    int LBSum = 0, RBSum = 0;

    if(left == right){ // 递归终止条件,子列只有一个数字
        if(a[left] > 0) return a[left];
        else return 0;
    }

    // 分
    center = (left + right) / 2; // 分界线
    // 递归求解左子列和右子列的最大和
    MaxLSum = Method3(a, left, center);
    MaxLSum = Method3(a, center+1, right);

    // 求解跨分界线的最大子列和 
    // center -> left
    for(i=center; i>=left; i--){
        LBSum += a[i];
        if(LBSum > MaxLBSum) MaxLBSum = LBSum;
    }
    // center -> right
    for(i=center+1; i<=right; i++){
        RBSum += a[i];
        if(RBSum > MaxRBSum) MaxRBSum = RBSum;
    }
    // 治
    return my_Max(MaxLSum, MaxRSum, MaxLBSum+MaxRBSum);
}

5-3--动态规划

// Method4:在线处理
int Method4(int *a, int N){
    int Sum = 0, MaxSum = 0;
    for(int i = 0; i < N; i++){
        Sum += a[i];
        if(Sum > MaxSum){
            MaxSum = Sum;
        }
        else if(Sum < 0){
            Sum = 0;
        }
    }
    return MaxSum;
}

5-4--完整代码

#include "iostream"
#include <math.h>

class Cal_MaxSeqSum{
public:
    Cal_MaxSeqSum(int *a, int N){
        this -> a = a;
        this -> N = N;
    }

    // Method1:暴力求解
    int Method1(){
        int Sum, MaxSum = 0;
        for(int i = 0; i < this->N; i++){
            for(int j = i; j < this->N; j++){
                Sum = 0; // 计算所有子序列的和
                for(int k = i; k <= j; k++){
                    Sum += this->a[k];
                }
                if(Sum > MaxSum) MaxSum = Sum;
            }
        }
        return MaxSum;
    }

    // Method2:暴力求解
    int Method2(){
        int Sum, MaxSum = 0;
        for(int i = 0; i < this->N; i++){
            Sum = 0;
            for(int j = i; j < this->N; j++){
                Sum += this->a[j];
                if(Sum > MaxSum) MaxSum = Sum;
            }
        }
        return MaxSum;
    }


    // Method3:分而治之
    int my_Max( int A, int B, int C ){ 
        return A > B ? A > C ? A : C : B > C ? B : C;
    }
    int Method3(int *a, int left, int right){
        int MaxLSum = 0, MaxRSum = 0;
        int center, i;
        int MaxLBSum = 0, MaxRBSum = 0;
        int LBSum = 0, RBSum = 0;

        if(left == right){ // 递归终止条件,子列只有一个数字
            if(a[left] > 0) return a[left];
            else return 0;
        }

        // 分
        center = (left + right) / 2; // 分界线
        // 递归求解左子列和右子列的最大和
        MaxLSum = Method3(a, left, center);
        MaxLSum = Method3(a, center+1, right);

        // 求解跨分界线的最大子列和 
        // center -> left
        for(i=center; i>=left; i--){
            LBSum += a[i];
            if(LBSum > MaxLBSum) MaxLBSum = LBSum;
        }
        // center -> right
        for(i=center+1; i<=right; i++){
            RBSum += a[i];
            if(RBSum > MaxRBSum) MaxRBSum = RBSum;
        }
        // 治
        return my_Max(MaxLSum, MaxRSum, MaxLBSum+MaxRBSum);
    }

    // Method4:在线处理
    int Method4(){
        int Sum = 0, MaxSum = 0;
        for(int i = 0; i < this->N; i++){
            Sum += this->a[i];
            if(Sum > MaxSum){
                MaxSum = Sum;
            }
            else if(Sum < 0){
                Sum = 0;
            }
        }
        return MaxSum;
    }

    int *a;
    int N;
};

int main(int argc, char* argv[]){
    // 初始化序列
    int N = 8;
    int seq[] = {4, -3, 5, -2, -1, 2, 6, -2};

    Cal_MaxSeqSum cal(seq, N);
    int sum1 = cal.Method1();
    int sum2 = cal.Method2();
    int sum3 = cal.Method3(seq, 0, N-1);
    int sum4 = cal.Method4();

    std::cout << "Sum1: " << sum1 << std::endl;
    std::cout << "Sum2: " << sum2 << std::endl;
    std::cout << "Sum3: " << sum3 << std::endl;
    std::cout << "Sum4: " << sum4 << std::endl;

    return 0;
}

        运行结果: 

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

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

相关文章

JS手写Promise(详细过程)

PS&#xff1a;JS手写Promise方法的整理在下一篇文章 手写Promise的API(resolve,reject,then,catch,finally,all)_Eric加油学&#xff01;的博客-CSDN博客 1、基础版Promise 首先&#xff0c;通过一个简单的Promise例子回顾其使用 const promise new Promise((resolve, rej…

为什么诚信是项目管理的关键部分?

由于有许多需要指导的活动部件和风险&#xff0c;管理一个新项目可能是一项具有挑战性的工作。在一些对质量有着严格要求的行业&#xff0c;项目结构、设定目标、跟踪状态、风险管理和资源管理等项目管理原则尤为重要&#xff0c;而领导这项工作的是诚信。那么&#xff0c;究竟…

IP 归属用 Ip2region 就够了

文章目录Ip2region 简介是什么特性支持的编程语言案例实操依赖获取IP输入流转化解析IP测试抖音、微博、小红书等各平台相继上线" 网络用户IP地址显示功能"&#xff0c; 境外显示 国家&#xff0c; 境内显示到 省市&#xff0c;且该功能无法关闭&#xff0c;IP地址为强…

【新2023Q2模拟题JAVA】华为OD机试 - 分苹果

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:分苹果 题目 AB两个人把苹果…

第16章_变量、流程控制与游标

第16章_变量、流程控制与游标 &#x1f3e0;个人主页&#xff1a;shark-Gao &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是shark-Gao&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f389;目前状况&#xff1a;23届毕业生&#xf…

ClickHouse学习笔记(三):MergeTree 原理解析

文章目录1、简介2、MergeTree 创建方式与存储结构2.1、MergeTree 的创建方式2.2、MergeTree 的存储结构3、MergeTree 数据分区3.1、分区目录的命名规则3.2、分区目录合并过程4、一级索引4.1、索引粒度4.2、索引生成4.3、索引查询5、二级索引6、数据存储7、数据标记8、协同总结8…

BootStrap4:栅格系统

1、container容器 container&#xff1a;固定宽度的容器container-fluid&#xff1a;响应式容器 2、栅格选项 Bootstrap4 总共有五个栅格等级&#xff0c;每个响应式分界点隔出一个等级 Ps&#xff1a;.row上带有margin-left: -15px;margin-right: -15px;属性&#xff0c;你…

【22年蓝桥杯】十三届蓝桥杯真题JavaB组解析+代码(带你复习知识点)(一)

试题 A: 星期计算 【填空题】 答案&#xff1a;7 解析&#xff1a;直接对所给数进行取余&#xff0c;然后直接再加6&#xff08;注意&#xff1a;不能直接让20^226再对7进行取余操作&#xff0c;这是不对的&#xff0c;这个6可以看成已经取余过了。&#xff09; 直接取余的话可…

Linux系统安装部署及配置Grafana

TOC 用于 UI 展示 wget https://dl.grafana.com/oss/release/grafana-8.0.3-1.x86_64.rpm1 安装 grafana 1.1 下载安装 wget https://dl.grafana.com/oss/release/grafana-8.0.3-1.x86_64.rpmsudo yum install grafana-8.0.3-1.x86_64.rpm1.2 启动&状态查看 sudo syst…

PHP初级教程------------------(3)

目录 文件包含 文件包含的作用 文件包含四种形式 文件加载原理 Include和require区别 文件加载路径 文件嵌套包含 函数 函数的基本概念 函数定义语法 函数命名规范 参数详解 形参 实参 默认值 引用传递 函数体 函数返回值 ​作用域 静态变量 可变函数 匿名函数 闭包 伪类型 文件…

作为一个数学专业的学生,我是怎么看待编程的?

1.概况 博主的专业是数学与应用数学&#xff0c;简称应数。虽然后面跟了个应用数学&#xff0c;但是这个专业应该是本科阶段最接近数学的专业了。我认为这个专业使我具有如下的几个优势&#xff1a; 数学的学习使我具有较强的思维能力。编程本质上就是通过写代码的方式来解决…

大数据Flink进阶(八):Apache Flink架构介绍

Apache Flink架构介绍 一、Flink组件栈 在Flink的整个软件架构体系中,同样遵循这分层的架构设计理念,在降低系统耦合度的同时,也为上层用户构建Flink应用提供了丰富且友好的接口。

山东大学机器学习大作业

数据处理与可视化这里是DLRM模型数据集预处理模块&#xff1a;args.ln_emb ln_emb.tolist() m_spa args.arch_sparse_feature_sizeln_emb np.asarray(ln_emb)num_fea ln_emb.size 1 # num sparse num dense featuresm_den_out ln_bot[ln_bot.size - 1]Sparse fea 26, D…

Java设计模式-3、单例模式

单例模式 单例模式属于创建型模式&#xff0c;⼀个单例类在任何情况下都只存在⼀个实例&#xff0c; 构造⽅法必须是私有的、由⾃⼰创建⼀个静态变量存储实例&#xff0c;对外提供⼀ 个静态公有⽅法获取实例。 优点是内存中只有⼀个实例&#xff0c;减少了开销&#xff0c;尤…

代码随想录|day26|回溯算法part03● 39. 组合总和● 40.组合总和II● 131.分割回文串

今天的练习基本就是回溯法组合问题&#xff0c;这一节只要看labuladong即可。 组合问题&#xff1a; 39. 组合总和---------------------形式三&#xff0c;元素无重可复选 链接&#xff1a;代码随想录 一次对&#xff0c;同样在进入下次循环时&#xff0c;注意startindex是从j…

欧莱雅校招负责人张泽宇:拥抱Z世代,探索新玩法

作为校招HR&#xff0c;你在雇主品牌创新实践的路上做过什么尝试&#xff1f; 2020年&#xff0c;欧莱雅正式推出了全新的雇主品牌价值主张 —— 敢为敢超越&#xff0c;就是欧莱雅&#xff08;Freedom to go beyond, thats the beauty of L’ORAL&#xff09;&#xff0c;鼓励…

使用ChatGPT进行AI对话

1.ChatGPT简介 ChatGPT是美国人工智能研究实验室OpenAI新推出的一种人工智能技术驱动的自然语言处理工具&#xff0c;使用了Transformer神经网络架构&#xff0c;也是GPT-3.5架构&#xff0c;这是一种用于处理序列数据的模型&#xff0c;拥有语言理解和文本生成能力&#xff0c…

C/C++ 日期 时间 函数总结

使用C标准库 有四个与时间相关的类型&#xff1a;clock_t、time_t、size_t 和 tm。类型 clock_t、size_t 和 time_t 能够把系统时间和日期表示为某种整数 头文件 #include <time.h> #include <stdio.h> tm 结构: struct tm {int tm_sec; // 秒&#xff0c;…

隐私计算-TEE执行环境

一、TEE 的定义 论述完 TEE 的概念后&#xff0c;接下来进一步解析 TEE 的深层定义。目前对于 TEE 的定义有很多种形式&#xff0c;针对于不同的安全性需求和平台&#xff0c;TEE 的定义也不尽相同&#xff0c;但在所有 TEE 的定义中都会包含两个最关键的点&#xff1a;独立执…

谈谈分布式一致性机制

分布式中一致性是非常重要的&#xff0c;分为弱一致性和强一致性。 现在主流的一致性协议一般都选择的是弱一致性的特殊版本&#xff1a;最终一致性。下面就从分布式系统的基本原则讲起&#xff0c;再整理一些遵循这些原则的协议或者机制&#xff0c;争取通俗易懂。 但是要真…