线性表的顺序结构—顺序表

###青岛大学王卓的数据结构与算法学习

###以及CSDN的优质文章

为了帮助个位能够更好的理解一些操作的原因,我在这里就引入我学习时看过的相关文章,希望对你有所帮助:

1.C语言*p、p以及&p的区别,*p和**p的区别​​​​​  

2.引用与解引用​​​​​​​

一.线性表

线性表(linear_list)是最常用且最简单的一种数据结构。一个线性表是n个数据元素的有限序列。

特点:

  1. 存在惟一的一个被称作“第一个”的数据元素
  2. 存在惟一的一个被称做“最后一个”的数据元素
  3. 除第一个之外,集合中的每个数据元素均只有一个前驱
  4. 除最后一个之外,集合中每个数据元素均只有一个后继

优点:

  1. 任意元素均可以随机存取(常数时的时间复杂度)

缺点:

  1. 在插入,删除某一点元素时,需要移动大量元素
  2. 浪费存储空间
  3. 属于静态存储形式,数据元素的个数不能自由扩充

那么,我们在了解完这些之后,便开始代码实现。

头部定义

//头文件
#include 
#include 

//宏定义
#define MAXSIZE 100
#define OK 1 //成功的标志
#define ERROR //失败的标志

//取一些别名
typedef int Elemtype; // 这里按照你以后想要传入的数据类型为主 这里我用int
typeddef int status; //函数的类型,以及返回值的类型 状态

#inlucde 这里引用该头文件是为了下面的内存动态分配而引用内置函数所准备的。

顺序表的定义

typedef struct
{
    ElemType* elem; // 基地址 指针是特殊的数组
    int length; //数组长度
}Sqlist;

顺序表的初始化

status Initlist(Sqlist *L) {
    //基地址的首地址赋值给L->elem
    L->elem = (ElemType*)malloc(MAXSIZE*sizeof(ElemType));
    //这是获取一个动态存储空间
    if (!L->elem) {
        return ERROR;
    }
    //存储分配失败
    L->length = 0; //初始长度为0
    return 0;
}

二.顺序表的具体操作

一.判断顺序表是否为空表

status IsEmpty(Sqlist *L) {
    if (L->length == 0) {
        return OK; // 返回1 正确
    }
    else {
        return ERROR; // 返回0 错误
    }

二.清空线性表

void ClearList(Sqlist *L) {
    L->length = 0; //将顺序表的长度为0,就是清空顺序表
}

三.销毁线性表

void DestoryList(Sqlist *L) {
    if (L->elem_ {
        free(L); //释放内存
    }
}

如果你用的是C++ 还有一个函数就是 delete()函数

使用delete Sqlist *L --->销毁顺序表,释放内存

四.插入一个元素位置

status InsertList(Sqlist *L,int i, ElemType e) {
    if (i < 1 || i > L->length + 1) {
        return ERROR;
    }
    if (L->length == MAXSIZE) {
        return ERROR;
    }
    //以上是判断是否越界或是线性表是否满了
    for (int j = L->length-1; j >= i-1;j--) {
        L->elem[j+1] = L->elem[j];
    }
    //L->length - 1 是最后位置的下标,不减去1,会指针越界
    L->elem[i-1] = ElemType e;
    L->length++;
    return OK;
}

Tips:L->length + 1这个判断是为防止i越位。i = L->length 就说明这个传入的值的下表就是列表的尾处,想要插入这个位置

它的时间复杂度---0(N)

五.删除一个元素的位置

status DeleteList(Sqlist *L,int i, ElemType *e) {
    if (i < 1 || i > L->length + 1) {
        return ERROR;
    }
    
    //没有什么东西可以再删除了
    if (L->length == 0) {
            return ERROR;
    }
    if (i < L->length) {
        for (int j = i; j < L->length; j++) {
            L->elem[j-1] = L->elem[j];
        }
        L->length--;
        return OK;
}

它的时间复杂度为---0(N)

六.返回该顺序表的长度

int Length(Sqlist *L) {
    return L->length;
}

七.遍历并输出顺序表长度

void PrintList(Sqlist *L) {
    printf("当前顺序表的长度是:%d",L->length);
    for (int i = 0; i < L->length; i++) {
        printf("%d",L->elem[i]);
    printf("\n");
}

 八.寻找列表中是否存在该元素

status Locate(Sqlist *L,ElemType x) {
    for (int i = 0; i < L->length;i++) {
        if (L->elem[i] == x) {
            return i + 1; //返回元素的实际位置
        }
    return ERROR; // 寻找失败,列表中不存在该元素
}

九.按位查找

status Getelem(Sqlist *L,int i, ElemType *e) {
    if (i < 1 || i > L->length) {
        printf("查找位置非法,查找失败\n");
        return ERROR;
    }
    else {
        *e = L->elem[i-1]; 
        return *e;
}

Tips:

这里是我们在外面创造一个相关元素类型的指针,将用顺序表的指针寻找到的元素赋值给该我们所想要的元素,回传出来,也就实现了寻找到该位置上的元素的操作。

十.建立顺序表

int CreatList(Sqlist *L,ElemType a[],int n) {
    // int n指的是是该数组的大小
    if (n >MAXSZIE) {
        return ERROR;
    }
    for (int i = 0; i < n; i++) {
        L->elem[i] = a[i];
    }
    L->length = n;
    return OK;
}

三.最后一些相关操作

int main() {
	Sqlist L;
	int k, l;
	InitList(&L);
	OutPut(&L);
	int a[6] = { 1,2,3,4,5,6 };
	CreatList(&L, a, 6);
	OutPut(&L);
	InsertList(&L, 3, 5);
	OutPut(&L);
	ElemType v = 0;
	k = Getelem(&L, 4,&l);
	printf("%d", k);
	return 0;
}

以及附带的结果

当前顺序表的长度:0

当前顺序表的长度:6
123456
当前顺序表的长度:7
1253456
3

感谢你的观看

你可能感兴趣的:(数据结构,c语言,数据结构)