基础数据结构和算法1:简介

1、数据结构

1.1 数据结构是什么?

数据结构是由数据和结构两方面组成,例如:

学生信息:

No.姓名年龄性别
1张三21
2李四22
3王五23

数据就是姓名、年龄和性别,结构就是姓名、年龄和性别的关系。
数据结构指的是数据与数据之间的逻辑关系
(1)计算机存储、组织数据的方式
(2)相互之间存在一种或多种特定关系的数据元素的集合

1.2 数据结构有什么用?

解决问题,如何高效(多快好省)的从已知数据求解未知数据

1.3 数据结构分类

No.分类特点e.g.
1集合结构杂乱无章无序关系班级座次
2线性结构一对一前驱后继顺序关系糖葫芦
3树形结构一对多祖先后代层次关系族谱
4图状结构多对多错综复杂网状结构铁路路线图

2、算法

2.1 算法是什么?

算法指的是解决特定问题的步骤和方法。

2.2 算法有什么用?

解决问题,如何高效(多快好省)的从已知数据求解未知数据。

2.3 如何判断算法的好坏?

对于一个问题的算法来说,之所以称之为算法,首先它必须能够解决这个问题(称为准确性)。其次,通过这个算法编写的程序要求在任何情况下不能崩溃(称为健壮性)。

如果准确性和健壮性都满足,接下来,就要考虑最重要的一点:通过算法编写的程序,运行的效率怎么样。

运行效率体现在两方面:
(1)算法的运行时间(称为“时间复杂度”)
(2)运行算法所需的内存空间大小(称为“空间复杂度”)

2.3.1 时间复杂度

1、时间复杂度是什么?

(1)算法的运行时间受硬件、系统等多个因素影响。我们使用一个与环境无关的方式评价算法执行速度:时间复杂度
(2)时间复杂度主要度量基本操作重复执行的次数,是输入规模和基本操作的数量关联,随着输入规模扩大的增长量

2、如何表示时间复杂度?

用O记号表示算法的时间性能
P(多项式)

No.表示级别
1O(1)常数(Constant)
2O(log_2n)对数(Logarithmic)
3O(n)线性(Linear)
4O(nlog_2n)线性对数(Linear Logarithmic)
5O(n^2)平方(2 Square)
6O(n^2)立方(3 Square)

NP(非确定多项式)

No.表示级别
1O(2^n)指数(Exponential)
2O(n!)阶乘(Factorial)
3O(n^n)n次方(n Square)

常用的时间复杂度从小到大的排序
O(1) < O(log_2n) < O(n) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)
在这里插入图片描述

2.3.2 空间复杂度

1、空间复杂度是什么?

空间复杂度是指运行完一个程序所需内存的大小

2、如何表示空间复杂度

一个程序执行时除了需要存储空间和存储本身所使用的指令、常数、变量和输入数据外,还需要对一些对数据进行操作的工作单元和存储一些为现实计算所需信息的辅助空间。程序执行时所需存储空间包括一下两部分:
(1)固定部分,这部分空间的大小与输入/输出的数据的个数多少、数值无关。主要包括指令空间(即代码空间)、数据空间(常量、简单变量)等所占的空间。这部分属于静态空间。
(2)可变空间。这部分空间的主要包括动态分配的空间,以及递归栈所需的空间等。这部分的空间大小与算法有关。

3、如何计算时间复杂度?

(1)找出基本语句(执行次数最多的语句)
最内层循环的循环体
(2)计算基本语句的执行次数的数量级
(3)只保留最高次幂,忽略低次幂和最高次幂的系数
用大O记号表示算法的时间性能

No.语句时间复杂度
1顺序语句、分支语句O(1)
2循环语句O(n^2)
3递归O(log_2n)、O(2^n)

3.1 O(1)

#include <stdio.h>
int main(){
    int n;
    scanf("%d",&n);
    printf("%d\n",n);
}

3.2 O(n)

#include <stdio.h>
int main(){
    int n;
    scanf("%d",&n);
    int count=0;
    for(int i=0;i<n;i++){
        printf("%d\n",++count);
    }
}

3.3 O(n^2)

int n;
scanf("%d",&n);
int count = 0;
for(int i=0;i<n;++i){
    for(int j=0;j<n;++j){
        printf("%d\n",++count);
    }
}

3.4 O(n^3)

int n;
scanf("%d",&n);
int count = 0;
for(int i=0;i<n;++i){
    for(int j=0;j<n;++j){
        for(int k=0;k<n;++k){
            printf("%d\n",++count);
        }
    }
}

3.5 O(log_2n)

int n;
scanf("%d",&n);
int count = 0;
for(int i=0;i<n;i*=2){
    printf("%d\n",++count);
}

3.6 O(2^n)

int n;
scanf("%d",&n);
int count = 0;
for(int i=0;i<pow(2,n);++i){
    printf("%d\n",++count);
}

3.7 O(n!)

long long factorial(int n){
    int res = 1;
    for(int i=1;i<n;++i){
        res*=i;
    }
    return res;
}

int n;
scanf("%d",&n);
int count = 0;
for(int i=0;i<factorial(n);++i){
    printf("%d\n",++count);
}

4、线性结构

数据结构中最常用最简单的结构是线性结构。
线性结构,又称线性表。逻辑结构上数据元素之间存在一个对一个的相邻关系。线性结构是n个数据元素的有序(次序)集合,它有下列几个特征:
1.集合中必存在唯一的一个"第一个元素";
2.集合中必存在唯一的一个"最后的元素";
3.除最后元素之外,其它数据元素均有唯一的"后继";
4.除第一元素之外,其它数据元素均有唯一的"前驱"。

5、练习

1、未出现的数字

从非负整数序列 0, 1, 2, …, n 中给出包含其中 n 个数的子序列,请找出未出现在该子序 列中的那个数。
输入描述:
输入为 n+1 个非负整数,用空格分开。
其中:首个数字为非负整数序列的最大值 n,后面 n 个数字为子序列中包含的数字。
输出描述:
输出为 1 个数字,即未出现在子序列中的那个数。
示例:

#include <bits/stdc++.h>
using namespace std;

int main() {
   int n = 0;
   scanf("%d",&n);
   int sum = 0;
   for(int i=0;i<n;++i){
       int n = 0;
       scanf("%d",&n);
       sum += n;
   }
   int sum_n = n*(n+1)/2; // 等差数列求和公式
   printf("%d\n",sum_n - sum);   
   return 0;
}

2、两个有序数组的归并输出

输入一个整数n(n <= 10000)和n个整数a[i],保证这n个整数已按照从小到大进行排序。然后输入一个整数m(m <= 10000),和m个整数b[j],保证这m个整数已按照从小到大进行排序。
将两组数归并后输出。

#include <stdio.h>

int main(){
    int n;
    scanf("%d",&n);
    int a[n];
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }

    int m;
    scanf("%d",&m);
    int b[m];
    for(int j=0;j<m;j++){
        scanf("%d",&b[j]);
    }

    int c[n+m];
    int i=0,j=0,k=0;
    while(i<n && j <m){
        if(a[i] < b[j]){
	    c[k++] = a[i++];
	}else if(a[i] == b[j]){
	    c[k++] = a[i++];
	    j++;
	}else{
	    c[k++] = b[j++];
	}
    }
    while(i<n){
        c[k++] = a[i++];
    }
    while(j<m){
        c[k++] = b[j++];
    }
    int count =k;
    for(k=0;k<count;k++){
        printf("%d\n",c[k]);
    }
    return 0;

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值