学习顺序表的自己的一些归纳

这篇博客介绍了C语言中顺序线性表的初始化、插入和删除操作。`InitList_Sq()`函数用于初始化线性表,动态分配存储空间。`ListInsert_Sq()`函数在指定位置插入元素,当存储空间不足时,通过`realloc()`扩展空间。`ListDelete_Sq()`函数删除指定位置元素,后续元素左移。所有操作的时间复杂度在最坏情况下为O(n)。
摘要由CSDN通过智能技术生成

初始化

​
#include<stdio.h>
#include<malloc.h>
#define LIST_INIT_SIZE 100  //线性表存储空间的初始分配量
#define LISTINCREMENT 10  //线性表存储空间的分配增量
​
typedef  struct{
    int *elem;     //存储空间基址
    int length;       //当前长度 
    int listsize;     //当前分配的存储容量(以sizeof(ElemType)为单位) 
}SqList;
​
//初始化
int InitList_Sq(SqList *L)
{
    L->elem = (int *)malloc(LIST_INIT_SIZE * sizeof(int));  //构造一个空的线性表L,分配空间
    if(!L->elem)
    {
        return -1;   //存储分配失败(申请失败) 
    }
    L->length = 0;   //空表长度为 0 
    L->listsize = LIST_INIT_SIZE;   //初始存储容量
    return 1; 
}
 
​
int main()
{
    SqList L;   //声明一个顺序表
    InitList_Sq(&L);   //初始化
    for(int i=0; i<10; i++)   //将顺序表的前10个单元赋值为0~9, 
    {
        L.elem[i] = i;
        L.length++;
        printf("%d ", L.elem[i]);   
    } 
}
 
 
'''
结果:
0 1 2 3 4 5 6 7 8 9
​

不懂

1 ElemType

因为数据结构是讨论抽象的数据结构和算法,一种结构中元素的类型不一定是整型、字符型、浮点型或者用户自定义类型,为了不重复说明,使用过程用 “elemtype” 代表所有可能的数据类型,简单明了的概括整体。

在算法中,除特别说明外,规定ElemType的默认是int型。

2 typedef struct

typedef是类型定义的意思。typedef struct 是为了使用这个结构体方便。

具体区别在于: 若struct node{ }这样来定义结构体的话。在定义 node 的结构体变量时,需要这样写:struct node n; 若用typedef,可以这样写:typedef struct node{}NODE; 。在申请变量时就可以这样写:NODE n;其实就相当于 NODE 是node 的别名。区别就在于使用时,是否可以省去struct这个关键字。

3 InitList_Sq()是什么意思

此段函数作用:初始化线性表,并使用动态内存分配函数 malloc 为线性表分配空间

int InitList_Sq(SqList *L);//形参是个指针,只需要赋指针(地址)给它就可以了

c语言的函数参数是值调用

4 malloc()

下面是 malloc() 函数的声明。

void *malloc(size_t size)
  • size -- 内存块的大小,以字节为单位。

  • 该函数返回一个指针 ,指向已分配大小的内存。如果请求失败,则返回 NULL。

5 问题1:

  1. 1. L->elem = (ElemType * )malloc(LIST_INIT_SIZE*sizeof(ElemType));

    2. newbase = (ElemType )realloc(L.elem,(L.listsize+LISTINCREMENT)sizeof(ElemType));

    其中L是已经定义的线性表,LIST_INIT_SIZE是线性表存储空间的初始分配量,listsize是当前分配的存储容量(以sizeof(ElemType)为单位)

    解释:

    第一个句子: 用malloc分配一段这么 LIST_INIT_SIZE * sizeof(ElemType) 多个字节的内存段,它返回一个指向该内存段首字节的指针变量,然后把这个指针变量强制转换为ElemType*类型,再把这个经转换的指针变量赋给L的elem成员 第二个句子: 先看一段话:

6 realloc语法:

指针名=(数据类型 * )realloc(要改变内存大小的指针名,新的大小)。 新的大小一定要大于原来的大小,不然的话会导致数据丢失! 所以你这个句子的意思是:把L的elem指向的那段内存扩大LISTINCREMENT*sizeof(ElemType)个字节。

6 sizeof的用法:

这是一个运算符(而不是一个函数,这点认识很重要)

sizeof(类型说明符,数组名或表达式) 或 sizeof 变量名 得到一个对象或者类型所占的内存字节数。 例如,如果你的机器上int占4字节,那么sizeof(int)就是4

malloc用法:

它是一个函数,原型是void *malloc(size_t size); 前面提过了,就是分配size个字节的内存,然后返回指向这段内存首字节的指针,void * 表示未确定类型的指针,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者...),所以你要用它指向什么数据,一般就要在malloc前加一个强制转换,把这个指针转为适合你使用的类型。

7 L->elem = (int *)malloc(LIST_INIT_SIZE * sizeof(int));

分配一个存储容量的大小LIST_INIT_SIZE×sizeof(ElemType)的存储空间.L->elem指向这存储空间的首地址.这是线性表的内容吧.打个比方说:就是建造了一个数组,比如说啊a[10],但这个数组是空的,L->elem就是指向数组的首地址.

8 顺序表的插入

要在第 i (1<=i<=n)个元素之前插入元素,共n-i+1个元素依次向后移一个位置。

插入下标位置 i012···i···n-1n
移动次数nn-1n-1···n-i···10

若长度为n的线性表采用顺序存储结构,在其第 i 个位置插入一个新元素的算法时间复杂度为O(n)

若i = n,算法时间复杂度为O(1)

​
#include<stdio.h>
#include<malloc.h>
#define LIST_INIT_SIZE 100  //线性表存储空间的初始分配量
#define LISTINCREMENT 10  //线性表存储空间的分配增量
typedef  struct{
    int *elem;     //存储空间基址
    int length;       //当前长度 
    int listsize;     //当前分配的存储容量(以sizeof(ElemType)为单位) 
}SqList;
 
int InitList_Sq(SqList *L)
{
    L->elem = (int *)malloc(LIST_INIT_SIZE * sizeof(int));  //构造一个空的线性表L
    if(!L->elem)
    {
        return -1;   //存储分配失败(申请失败) 
    }
    L->length = 0;   //空表长度为 0 
    L->listsize = LIST_INIT_SIZE;   //初始存储容量
    return 1; 
}
 
​
//插入(老师版本)
int ListInsert_Sq(SqList *L, int i, int e)  //在顺序表的第i个位置插入元素e 
{
    int k;
    //i的范围区间[1, ListLength_Sq(L)+1] 
    if(i<1 || i>L->length+1)
    {
        return -1;   //i的值不合法 
    }
    if(L->length >= L->listsize)  //存储空间=分配空间,空间已满,增加分配 
    {
        L->elem= (int *)realloc(L->elem, (L->listsize+LISTINCREMENT) * sizeof(int));
        if(!L->elem)
        {
            return -1;    //存储分配失败  
        } 
        L->listsize += LISTINCREMENT;  //增加存储容量 
    }
    for (k=L->length; k>i-1; k--)  
    {
        L->elem[k]=L->elem[k-1];
    } 
    L->elem[k]=e;  //插入元素e
    L->length++;  //顺序表长度加1
    return 1;
}
​
/*插入(用指针)
​
int ListInsert_Sq(SqList *L, int i, int e)  //在顺序表的第i个位置插入元素e 
{
    //i的范围区间[1, ListLength_Sq(L)+1] 
    if(i<1 || i>L->length+1)
    {
        return -1;   //i的值不合法 
    }
    if(L->length >= L->listsize)  //存储空间=分配空间,空间已满,增加分配 
    {
        int *newbase = (int *)realloc(L->elem, (L->listsize+LISTINCREMENT) * sizeof(int));
        if(!newbase)
        {
            return -1;    //存储分配失败  
        } 
        L->elem = newbase;   //新基址
        L->listsize += LISTINCREMENT;  //增加存储容量 
    }
    int *q = &(L->elem[i-1]);  //q为插入的位置
    for (int *p=&(L->elem[L->length-1]); p>=q; --p)  //p为最后一个位置,用来移动元素 
    {
        *(p+1) = *p;      //插入位置及之后的元素右移 
    } 
    *q = e;   //插入元素e
    ++L->length;   //表长增1
    return 1;
}
​
*/
 
int main()
{
    SqList L;   //声明一个顺序表
    InitList_Sq(&L);  //初始化
    for(int i=1; i<=10; i++)  //空表中,逐个插入1~10
    {
        ListInsert_Sq(&L, i, i);
    } 
    for(int i=0; i<10; i++)   //遍历、打印 
    {
        printf("%d ", L.elem[i]);
    }
}
 
'''
结果:
1 2 3 4 5 6 7 8 9 10

