线性表(二)
目录
1.删除操作
所以删除算法的思路:
1)如果删除位置不合理,抛出异常;
2)取出删除元素;
3)从删除元素位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置;
4)表长-1。
实现代码: ListDelete.c
现在我们分析一下,插入和删除的时间复杂度。
最好的情况:插入和删除操作刚好要求在最后一个位置操作,因为不需要移动任何元素,所以此时的时间复杂度为0(1)。
最坏的情况:如果要插入和删除的位置是第一个元素那就意味着要移动所有的元素向后或者向前,所以这个时间复杂度为0(n)。
至于平均情况,就取中间值0((n-1)/2),平均情况复杂度简化后还是0(n)。
2.数据长度和线性表长度区别
数组的长度是存放线性表的存储空间的长度,存储分配后这个量一般是不变的。
线性表的长度是线性表中数据元素的个数,随着线性表插入和删除的进行,这个量是变化的。
3.线性表顺序存储结构的优缺点
线性表的顺序存储结构,在存、读数据时,不管是哪个位置,时间复杂度都是0(1)。而在插入或删除时,时间复杂度都是0(n)。
这就说明,它比较适合元素个数比较稳定,不经常插入和删除元素,而更多的操作是存取数据的应用。
那我们接下来给大家简单总结下线性表的顺序存储结构的优缺点:
优点:
1)无须为表示表中元素之间的逻辑关系而增加额外的存储空间。
2)可以快速地存取表中任意位置的元素。
缺点:
1)插入和删除操作需要移动大量元素。
2)当线性表长度变化较大时, 难以确定存储空间的容量。
3)容易造成存储空间的“碎片”。
4.线性表的链式存储结构
1)前面我们讲的线性表的顺序存储结构,它最大的缺点就是插入和删除时需要移动大量元素,这显然就需要耗费时间。
2)为什么当插入和删除时,就要移动大量的元素?
原因就在于相邻两元素的存储位置也具有邻居关系,它们在内存中的位置是紧挨着的,中间没有 间隙,当然就无法快速插入和删除。
3)线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以存在内存中未被占用的任意位置。
4)比起顺序存储结构每个数据元素只需要存储一个位置就可以了。现在链式存储结构中,除了要存储数据元素信息外,还要存储它的后继元素的存储地址(指针)。
也就是说除了存储其本身的信息外,还需存储一个指示其直接后继的存储位置的信息。
5)我们把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称为指针或链。这两部分信息组成数据元素称为存储映像,称为结点(Node )。
n个结点链接成一个链表,即为线性表(a1, a2,a3, ...an)的链式存储结构。
因为此链表的每个结点中只包含一个指针域,所以叫做单链表。
5.单链表
对于线性表来说,总得有个头有个尾,链表也不例外。我们把链表中的第一个结点的存储位置叫做头指针,最后一个结点指针为空(NULL)。
有时为了更加方便对链表进行操作,会在单链表的第一个结点前附设一个结点,叫做头结点。头结点的数据域可以不存储任何信息,也可以存储如线性表的长度等附加信息,头结点的指针域存储指向第一个结点的指针。
6.顺序表的基本操作
1)按位查找
GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值。
#define InitSize 10//顺序表的初始长度
typedef struct{
ElemType *data;//指示动态分配数组的指针 动态分配
int MaxSize;//顺序表的最大容量
int length;//顺序表的当前长度
} SeqList;//顺序表的类型定义(动态分配方式)
ElemType GetElem(SeqList L,int i){
return L.data[i-1];
}
时间复杂度为0(1),由于顺序表的各个数据元素在内存中连续存放,因此可以根据起始地址和数据元素大小立即找到第i个元素--“随机存取”特性。
2)按值查找
LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。
#define InitSize 10//顺序表的初始长度
typedef struct{
ElemType *data;//指示动态分配数组的指针
int MaxSize;//顺序表的最大容量
int length;//顺序表的当前长度
} SeqList;//顺序表的类型定义(动态分配方式)
//在顺序表L中查找第-一个元素值等于e的元素,并返回其位序
int LocateElem(SeqList L,ElemType e){
for(int i=Q; i<L. length;i++)
if(L. data[i]==e)
return i+1;//数组下标为主的元素值等于e,返回其位序i+1
return0;//退出循环,说明查找失败
}
最好情况:目标元素在表头,循环1次; 最好时间复杂度= 0(1)
最坏情况:目标元素在表尾,循环n次;最坏时间复杂度= O(n)
平均情况:假设目标元素出现在任何一个位置的概率相同,都是1/n
目标元素在第1位,循环1次:在第2位,循环2次; ..... 在第n位,循环n次
得出平均时间复杂度= 0(n)
基本数据类型: int、 char、 double、float等可以直接用运算符“==”比较
那结构类型的数据元素也这样吗?
3)结构类型的比较
C语言中,结构体的比较不能直接用“==”
需要依次对比各个分量来判断两个结构体是否相等
typedef struct {
int num;
int people;
} Customer;
void test() {
Customer a;
a.num = 1;
a.people = 1;
Customer b;
b.num = 1;
b.people = 1;
if (a == b) { //Invalidoperandsko binary expression (Customer' and 'Customer')
printf("相等");
}else {
printf("不相等");
bool isCustomerEqual (Customer a, Customer b){
if (a.num == b.num && a.people == b.people)
return true;
else
return false;
}
if (a.num == b.num && a.people == b.people)
{
printf("相等");
}
else
{
printf("不相等");
}