- 数据结构主要研究非数值计算程序设计中的操作对象,以及这些对象之间关系和操作的学科。
- 三个实例:学生学籍管理系统,人机对弈问题,最短路径问题。
- 电话号码查询系统设有一个电话号码薄,它记录了N个人的名字和其相应的电话号码,假定按如下形式安排:
(a1,b)(a2,b2)…(an b),其中a,b(i=1,2.n)分别表示某人的名字和对应的电话号码,要求设计一个算法,当给定任何一个人的名字时,该算法能够打印出此人的电话号码,如果该电话簿中根本就没有这个人,则该算法也能够报失没有这个人的标志。 - 结构体概念的引入:
- 结构体如何取名:
- 在定义结构体的花括号之后加上别名;
- 在main函数中另起一行调用该结构体;
- 结构体的引用:
- 别名+ · +元素;
- 结构体中嵌套的结构体:外别名内别名元素
- typedef可以把别名由变量转化为类型,也就是说运用时需要额外定义:stu stt;
- 结构体指针
- 定义指针: stu*pstu=&stt;
- 引用:pstu->ID=666;(实现修改)
- 结构体数组:
- 别名处和定义时写成数组的形式即可。
- 最终答案:
#include<stdio.h>
#include<string.h>
#define N 10
//定义结构体
struct person
{
char name[9];
char phone[12];
} per[N];
int main()
{
int n = sizeof(per) / sizeof(per[0]);//计算数组的个数(数组的大小除以单个元素的大小)
char name1[9];
struct person per[N]={
{"张三", "13800138000"},
{"李四", "13900139000"},
{"王五", "13700137000"}
};
printf("输入姓名:");
scanf("%s",name1);
for(int i=0;i<n;i++)
{
if(strcmp(per[i].name, name1) == 0)
printf("TA的电话号码为:%s\n",per[i].phone);
}
return 0;
}
#include<stdio.h>//需要手动存入数据的方法
#include<string.h>
#define N 10
//定义结构体
struct person
{
char name[9];
char phone[12];
} per[N];
int main()
{
int n;
char name1[9];
printf("请输入电话簿的人数:");
scanf("%d",&n);
struct person per[N];
printf("请手动存入数据:\n");
for(int i=0;i<n;i++)
{
scanf("%s %s",per[i].name,per[i].phone);
}
printf("输入姓名:");
scanf("%s",name1);
for(int i=0;i<n;i++)
{
if(strcmp(per[i].name, name1) == 0)
printf("TA的电话号码为:%s\n",per[i].phone);
}
return 0;
}
-
数据结构的基本概念和术语
-
抽象数据类型
- 抽象数据类型的定义格式:(D,S,P)
ADT 抽象数据类型名
{
数据对象:<数据对象的定义>
数据关系:<数据关系的定义>
基本操作:<基本操作的定义>
}ADT 抽象数据类型名 - 基本操作的定义格式:
基本操作名(参数表)
初始条件:<初始条件描述>
操作结果:<操作结果描述>
基本操作的两种参数:
赋值参数:为操作提供输入值
引用参数:以“&”打头,可提供输入值,还可以返回操作结果
//通过a和b的交换来理解&的含义
//1.使用&的情况
#include<stdio.h>
int swap(int &i,int &j)
{
int m;
m=i;
i=j;
j=m;
return i,j;
}
int main()
{
int a=8,b=5;
swap(a,b);
printf("%d %d",a,b);
return 0;
}
//2.纯C语言的情况
#include<stdio.h>
int swap(int *i,int *j)
{
int m;
m=*i;
*i=*j;
*j=m;
return *i,*j;
}
int main()
{
int a=8,b=5;
swap(&a,&b);
printf("%d %d",a,b);
return 0;
}
- 本书采用的类c语言的简要说明:
- 预定义常量和类型:#define表示
- 数据结构的表示用类型定义(typedef)描述,数据元素类型用ElemType
- 基本操作的算法用以下格式来描述:
- 函数类型 函数名(函数参数表)
- {语句序列}
- 以&打头的为引用参数,当函数返回值为函数结果代码时,函数定义为status类型。
- 内存的动态分配和释放内存空间
分配:指针变量=new数据类型(malloc)
释放空间:delete指针变量(free) - 赋值,选择和循环省略。
- 内存的动态分配和释放内存空间
- 算法分析
- 定义:为了解决某类问题而规定的一个有限长的操作序列。
- 算法5个重要特性:有穷性,确定性,可行性,输入,输出。
- 评价标准:正确性,可读性,健壮性,高效性。
- 时间复杂度
- 语句频度:一条语句的重复执行次数。语句频度之和为算法的执行时间。
- 时间复杂度定义:随着问题规模n的变大,算法执行时间的增长率和基本语句执行次数的函数f(n)的增长率相同,称作算法的渐进时间复杂度,简称时间复杂度。
- 时间复杂度表示的基本方法:把语句频度最大的作为基本语句,计算基本语句频度得到问题规模n的某个函数f(n),取其数量级用符号“Ο”表示。
- 常见:常量阶Ο(1),线性阶Ο(n),平方阶Ο(n*2),立方阶,对数阶Ο(log2n)
- 语句频度的计算:常数为1,多项式保留最高次项并且去掉次数,有多少次循环就是n的多少次方。
- 最好时间复杂度,最坏时间复杂度和平均时间复杂度(f(n)=n/2)
- 空间复杂度
- 定义:算法的存储空间和数据规模之间的增长关系。
- 递归的深度有多大,算法的空间复杂度就有多大。
- 求解方法:找变量。
- 变量=常量时,就是Ο(1)
- 当变量为数组,list等,其中变量的值随着输入值的改变而改变的时候空间复杂度就有可能是Ο(n)
- 如果是nums(变量)的平方倍时可能是Ο(n*2)(一般是二维数组)
- 递归函数:一般为Ο(n),用到了递归栈。
- 小结
-
本章思维导图
-
两个易错的时间复杂度
此时间复杂度为O(1)。常数级。
此时间复杂度为O(根号n)。y的x次为两个n相乘,则次数x为根号下n。