数据结构-浙江大学-开篇(一)

简介

此数据结构的基于数据结构-浙江大学的视频教材的学习整理。

感谢陈越和何钦铭两位老师!


先看一个例子:顺序输出1-N个正整数

#include <stdio.h>

void printN(int N)
{
    for (int i = 0; i<N; i++) {
        printf("%d ", i);
    }
    return;
}

void printN2(int N)
{
    if (N > 0) {
        printN2(N - 1);
        printf("%d ", N);
    }
}

int main(int argc, const char * argv[]) {
    printN2(1000000);
}

可以看到,有两个做法,一个是直接使用for循环,一个是使用递归。

在N = 1,10,100,1000,10000,100000。。。。做实验

你会发现,数据量越大,递归到最后直接报内存不足。
这是因为,函数一直没有释放,函数每次调用都要入栈,每次只入不出,栈满了,导致内存不足,报错。

解决问题方法的效率,跟空间的利用率有关

这,就引出我们今天的话题----数据结构


在这里插入图片描述

#include <stdio.h>
//n表示n,x表示f(x)中x的值,a[]表示:[a0,a1,a2...an]
double f(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;
}

int main(int argc, const char * argv[]) {
    double a[] = {1, 2, 3};
    //计算数学式:1 + 2*2^1+ 3*2^2
    printf("%f\n", f(3, a, 2));
    //1*2^0 + 2*2^1 + 3*2^2 = 1 + 4 + 12 = 17
}

计算其算法复杂度:
+和-法忽略不计
n次循环
每次循环需要:a[i] * pow(x, i) = a[i] * x^i
(a[i]) 乘以 (x^i )是1次
x^i是i-1次
所以,a[i] * pow(x, i)是i次
1 + 2 + 3 +…+n = n(1+n)/2=(n+n*n)/2
忽略常数,只算最高位
那么,这个算法的时间复杂度是n^2

个人觉得这个算法挺好的,主要是思考的时候简单,老师说 ,这么写会被鄙视。。。

秦九韶算法

有个秦九韶算法,这么写的:
在这里插入图片描述
提取公因子x,写程序的时候,从里往外算(写)

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;
}

计算其算法复杂度:
+和-法忽略不计
n次循环
每次循环需要:x*p
那么,这个算法的时间复杂度是n

同样一道题,使用不同的方法,其算法的时间复杂度是不一样的
因此,如果将问题借的更好,就是数据结构与算法研究的问题

那,什么是数据结构呢?


数据结构:

数据对象在计算机中的组织形式,包括:
逻辑结构
物理存储结构

数据对象不是孤立存在的,数据对象必定与一些列加在其上的操作相关联

完成这些操作所用的方法就是算法

抽象数据类型(Abstract Data Type)

数据类型:
数据对象集
数据集合相关联的操作集

抽象:描述数据类型的方法不依赖于具体方法
包括:
与存放数据的机器无关
与数据存储的物理结构无关
与实现操作的算法和编程语言无关

也就是:只描述数据对象集和操作“是什么”,而不关心“怎么做到”


算法

算法(Algorithm)
一个有限指令集
接收一些输入(有可能没输入)
产生输出
一定在有限步骤之后终止
每一条指令必须:有充分明确的目标,不能有歧义。计算机能处理的范围内

算法的判断标准:
空间复杂度:根据算法写成的程序在执行时占用存储单元的长度

时间复杂度:根据算法写成的程序在执行时耗费时间的长度
在计算时间复杂度的时候,+ -法忽略不计
只算阶层最高的

我们关注时间复杂度,最主要的是关注两个:
最坏情况复杂度
平均复杂度

在这里插入图片描述我们不对算法做精确处理,只需要掌握其增长趋势即可。

不同的函数增长速度:
在这里插入图片描述
在这里插入图片描述


求最大子列和问题

给定{1, -3, 8, 10, -9},求里面连续相加的最大值。
{8, 10}
在这里插入图片描述
方案一:暴力法,一个一个加

int MaxSubseqSum1(int A[], int N)
{
    int ThisSum, MaxSum = 0;
    int i, j, k;
    for (i = 0; i<N; i++) {//i是子列左端的位置
        for (j = i; j<N; j++) {//j是子列右端的位置
            ThisSum = 0;
            for (k = i; k<=j; k++) {
                ThisSum += A[k];//ThisSum是A[i]到A[j]的子列和
            }
            if (ThisSum > MaxSum) {//如果ThisSum大于MaxSum,则MaxSum = ThisSum
                MaxSum = ThisSum;
            }
        }
    }
    return MaxSum;
}

时间复杂度是O(N^3)

方案二:

int MaxSubseqSum2(int A[], int N)
{
    int ThisSum, MaxSum = 0;
    int i, j;
    for (i = 0; i<N; i++) {//i是子列左端的位置
        ThisSum = 0;
        for (j = i; j<N; j++) {//j是子列右端的位置
            ThisSum += A[j];//ThisSum是A[i]到A[j]的子列和
            if (ThisSum > MaxSum) {//如果ThisSum大于MaxSum,则MaxSum = ThisSum
                MaxSum = ThisSum;
            }
        }
    }
    return MaxSum;
}

时间复杂度O(N^2)

方案三:分治法
在这里插入图片描述
时间复杂度O(NlogN);

方案四:在线处理法

int MaxSubseqSum4(int A[], int N)
{
    int ThisSum = 0, MaxSum = 0;
    int i;
    for (i = 0; i<N; i++) {//i是子列左端的位置
        ThisSum += A[i];
        if (ThisSum > MaxSum) {//如果ThisSum大于MaxSum,则MaxSum = ThisSum
            MaxSum = ThisSum;
        }else if (ThisSum < 0){
            ThisSum = 0;
        }
    }
    return MaxSum;
}

时间复杂度O(N)


参考PPT

参考PPT

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值