数据结构学习笔记系列1——数据结构概论

数据结构学习笔记系列1
视频网址: https://www.bilibili.com/video/av18586085
汇总贴链接:https://blog.csdn.net/DX5618258/article/details/104085229

1.1.1关于数据组织

例1.如何在书架上摆放图书
操作1:新书如何插入
操作2:如何查找书

方法1:随便放
操作1:哪里有空放哪里
操作2:累死
方法2:按照书名的拼音字母顺序排放
操作2:二分查找(如:从L开始分前后区(类似解方程的二分法))
操作1:新书插入难(其后的每本书都需要后移)
方法3:把书架划分几块区域,每块区域指定摆放某种类别的书,在每种类别内按照书名的拼音字母顺序排放
操作1:新书插入(先确定类别,二分查找,移除空位)
操作2:限定类别,再二分查找

问题:1.空间如何分配 2.类别分多细
总结:解决问题方法的效率和数据的组织方式有关

1.1.2关于空间使用

例2:写程序实现printN,使得传入一个正整数N的参数后,能顺序打印从1到N的全部正整数。
以下为两种输出程序: 1. 循环输出 2. 递归输出

#include <iostream>

void PrintN(int N);
//程序入口
int main()
{  
    int N;  
    scanf_s("%d" , &N );  
    PrintN( N );  
    return 0;  
}
//循环输出
void PrintN(int N) 
{  
    for (int i = 1; i <= N;i++) 
    {  
        printf("%d\n",i);  
    }  
}
//递归输出(占用大量内存后再输出)
void PrintN(int N) 
{  
    if (N) 
    {  
        PrintN(N-1);  
        printf("%d\n", N);  
    }  
    return; 
}

问题:当N达到10000量级时(每台机器的配置和性能可能有所区别,当N足够大时结果都是一样的),递归输出程序出现异常,原因是占用内存过大,程序崩溃
总结:解决问题方法的效率和空间的利用效率有关

注:scanf、gets等语句无法正常使用,按照错误列表的提示修改指定位置的scanf和gets等语句,scanf改为scanf_s,gets改为gets_s……(而且,scanf在读取数据时不检查边界,可能会造成内存访问越界的问题,使用scanf_s,会多一个参数来控制读取的字符数量,这样确实比使用scanf输入更加安全。)

1.1.3 关于算法效率

例3:写程序计算给定多项式在给定点x处的值

f(x)=a_0+a_1 x+⋯+a_(n-1) x^(n-1)+a_n x^n

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;
}
f(x)=a_0+x(a_1+x(⋯(a_(n-1)+x(a_n ))⋯))
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;
}

例3的问题具体化:多项式简化为系数以所在项索引值相同的多项式,即在这里插入图片描述
并计算该多项式在点x=1.1处的值f(1.1)。

#include <iostream>
#include <time.h>  //clock ()函数需要调用此头文件
#include <math.h>  //在vs中可以不调用此头文件也可以计算pow ()函数

//clock_t是clock()函数返回的变量类型,两个变量代表程序运行起止时间
clock_t start, stop;
//记录被测函数的运行时间,单位是秒
double duration;
//定义多项式最大项数
#define MAXN 10
//定义函数执行次数
#define MAXK 1e7
//测试函数的声明
double f1(int n, double a[], double x);
double f2(int n, double a[], double x);

int main()
{
    /*声明并初始化系数数组*/
    double a[MAXN];
    for (int i = 0; i < MAXN; i++) 
    {  
        a[i] = (double)i;  
    }

    start = clock();/*开始计时*/
    for (int i = 0; i < MAXK; i++) 
    {  
        f1(MAXN - 1, a, 1.1);  
    }
    stop = clock();   /*结束计时*/
    duration = (((double)(stop - start)) / CLK_TCK) /MAXK;
    printf("ticks1 = %f\n",(double)(stop - start));
    printf("duration1 = %6.2e\n",duration);

    start = clock();/*开始计时*/
    for (int i = 0; i < MAXK; i++)
    {	
        f2(MAXN - 1, a, 1.1);  
    }
    stop = clock();/*结束计时*/
    duration = (((double)(stop - start)) / CLK_TCK) / MAXK;
    printf("ticks2 = %f\n", (double)(stop - start));
    printf("duration2 = %6.2e\n", duration);
    return 0;
}

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

