一、线性表的定义和基本操作
1.线性表的定义
2.线性表的基本操作
“带回来”解释:
在main函数中传入x=1,但是在test函数中又改成了1024,实际上在内存中这个等于1024的是另一个x,然后在main函数中再次输出的时候输出的还是1,因为根本就没有改变x=1这个内存中的x的值
二、顺序表的定义
1.顺序表的定义
2.顺序表的实现
(1)、静态分配
在执行SqList L的时候就会给顺序表分配他所需要的空间
如果不设置默认值的话后两个数就会出现很奇怪的值
产生奇怪值的原因是在这个存储空间分配给这个顺序表之前存储了其他数据,所以会有脏数据,但是为什么说考研省略设置默认值的步骤,这是因为我们这里用的fo循环打印全部的内存本来就是违规的,而应该按照顺序表的长度打印。 在声明顺序表时,刚开始把他的length值设为0是必须做的。
(2)、动态分配
*data指针指向了顺序表中第一个数据元素的位置
malloc函数申请一整片连续的存储空间,free函数用来释放空间。 malloc函数会返回指向这一整片存储空间开始地址的一个指针。
分析动态实现的背后过程: 声明顺序表的数据元素类型是int类型,data指向数据表中的第一个元素。 然后实现一个InitList函数用于初始化一个动态分配方式实现的顺序表 然后实现一个函数拥有动态的增加顺序表的长度。
最后在main函数里调用相关的操作。 执行完这句后计算机会在内存中开辟这样一小块空间。
执行完第二句代码之后data应该指向了malloc函数申请的空间的第一个位置
之后这里写的main函数省略了将数据填入顺序表的过程 然后执行增加动态数组长度。 然后开辟了新的空间,现在可以多存五个数据
因为malloc开辟了新的空间,之前存的数据都不在新的空间,所以需要一个for循环把数据存入新的空间。
由于增加了五个空间,所以要把最大空间增大5,最后调用free函数把之前创建的已经被新空间代替的p空间释放掉。
代码演示:
#include<stdio.h>
#include<stdlib.h>
#define InitSize 3
typedef int ElemType;
typedef struct {
ElemType* data;
int MaxSize;
int length;
}SeqList;
void InitList(SeqList& L) {
L.data = (int*)malloc(InitSize * sizeof(int));
L.length = 0;
L.MaxSize = InitSize;
}
void IncreaseSize(SeqList& L, int len) {
int* p = L.data;
L.data = (int*)malloc((L.MaxSize + len) * sizeof(int));
for (int i = 0; i < L.length; i++)
{
L.data[i] = p[i];
}
L.MaxSize = L.MaxSize + len;
free(p);
}
int main() {
SeqList L;
InitList(L);
L.data[0] = 1;
L.data[1] = 2;
L.data[2] = 3;
L.length = 3;
IncreaseSize(L, 5);
for (int i = 0; i < L.length; i++)
{
printf("%d\n",L.data[i]);
}
return 0;
}
3.顺序表的插入删除
(1)、插入
要把C插入,就要把后边的全都往后移一格。
当在位置9插入3时,运行代码之后3会插到data[8],但是位置7和8都是空的, 所以这个代码不够健壮
所以插入的比较好的代码应该写成: 代码演示:
#include<stdio.h>
#define MaxSize 3
typedef struct {
int data[MaxSize];
int length;
}SqList;
bool ListInsert(SqList& L, int i, int e) {
if (i<1 || i>L.length+1) {
printf("因为i范围无效插入失败!\n");
return false;
}
if (L.length >= MaxSize)
{
printf("因为存储空间已满插入失败!\n");
return false;
}
for (int j = L.length; j >= i; j--)
{
L.data[j] = L.data[j - 1];
}
L.data[i - 1] = e;
L.length++;
return true;
}
void main() {
SqList L;
L.data[0] = 0;
L.data[1] = 1;
L.data[2] = 2;
L.length = 3;
ListInsert(L,3,8);
printf("当前顺序表的内容为:\n");
for (int i = 0; i < L.length; i++)
{
printf("L.data[%d]=%d\n",i,L.data[i]);
}
}
插入操作的时间复杂度:
(2)、删除
删除之后需要把后边的全部往前移一位,同时要把length的值减一
代码实现:
&L:是删除哪个顺序表 i:要删除第几个数据元素 &e:用这个元素把此次删除的数据元素返回 代码演示:
#include<stdio.h>
#define MaxSize 10
typedef struct {
int data[MaxSize];
int length;
}SqList;
void InitList(SqList &L) {
L.length = 0;
}
bool ListDelete(SqList& L, int i, int& e) {
if (i<1||i>L.length)
{
return false;
}
e = L.data[i - 1];
for (int j = i; j < L.length; j++)
{
L.data[j - 1] = L.data[j];
}
L.length--;
return true;
}
int main() {
SqList L;
InitList(L);
L.data[0] = 1;
L.data[1] = 2;
L.data[2] = 3;
L.data[3] = 4;
L.length = 4;
int e = -1;
if (ListDelete(L, 3, e)) {
printf("已删除第3个元素,删除元素的值为=%d\n",e);
}
else
{
printf("位序i不合法,删除失败\n");
}
for (int i = 0; i < L.length; i++)
{
printf("L[%d]=%d\n",i,L.data[i]);
}
}
删除操作的时间复杂度:
4.顺序表的查找
1.按位查找
(1)静态分配
(2)动态分配
按位查找的时间复杂度:
2.按值查找
结构类型的数据元素不能这样
按值查找的时间复杂度:
|