定义:
- 线性表是一种逻辑结构,
- 具有相同类型的n个元素的有限序列。可以有零个元素(序列即有序号的排列元素)
- 逻辑关系:
- 在线性表中除了表头元素,每一个元素都具有前缀元素
- 除了表尾元素,都有后缀
- 元素具有逻辑上的顺序性,在序列中每个元素排序都有先后次序
- 在逻辑上相邻的元素,在物理上也要保存相邻
特点:
- 个数有限
- 元素具有逻辑上的顺序性,在序列中每个元素排序都有先后次序
- 都是数据元素,且都是单个元素
- 数据类型都相同,意味着占有大小相同的存储控件
- 具有抽象性,即讨论元素间一对一的逻辑关系,而不是元素内容
- 逻辑结构,表示元素之间一对一相邻的关系
九种基本操作(函数的功能):
- InitList(&L):初始化表,构造一个空的线性表
- DestroyList(&L):销毁操作,销毁线性表,并释放线性表L所占用的内存控件
- 查找:
- LocateElem(L,e):按值查找操作,只返回第一个相同值
- GetElem(L,i):按位查找操作
- ListInsert(&L,i,e):插入操作,在表L中第i个位置插入元素e,即在i-1和i之间插入元素e
- ListDelete(&L,i,&e):删除操作,在表L中第i个位置的元素,并用e返回删除元素的值
- PrintList(L):输出操作
- Empty(L):判空操作,若为空表,则返回true;
- Length():求表长,返回L的长度。即数据元素的个数
线性表的顺序存储:
线性表的顺序存储又称顺序表-—理解:食堂排队打饭,逻辑和物理均相邻,所以两者的顺序相同
实现:
- 数组,
- 数组中下标从零开始,而顺序表从1开始
- 数组容量固定,顺序表可变化
- 数组可以是多维的,而顺序表只能是一维的。
- 顺序表可以实现随机存储,因为根据第一个元素地址可以推算出其他元素的地址
- 计算元素存放的内存大小 :sizeof(ElemType)
- 顺序表 数组下标 内存地址
- a1 0 LOC(A)
- a2 1 LOC(A)+sizeof(ElemType)
- a3 2 LOC(A)+2*sizeof(ElemType)
- … … …
- n n-1 LOC(A)+(n-1)*sizeof(ElemType)
顺序表的定义
指针:存放一个地址单元的地址
数组静态分配
#define MaxSize 50; //定义宏 typedef struct{ //结构体:将不同数据类型的组合到一起 ElemType data[MaxSize]; int length; //数据表的长度 }SqList; //结构体的名字;
数组动态分配
#define MaxSize 50; //定义宏 typedef struct{ //结构体:将不同数据类型的组合到一起 ElemType *data; //根据首地址,仅仅只是地址,无内存空间,需要申请 int length; //数据表的长度 }SqList; //结构体的名字;
动态分配指针申请控件
C L.data=(Elemtype*)malloc(sizeof(ElemType)*InitSize); C++ L.data=new ElemType[InitSize]; sizeof(Elemtype)计算每个数据类型的大小 * 数据个数
顺序表的基本操作
注: &L 的使用情况,所有需要进行修改的情况都会使用&L ,其他查看之类的不需要引用&
插入操作
&L 在函数体内部操作是作用于一个局部变量上面,
bool ListInsert(SqList &L,int i,ElemType e){ if(i<1||i>L.length+1) //判断插入表的位置 return false; if(L.length>MaxSize) //检测数组是否已满 return false; for(int j=L.length;j>=i;j--) // L.data[j]=L.data[j-1]; //将插入位置i之后的元素都往后移动一位 L.data[i-1]=e; L.length++; //顺序表长度加一 return true; }
平均时间复杂度:一共有n+1个合法位置(n为数组长度,1为新插入)
所以每个位置插入的概率为1/(n+1),再乘以循环的次数(n-i+1 :从尾部一直到 i)=n/2,
所以 O(n)
最好和最坏时间复杂度:最好,在表最后一位插入,O(1); 最坏,在表头插入,O(n)
删除操作
&e 将删除的值返回给函数
bool ListInsert(SqList &L,int i,ElemType &e){ if(i<1||i>L.length+1) //判断删除表的位置 return false; e=L.data[i-1]; //数组下标从0开始 for(int j=i;j<L.length;j++) // L.data[j-1]=L.data[j]; //将插入位置i之后的元素都往前移动一位 L.length--; //顺序表长度减1 return true; }
平均时间复杂度:一共有n个位置
所以每个位置插入的概率为1/n,再乘以循环次数(n-i)=(n-1)/2,
所以O(n)
最好和最坏时间复杂度:最好,在表最后一位删除,O(1);最坏,表头删除,O(n)
按值查找,需要遍历
int LocateElem(SqList L, ElemType e){ int i; for(i=0;i<L.length;i++){ //从第一位数组元素开始 if(L.data[i]==e) return i+1; //返回循序表的下标 } return 0; //表示查找失败 }
平均时间复杂度:n个数据元素,概率为1/n,从头移动到 i ,乘以循环次数 i =(n+1)/2
所以O(n)
最好和最坏时间复杂度:最好,在数组头找到,O(1);最坏,数组尾找到,O(n)
线性表的链式存储
- 线性表的链式存储又称单链表
- 元素存储单元不一定连续,通过指针来实现线性逻辑关系,