一. 数据结构理论知识:
程序 = 数据结构 + 算法
1.定义:数据结构是指数据与数据之间的逻辑结构、存储结构和运算操作。
逻辑结构:
主要是指数据与数据之间的逻辑物理关系:
线性关系:
数据与数据之间满足一对一的关系:
线性表、栈、队列
层次关系(树形关系):
数据与数据之间满足一对多的关系:
树、二叉树
网状关系(图形关系):
数据与数据之间满足多对多的关系:
图
存储结构:
数据在内存当中的存储方式
顺序存储:
在内存当中开辟一块连续的存储空间
链式存储:
数据在内存当中不需要开辟一块连续的空间
为了让数据与数据之间建立联系,我们把每一个数据称之为结点,结点有两部分组成:数据域和指针域,数据域保存数据,指针域保存后一个结点的地址。
索引存储:
哈希存储(散列表):
需要一个性能比较好的哈希函数(取随机数法、除留取余法等),需要有一个好的冲突处理方式(再哈希法、链地址法等)作为冲突处理方式。
运算操作:增、删、改、查
2 .算法的相关概念
2.1 算法的概念
实现某一个函数功能的方法(解决问题的办法)
2.2 算法的特性
1、算法的有穷性 —— 执行步骤是有穷的
2、算法的确定性 —— 计算步骤无二义性
3、算法的可行性 —— 每个计算步骤能够在有限的时间内完成
4、输入 —— 算法有一个或者多个输入
5、输出 —— 算法有一个或者多个输出
2.3 算法的分析
在保存算法正确无误的情况下,评价算法好坏的方法:
1、消耗时间的多少 —— 越少越好
2、耗费内存的多少 —— 越少越好
3、容易理解、容易调试、容易维护
4、时间复杂度 —— 越少越好
5、空间复杂度 —— 越少越好
2.4 时间复杂度
频度:一个代码执行的次数
1、for(i = 0;i < n; i++) 频度是 n+1
2、for(i = 0; i < n; i++)
for(j = 0; j < n; j++) 频度是 n (n + 1)
时间复杂度:一个代码所有的频度之和,用T(n)表示
T(n) = n + 1+ n(n +1 )= n^2 + 2n + 2 简写 T(n)= O(n^2)
线性表的存储:
线性表的顺序存储:顺序表
线性表的链式存储:链表
二.顺序表
1.概念
顺序表是线性表的顺序存储,需要开辟一块连续的空间,所以使用数组。
为了方便访问顺序表,我们需要定义一个变量last,用以存储最后一个数据的位置,后续代码(用last = -1编写)
2.顺序表代码流程梳理:
①创建一个空的顺序表
②插入数据
③遍历并打印数据
④判断顺序表是否为满
⑤判断顺序表是否为空
⑥删除数据,并返回数据
⑦根据数据修改数据
⑧根据位置修改数据
⑨根据位置查找数据
⑩根据数据查找位置
11.根据位置插入数据
12.
3.顺序表整体代码实现:
#include <stdio.h>
#include <stdlib.h>
#define N 10
typedef struct
{
int data[N];
int last;//last代表的是数组中最后一个有效元素的下标
}seqlist_t;
//1.创建一个空的顺序表
seqlist_t* CreateEpSeqlist();//返回的是申请空间的首地址
//2.向顺序表的指定位置插入数据
int InsertIntoSeqlist(seqlist_t* p, int post, int data);//post第几个位置,data插入的数据
//3.遍历顺序表sequence 顺序 list 表
void ShowSeqlist(seqlist_t* p);
//4.判断顺序表是否为满,满返回1 未满返回0
int IsFullSeqlist(seqlist_t* p);
//5.判断顺序表是否为空
int IsEpSeqlist(seqlist_t* p);
//6.删除顺序表中指定位置的数据post删除位置
int DeletePostSeqlist(seqlist_t* p, int post);
//7.清空顺序表
void ClearSeqList(seqlist_t* p);
//8.修改指定位置的数据
int ChangePostSeqList(seqlist_t* p, int post, int data);//post被修改的位置,data修改成的数据
//9.查找指定数据出现的位置
int SearchDataSeqList(seqlist_t* p, int data);//data代表被查找的数据
//10.合并表
void CombineAB(seqlist_t *p,seqlist_t *pb);
int main()
{
seqlist_t* p = CreateEpSeqlist();//创建一个空的顺序表
InsertIntoSeqlist(p, 0, 1);
InsertIntoSeqlist(p, 1, 2);
InsertIntoSeqlist(p, 2, 3);
InsertIntoSeqlist(p, 3, 4);
ShowSeqlist(p);//1 2 3 4
DeletePostSeqlist(p, 1);
ShowSeqlist(p);//1 3 4
ChangePostSeqList(p, 1, 100);
ShowSeqlist(p);//1 100 4
int t;//承接查找数据的下标
t=SearchDataSeqList(p, 100);
printf("%d\n", t);//1
seqlist_t* pb = CreateEpSeqlist();
InsertIntoSeqlist(pb, 0, 1);
InsertIntoSeqlist(pb, 1, 100);
InsertIntoSeqlist(pb, 2, 200);
InsertIntoSeqlist(pb, 3, 300);
InsertIntoSeqlist(pb, 4, 400);
ShowSeqlist(pb);
CombineAB(p,pb);
ShowSeqlist(p);
return 0;
}
//1.创建一个空的顺序表
seqlist_t* CreateEpSeqlist()//返回的是申请空间的首地址
{
//动态申请一块空间
seqlist_t* p = (seqlist_t*)malloc(sizeof(seqlist_t));
//sizeof(seqlist_t)计算结构体的大小
if (p == NULL) {
printf("申请空顺序表错误\n");
return NULL;
}
//last是最后一个有效元素的下标
p->last = -1;//空
return p;
}
//4.判断顺序表是否为满,满返回1 未满返回0
int IsFullSeqlist(seqlist_t* p)
{
return p->last + 1 == N;//成立返回1(满),不成立返回0
}
//2.向顺序表的指定位置插入数据
int InsertIntoSeqlist(seqlist_t* p, int post, int data)//post第几个位置,data插入的数据
{
//1、容错判断
//小于最小,大于最大;顺序表满了帮你插入
if (post<0 || post>p->last+1|| IsFullSeqlist(p)) {
printf("插入失败\n");
return -1;//错误返回
}
//2、last-post往后移动一个位置
int i;
for (i = p->last; i >= post; i--) {
p->data[i + 1] = p->data[i];
}
//3、插入数据
p->data[post] = data;
//4、p->last+1
p->last++;
return 0;
}
//3.遍历顺序表sequence 顺序 list 表
void ShowSeqlist(seqlist_t* p)
{
int i;
for (i = 0; i <= p->last; i++) {
printf("%d ", p->data[i]);
}
printf("\n");
}
//5.判断顺序表是否为空
int IsEpSeqlist(seqlist_t* p)
{
return p->last == -1;
}
//6.删除顺序表中指定位置的数据post删除位置
int DeletePostSeqlist(seqlist_t* p, int post)
{
//1、容错判断
if (post > p->last || post < 0 || IsEpSeqlist(p)) {
printf("删除失败\n");
return -1;
}
//2、post+1-last向前移动一个位置
int i;
for (i = post + 1; i <= p->last; i++) {
p->data[i - 1] = p->data[i];
}
//3、有效元素-1
p->last--;
return 0;
}
//7.清空顺序表(清空:访问不到,但内存当中还有;销毁:内存清空)
void ClearSeqList(seqlist_t* p)
{
p->last = -1;
}
//8.修改指定位置的数据
int ChangePostSeqList(seqlist_t* p, int post, int data)//post被修改的位置,data修改成的数据
{
//1、容错判断
if (post<0 || post>p->last) {
printf("修改失败\n");
return -1;
}
//2、修改指定位置数据
p->data[post] = data;
}
//9.查找指定数据出现的位置
int SearchDataSeqList(seqlist_t* p, int data)//data代表被查找的数据
{
int i;
for (i = 0; i <= p->last; i++) {
if (p->data[i] == data) {
return i;
}
}
return -1;
}
//10.合并表
void CombineAB(seqlist_t *p,seqlist_t *pb)
{
int i;
for(i=0;i<=pb->last;i++){
if(SearchDataSeqList(p,pb->data[i])==-1){//没有找到
InsertIntoSeqlist(p,p->last+1,pb->data[i]);
}
}
}
2.单链表代码实现: