本期我们开始学习四大数据结构中的线性结构,还记得四大结构包括什么嘛?包括集合结构、线性结构、树形结构、图状结构,线性表有包括顺序表和链表(单向链表、循环链表和双向链表)。
线性表是最基本、最简单、也是最常用的—种数据结构。 —个线性表是 n 个具有相同特性的数据元素的有限序列 。前驱元素: 若 A 元素在 B 元素的前面,则称 A 为 B 的前驱元素。后继元素: 若 B 元素在 A 元素的后面,则称 B 为 A 的后继元素。
我们上学的时候每天去食堂买饭,然后按照先来后到的顺序,一个挨着一个这样的的顺序,我们可以把它看作为一个线性表。
线性表( Linear List ) :是由 n(n ≥ 0) 个类型相同的数据元素 1 , 2 , … , … , 组成的有限序列,记作( 1 , 2 , … , … , ),其中数据元素 可以是整型、实型、字符、布尔或复合类型等任何一种数据类型。
重点:
1.n 是线性表数据元素的个数即线性表的长度,当 n=0 时称为空表。
2.当 n>0 时, (1<<)有且仅有一个直接前驱a−1 和一个直接后继a+1 。
3.a1没有前驱元素,没有后继元素。
1.数据元素之前有“一对一”的逻辑关系。
2.第一个元素没有前驱节点,这个元素被称为头结点。
3.最后一个元素没有后继结点,这个元素被称为尾节点。
4.除了头结点和尾节点之外,其他节点有且只有一个前驱节点和一个后继结点。
按照存储结构可以分为:顺序表和链表(单链表、循环链表、双向链表)。
使用一组地址连续的存储单元依次存储线性表的各个数据元素,该结构称作 线性表的顺序存储结构 ,简称为 顺序表( Sequential List) 。我们使用的数组就是顺序结构的。
使用静态方式分配内存空间
//线性表存储空间分配
//使用静态分配空间
#define Max_Size 100
typedef struct{
int elem[Max_Size];
// 当前长度
int length;
}SqList;
使用动态的方式分配内存空间,直接定义指针,数组的大小用相应的函数来动态分配内存。
//线性表存储空间分配
//使用静态分配空间
#define Max_Size 100
typedef struct{
int elem[Max_Size];
// 当前长度
int length;
}SqList;
需要使用malloc函数来进行动态分配内存
SqList L;
L.elem=(Eletype*)malloc(sizeof(Eletype*)Maxsize);
malloc(m)函数:开辟m字节长度的地址空间,返回这段空间的首地址。
sizeof(x)运算:计算变量x的长度,sizeof尤其在应试考试的选择题中比较易错,初学者一般认为他是一个函数。
线性表的存储结构如下图所示:
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define SQLMAXSIZE 100
int InitSL(Sqlist *L) {
//使用malloc函数进行初始化
L->elem = (int *)malloc(sizeof(int) * SQLMAXSIZE);
//存储空间分配失败
if (!L->elem)
return OVERFLOW;
//初始化长度
L->length = 0;
return OK;
}
int GetElem(Sqlist *L, int position, int *e) {
//判断position是否合理
if (position < 1 || position > L->length)
return ERROR;
*e =L->elem[position - 1];
return OK;
}
int LocateElem(Sqlist *L, int e) {
for (int i = 0; i < L->length; i++) {
if(e == L->elem[i])
return i + 1;
}
return 0; // 0代表查找元素不在循序表中
思路分析:
1. 在线性表L中查找与指定值e相同的数据元素的位置 从表的一端开始,逐个进行记录的关键字和给定值的比较。
找到,返回该元素的位置序号,未找到,返回0。
int Listinsert(Sqlist &L,int i,int e){
// i取值不合法
if(i<0||i>L.length+1) return ERROR;
//当前存储空间已满
if(L.length==SQLMAXSIZE) return ERROR;
for(int j=L.length-1;j>0;j--){
//插入位置元素及之后的元素后移
L.elem[j+1]=L.elem[j];
}
//将新的元素e放入第i个位置
L.elem[i-1]=e;
L.length++;
return OK;
}
思路分析:
1. 判断插入位置i是否合法。
2.判断插入顺序表的存储空间是否已经满了,如果满了返回ERROR。
3.将第n至i位的元素依次向后移动一个位置,空出第i个位置。
4.要将插入的元素e放入到第i个位置。
5.表长增+1。
int ListDelete(Sqlist &L,int i){
// i取值不合法
if(i<0||i>L.length+1) return ERROR;
// 被删除元素之后的元素往前移动
for(int j=i;j<=L.length-1;j++){
L.elem[j-1]=L.elem[j];
}
// 表长-1
L.length--;
return OK;
}
思路分析:
1.判断删除的位置i是否合法。
2.将i+1至n位的元素依次向前移动一个位置,后一个元素覆盖前一个元素。
3.标的长度-1。
本节课主要介绍了线性表的基本概念、特性以及两种常见的线性表:顺序表和链表和顺序表代码的部分,希望读者能够通过本期的学习充分理解线性表和能够独立的写出c语言的相关代码。