9 删除

删除下标位置 i012···i···n-2n-1
移动次数n-1n-2n-3···n-i+1···10

若长度为n的线性表采用顺序存储结构,在其第 i 个位置删除一个元素的算法时间复杂度为O(n)

若i = n-1,算法时间复杂度为O(1)

#include<stdio.h>
#include<malloc.h>
#define LIST_INIT_SIZE 100  //线性表存储空间的初始分配量
#define LISTINCREMENT 10  //线性表存储空间的分配增量
typedef  struct{
    int *elem;     //存储空间基址
    int length;       //当前长度 
    int listsize;     //当前分配的存储容量(以sizeof(ElemType)为单位) 
}SqList;
 
int InitList_Sq(SqList *L)
{
    L->elem = (int *)malloc(LIST_INIT_SIZE * sizeof(int));  //构造一个空的线性表L
    if(!L->elem)
    {
        return -1;   //存储分配失败(申请失败) 
    }
    L->length = 0;   //空表长度为 0 
    L->listsize = LIST_INIT_SIZE;   //初始存储容量
    return 1; 
}
 
int ListDelete_Sq(SqList *L, int i, int *e)  //在顺序表L中删除第i个元素,用e返回其值
{
    //i的范围区间[1, ListLength_Sq(L)+1]
    if(i<1 || i>L->length)
    {
        return -1;   //i值不合法 
    } 
    int *p = &(L->elem[i-1]);  //指针p指向被删除元素的位置 
    *e = *p;   //被删除的元素赋值给e
    int *q = &(L->elem[L->length-1]);   //指针p指向表尾元素的位置 
    for(++p; p<=q; ++p) 
    {
        *(p-1) = *p;   //被删除元素之后的元素左移 
    }
    --L->length;   //表长减1 
    return 1;
}
 
int main()
{
    SqList L;    //声明一个顺序表
    InitList_Sq(&L);    //初始化
    for(int i=0; i<10; i++)
    {
        L.elem[i] = i;  //空表中,逐个赋值0~9
        printf("%d ", L.elem[i]);
        L.length++;
    }
    printf("\n");
    int e = 0;
    ListDelete_Sq(&L, 6, &e);
    printf("被删除的元素是:%d\n", e);
    printf("删除后的顺序表:");
    for(int i=0; i<9; i++)
    {
        printf("%d ", L.elem[i]);   
    } 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值