什么是数据结构?
简单来说数据结构就是计算机储存,组织数据的方式,而数组就是最基础的数据结构。
那为什么会有数据结构的存在呢?
这需要将数据结构分成数据和结构两部分进行分析。
数据:我们在计算机屏幕上所看见的文字信息和数值,这些都是数据。
结构:当我们想要使⽤⼤量使⽤同⼀类型的数据时,通过⼿动定义⼤量的独⽴的变量对于程序来说,可读性 ⾮常差,我们可以借助数组这样的数据结构将⼤量的数据组织在⼀起,结构也可以理解为组织数据的 ⽅式。
如果数据在内存中以杂乱无章形式储存在,如图1,当我们需要得到一个数据时,会显得无从下手,计算机也会没有任何规律地寻找,这会大大降低工作效率。而数据以图2的形式储存时,计算机就可以快速地找到我们需要的数据。
图1:
图2:
总结:
1)能够存储数据(如顺序表、链表等结构);
2)存储的数据能够⽅便查找。
顺序表是什么?
顺序表的底层结构是数组,对数组的封装,实现了常⽤的增删改查等接⼝,我们可以将它看作一个工具来理解。
顺序表也是线性表的一种,而线性表就是具有相同特性的数据结构的集合。
线性表的物理结构不一定连续,而逻辑结构一定连续;
顺序表的物理结构和逻辑结构都是连续的。
顺序表又分为静态顺序表和动态顺序表。
静态顺序表:使用定长的数组储存元素。
静态顺序表有一个很致命的缺点,空间给多了会很浪费,给少了又会不够用,导致信息丢失,这在实际工作中会给公司带来巨大的损失。
动态顺序表也就是对静态顺序表的改良,拥有着动态增容的能力(成倍数增加,一般以二倍形式增加),完美地弥补了静态顺序表的缺陷。
顺序表的代码实现:
顺序表代码实现的头文件:
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>typedef int seq;//将类型名重命名,以便在使用的时候随时改变数据类型typedef struct sequce//创建顺序表结构体,并将其重命名
{seq* arr;//因为要实现动态顺序表,所以要用seq*的类型来创建数组int size;//数组中的有效数据个数int cap;//数组拥有的空间
}sl;void Sequce_set(sl* s);//初始化顺序表
void Sequce_front(sl* s, seq x);//前插
void Print(sl s);//打印顺序表
void En(sl* s);//动态内存实现
void Sequce_back(sl* s, seq x);//尾插
void Sequce_popback(sl* s);//尾删
void Sequce_popfront(sl* s);//首删
void N_ull(sl* s);//判断空指针
void Zd_set(sl* s, int n, seq x);//指定位置插入
void Zd_del(sl* s, int n);//指定位置删除
void des(sl* s);//内存销毁
实现功能的函数代码:
#define _CRT_SECURE_NO_WARNINGS 1#include "seq.h"//初始化顺序表
void Sequce_set(sl* s)
{s->arr = (seq*)malloc(sizeof(seq) * 4);s->size = 0;s->cap = 1;
}//表首插入
void Sequce_front(sl* s, seq x)
{N_ull(s);En(s);for (int i = s->size; i > 0; i--){s->arr[i] = s->arr[i - 1];}s->arr[0] = x;s->size++;
}//表尾插入
void Sequce_back(sl* s, seq x)
{N_ull(s);En(s);s->arr[s->size] = x;s->size++;
}//表首删除
void Sequce_popfront(sl* s)
{N_ull(s);if (s->size == 0){return;}for (int i = 1; i < s->size; i++){s->arr[i - 1] = s->arr[i];}s->size--;
}//表尾删除
void Sequce_popback(sl* s)
{N_ull(s);if (s->size == 0){return;}s->size--;
}//指定位置添加
void Zd_set(sl* s, int n, seq x)
{N_ull(s);En(s);if (s->size < n){return;}for (int i = s->size; i > n; i--){s->arr[i] = s->arr[i - 1];}s->arr[n] = x;s->size++;
}//指定位置删除
void Zd_del(sl* s, int n)
{if (s->size == 0){return;}N_ull(s);for (int i = n; i < s->size - 1; i++){s->arr[i] = s->arr[i + 1];}s->size--;
}//打印顺序表
void Print(sl s)
{for (int i = 0; i < s.size; i++){printf("%d ", s.arr[i]);}printf("\n");
}//判断容量
void En(sl* s)
{N_ull(s);while (s->cap <= s->size){int newcap = 2 * s->cap;seq* ps = (seq*)realloc(s->arr, sizeof(seq) * newcap);if (!ps){exit(1);}s->arr = ps;s->cap = newcap;}
}//判断空指针
void N_ull(sl* s)
{if (!s){exit(1);}
}//顺序表销毁
void des(sl* s)
{free(s->arr);s->arr = NULL;
}
用来测试功能的实现的代码:(用来测试功能函数是否正常运行)
#define _CRT_SECURE_NO_WARNINGS 1#include"seq.h"int main()
{sl s;Sequce_set(&s);//初始化顺序表Sequce_front(&s, 1);//表前插入Print(s);Sequce_front(&s, 2);//表前插入Print(s);Sequce_front(&s, 3);//表前插入Print(s);Sequce_back(&s, 1);//表尾插入Print(s);Sequce_back(&s, 2);Print(s);Sequce_back(&s, 3);Print(s);Sequce_popfront(&s);//表首删除Print(s);Sequce_popfront(&s);Print(s);Sequce_popfront(&s);Print(s);Sequce_popback(&s);//表尾删除Print(s);Sequce_popback(&s);Print(s);Sequce_popback(&s);Print(s);Zd_set(&s, 2, 99);Print(s);des(&s);return 0;
}