作者:mobiledu2502907897 | 来源:互联网 | 2023-06-04 12:00
第二章 线性表
1. 线性表的定义和基本操作
1.1 定义
具有相同类型数据类型的n(n>=0)个数据元素的有限序列,其中n为表长,当n = 0时线性表是一个空表。若用L命名线性表,表示为:L = (a1,a2…,an)
C语言中如何确定一个数据元素的大小
sizeof(ElemType)
1.2 线性表的特点
- 表中个数有限
- 表中元素具有逻辑上的顺序性,表中元素有其先后次序
- 表中元素都是数据元素,每个元素都是单个元素
- 表中元素的数据类型都相同,每个元素占有相同大小的存储空间
- 表中元素具有抽象性,只考虑元素间逻辑关系,不考虑元素表示什么内容
1.3 若需要直接改变x的值要用到&
#include
void test(int x){x = 1024;printf("test函数内部x = %d\n",x);
}int main(){int x = 1;printf("调用test前x = %d\n",x); test(x); printf("调用test后x = %d\n",x);
}
造成未赋值却有值是因为,在调用test时,在内存中复制了一个x使得test函数中的x值给到复制的x的位置,x的数值未发生改变
#include
//使用&直接对内存中的x的值进行改变,C++支持,C语言不支持
void test(int & x){x = 1024;printf("test函数内部x = %d\n",x);
}int main(){int x = 1;printf("调用test前x = %d\n",x); //调用test前x = 1test(x); //test函数内部x = 1024printf("调用test后x = %d\n",x); //调用test后x = 1024
}
1.4 线性表的基本操作
InitList(&L):初始化表(构造一个空的线性表)
Length(L):求表长(返回线性表L的长度)
LocateElem(L,e):按值查找操作(在表L中查找特定关键字值的元素)
GetElem(L,i):按位查找操作(获取表中第i个位置的元素的值)
ListInsert(&L,i,e):插入操作(在表L中的第i个位置上插入指定元素e)
ListDelete(&L,i,&e):删除操作(删除表L中第i个位置的元素,并用e返回删除元素的值)
PrintList(L):输出操作(按照先后顺序输出线性表L的所有元素值)
Empty(L):判空操作
DestroyList(&L):销毁操作(销毁线性表,并释放线性表L所占用的内存空间)
2. 顺序表的实现
2.1 静态分配
#include //定义线性表的最大长度
#define MaxSize 10typedef struct {//用静态数组存放数据元素int data[MaxSize];//顺序表的长度int length;
}SqList;//基本操作——初始化一个顺序表
void InitList(SqList &L){for (int i &#61; 0;i}int main() {//声明一个顺序表SqList L;//初始化顺序表InitList(L);//打印顺序表&#xff0c;这里最好使用顺序表的基本操作来访问各个数据GetElem(L,i)for(int i&#61;0;i<10;i&#43;&#43;){printf("data[%d]&#61;%d\n",i,L.data[i]);}
}
由于内存中会有遗留数据&#xff0c;所以使得顺序表中会出现非0数据
2.2 动态分配
#include
#include
#define InitSize 10typedef struct {int *data;int MaxSize;int length;
}SqList;void InitList(SqList &L){L.data &#61; (int *)malloc(InitSize*sizeof(int));L.length &#61; 0;L.MaxSize &#61; InitSize;
}
void IncreaseSize(SqList L,int len){int *p &#61; L.data;L.data &#61; (int *)malloc((L.MaxSize&#43;len)*sizeof(int));for (int i &#61; 0; i < L.length; &#43;&#43;i) {L.data[i] &#61; p[i];}L.MaxSize &#61; L.MaxSize&#43;len;free(p);
}int main(){SqList L;InitList(L);IncreaseSize(L,5);return 0;
}
- 动态申请内存空间&#xff08;malloc函数&#xff09;
malloc函数返回一个指针&#xff0c;需要强制转换数据类型
malloc函数会在内存中创建一整片连续的空间
//malloc函数的参数需要指明分配多大的内存空间
L.data &#61; (ElemType *)malloc(siazeof(ElemType)*InitSize);
- 释放内存空间&#xff08;free函数&#xff09;
free();
2.3 顺序表的特点
- 随机访问&#xff0c;可以在O(1)时间内找到第i个元素
- 存储密度高&#xff0c;每个节点只存储数据元素
- 拓展容量不方便&#xff08;即便采用动态分配的方式实现&#xff0c;拓展长度的时间复杂度也比较高&#xff09;
- 插入删除不方便&#xff0c;需要移动大量元素
2.4 顺序表的基本操作
2.4.1 插入
- ListInsert(&L,i,e)&#xff1a;插入操作&#xff0c;在表L中的第i个位置上插入指定元素e
#define MaxSize 10
typedef struct{ElemType data[10];int length;
}SqList;bool ListInsert(SqList &L,int i,ElemType e){if (i<1||i>L.length&#43;1){return false;}if (L.length>&#61;MaxSize){return false;}for (int j &#61; L.length; j >&#61;i ; j--) {L.data[j] &#61; L.data[j-1];}L.data[i-1] &#61; e;L.length&#43;&#43;;return true;
}int main(){SqList L;InitList(L);ListInsert(&L,3,3);
}
2.4.2 删除
-
ListDelete(&L,i&e)&#xff1a;删除操作&#xff0c;删除表中第i个位置的元素&#xff0c;并用e返回删除元素的值
#include
#include
#include #define MaxSize 20typedef struct{int *data;int length;
}SqList;void InitList(){L.data &#61; (int *)malloc(MaxSize*sizeof(int));L.length &#61; 0;
};//e为此次删除的数据元素返回
bool ListDelete(SqList &L,int i,ElemType &e){if (i<1||i>L.length){return false;}e &#61; L.data[i-1];for (int j&#61;i;j}int main(){SqList L;InitList(L);if (ListDelete(L,3,e)){printf("已经删除第三个元素&#xff0c;删除元素值为&#61;%d\n",e);} else{printf("位序i不合法&#xff0c;删除失败\n");}
}
2.4.3 查找
2.4.3.1 按位查找
GetElem(L,i)&#xff1a;获取表中第i个位置的元素的值
#include
#include #define MaxSize 10
typedef struct{ElemType data[MaxSize];int length;
}SqList;
ElemType GetElem(SqList L,int i){return L.data[i-1];
}
#define InitSize 10
typedef struct{ElemType *data;int MaxSize;int length;
}SeqList;
int LocateElem(SeqList L,ElemType e){for (int i &#61; 0; i < L.length; i&#43;&#43;) {if (L.data[i]&#61;&#61;e){return i&#43;1;}}return 0;
}
顺序表按值查找平均时间复杂度&#xff1a;O(n)
最好情况&#xff1a;目标元素在表头 时间复杂度为O(1)
最坏情况&#xff1a;目标元素在表尾 时间复杂度为O(n)