测试结果如下图
在这里插入图片描述
计算结果表明采用第二种方法计算多项式会使计算时间缩短一个数量级。

注:程序中下划线部分是为了使时间足够大,便于数据准确及数据采集,否则结果如下
在这里插入图片描述

结论:解决问题方法的效率和算法的巧妙程度有关

1.1.4 抽象数据类型

问:到底什么是数据结构
1.数据对象在计算机中的组织方式:

  • 1.1 逻辑结构:一对一、线性结构;一对多、树型结构;多对多、图型结构;

  • 1.2 物理存储结构

2.数据对象必定与一系列加在其上的操作相关联,完成这些操作所用的方法就是算法

抽象数据类型(Abstract Data Type)
数据类型:数据对象集;数据集合相关联的操作集
抽象:描述数据类型的方法不依赖于具体实现。即
1.与存放数据的机器无关;
2.与数据存储的物理结构无关;
3.与实现操作的算法和编程语言无关;
综上所述:抽象即只描述数据对象集合相关操作集“是什么”,不涉及“如何做到”的问题。

简单地类比就是只看函数的输入和输出,不看这个函数是如何实现的具体过程。

例4:“矩阵”的抽象数据类型定义
类型名称:矩阵(Matrix)
数据对象集:一个MxN的矩阵A_(M×N)=(a_ij)(i=1,⋯,M;j=1,⋯,N)由MxN个三元组<a,i,j>构成,其中a是矩阵元素的值,i是元素所在的行号,j是元素所在的列号。
操作集:对于任意矩阵A、B、C∈Matrix,以及整数i、j、M、N
Matrix Create(int M ,int N):返回一个MxN的空矩阵;
int GetMaxRow(Matrix A):返回矩阵A的总行数;
int GetMaxCol(Matrix A):返回矩阵A的总行数;
Matrix Add(Matrix A,Matrix B):如果A和B的行、列数一致,则返回矩阵C=A+B,否则返回错误标志;

抽象的地方例如:
矩阵A_(M×N)是二维数组还是一维数组还是十字链表并未指明,在此处并不关心其是否是哪种类型;
Matrix Add操作是先按行相加还是先按列相加,用什么语言来实现这个操作,在此处并不关心。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!关于学习数据结构的C语言笔记,我可以给你一些基本的指导和概念。数据结构是计算机科学中非常重要的一门课程,它涉及存储和组织数据的方法。C语言是一种常用的编程语言,很适合用于实现各种数据结构。 下面是一些数据结构的基本概念,你可以在学习笔记中包含它们: 1. 数组(Array):一种线性数据结构,可以存储相同类型的元素。在C语言中,数组是通过索引访问的。 2. 链表(Linked List):也是一种线性数据结构,但不需要连续的内存空间。链表由节点组成,每个节点包含数据和指向下一个节点的指针。 3. 栈(Stack):一种后进先出(LIFO)的数据结构,类似于装满物品的箱子。在C语言中,可以使用数组或链表来实现栈。 4. 队列(Queue):一种先进先出(FIFO)的数据结构,类似于排队等候的队伍。同样可以使用数组或链表来实现队列。 5. 树(Tree):一种非线性数据结构,由节点和边组成。每个节点可以有多个子节点。二叉树是一种特殊的树结构,每个节点最多有两个子节点。 6. 图(Graph):另一种非线性数据结构,由节点和边组成。图可以用来表示各种实际问题,如社交网络和地图。 这只是数据结构中的一些基本概念,还有其他更高级的数据结构,如堆、哈希表和二叉搜索树等。在学习笔记中,你可以介绍每个数据结构的定义、操作以及适合使用它们的场景。 希望这些信息对你有所帮助!如果你有任何进一步的问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值