知识点
程序=算法+数据结构
数据结构:是一门研究非数值计算的程序设计问题中计算机的操作对象以及它们之间的关系和操作等的学科。
空间数据结构:研究空间数据如何在计算机中表达、组织和管理。
抽象数据类型:由用户定义,表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称。具体包括三部分:数据对象、数据对象上的关系的集合和对数据对象的基本操作的集合。
数据结构和抽象数据类型的概念与程序设计中的数据类型概念的区别:
数据结构是指数据元素之间的关系和组织方式,而抽象数据类型是对数据结构的抽象描述,定义了数据的逻辑结构和操作。数据类型概念则是程序设计中用来表示数据的类型,包括基本数据类型和自定义数据类型。
数据结构和抽象数据类型更侧重于数据的组织和操作方式,而数据类型概念更侧重于数据的类型和特性。
数据:所有能输入到计算机去的描述客观事物的符号
数据元素:数据的基本单位,也称节点node或记录record
数据项:有独立含义的数据最小单位,也称域
根据数据元素间关系的基本特性,有四种基本数据结构:
①集合:数据元素间除“同属于一个集合”外,无其他关系
②线性结构:一个对一个,如线性表、栈、队列
③树形结构:一个对多个,如树
④图状结构:多个对多个,如图
数据的逻辑结构:只抽象反映数据元素的逻辑关系
数据的存储(物理)结构:数据的逻辑结构在计算机存储器中的实现
存储结构分为顺序存储结构和链式存储结构。
顺序存储结构:借助元素在存储器中的相对位置来表示数据元素间的逻辑关系
易错——顺序存储结构是顺序存储,随机存取!
链式存储结构:借助指示元素存储地址的指针表示数据元素间的逻辑关系
算法:解决某一特定问题的具体步骤的描述,是指令的有限序列。
算法的5个重要特性:有穷性、确定性、可行性、输入、输出
- 有穷性:一个算法必须总是在执行有穷步之后结束,且每一步都在有穷的时间内完成
- 确定性:算法中每一条指令必须有确切的含义
- 可行性:算法中描述的操作都是可以通过已经实现的基本运算执行有限次来实现
- 输入:一个算法有0个或多个输入
- 输出:一个算法有1个或多个输出
数据结构中评价算法的两个重要指标:时间复杂度和空间复杂度
时间复杂度:基本操作重复执行的次数是问题规模n的某个函数,记作:
空间复杂度:类似于时间复杂度,作为算法所需存储空间的量度
评价算法的两个重要指标/5个重要特征、鲁棒性名词解释、线性结构插入、删除时移动元素个数
第一周上机作业:
1、从文本文件source.txt中读取若干整数,基于冒泡排序法进行从大到小排序(分别实现基于数组的排序、基于链表的排序),并输出至文本文件result.txt中。
基于数组的排序
若文件中整数的个数已知,假设固定为6个:
#include <stdio.h>
int main()
{
int i,j,temp=0;
int a[6];
FILE *file,*resultfile;
file=fopen("D:\\Cfiles\\source.txt","r");
if(file==NULL)
{
printf("Error opening file\n");
return 1;
}
else
{
for(i=0;i<6;i++)
fscanf(file,"%d",&a[i]);
fclose(file);
for(i=0;i<6;i++)
{
for(j=0;j<5-i;j++)
if(a[j]<a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
resultfile=fopen("D:\\Cfiles\\result.txt","w");
if(resultfile==NULL)
{
printf("Error creating result file\n");
return 1;
}
for(i=0;i<6;i++)
fprintf(resultfile,"%d ",a[i]);
fclose(resultfile);
}
return 0;
}
基于链表的排序
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int data;
struct Node* next;
} Node;
Node* createNode(int data)
{
Node* newNode=(Node*)malloc(sizeof(Node));
newNode->data=data;
newNode->next=NULL;
return newNode;
}
void insertNode(Node** head, int data)
{
Node* newNode=createNode(data);
Node* current=*head;
if (*head==NULL||(*head)->data<=data)
{
newNode->next=*head;
*head=newNode;
}
/*若没有节点或新输入的节点的值大于原来的头节点,
则新输入的节点成为新节点*/
else
{
while (current->next!=NULL&&(current->next->data)>data)
{
current=current->next;
}
newNode->next=current->next;
current->next=newNode;
}
}
void printList(Node* head)
{
FILE* fp=fopen("D:\\Cfiles\\result.txt","w");
while (head!=NULL)
{
fprintf(fp,"%d ",head->data);
printf("%d ",head->data);
head=head->next;
}
fclose(fp);
}
int main()
{
Node* head=NULL;
FILE* fp=fopen("D:\\Cfiles\\source.txt","r");
int num;
if (fp==NULL)
{
printf("Error opening file.\n");
return 1;
}
while (fscanf(fp,"%d",&num)==1)
{
insertNode(&head, num);
}
/*"fscanf(fp,"%d",&num)==1"说明成功输入一个整数*/
fclose(fp);
printList(head);
return 0;
}
2、已知k阶斐波那契序列的定义为
试编写求k阶斐波那契序列的第m项值的函数算法,k和m均以值调用的形式在函数参数表中出现。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int Fibonacci(int k, int m);
int main()
{
int k, m;
printf("请输入斐波那契序列的阶数k:");
scanf("%d",&k);
printf("请输入序列的项数m:");
scanf("%d", &m);
printf("%d阶斐波那契序列的第%d项结果为%d", k, m, Fibonacci(k, m));
return 0;
}
int Fibonacci(int k, int m)
{
int i, sum=0;
if (m <= k - 2)
return 0;
else if (m == k - 1)
return 1;
else
{
for (i = m - k; i < m; i++)
{
sum += Fibonacci(k, i);
}
return sum;
}
}
总结
- vs2019中用到fopen等函数时先要进行宏定义:#define _CRT_SECURE_NO_WARNINGS
- 直接右键文件复制的文件地址只有\,而C语言中文件地址要用\\,如:"D:\\Cfiles\\source.txt"
- 要复习(预习)链表相关的知识