算法2.0 线性表顺序存储的实现

这里写图片描述

线性表的特点

单链表强调元素在逻辑上紧密相邻,所以首先想到用数组存储。但是普通数组有着无法克服的容量限制,在不知道输入有多少的情况下,很难确定出一个合适的容量。对此,一个较好的解决方案就是使用动态数组。首先用malloc申请一块拥有指定初始容量的内存,这块内存用作存储单链表元素,当录入的内容不断增加,以至于超出了初始容量时,就用realloc扩展内存容量,这样就做到了既不浪费内存,又可以让单链表容量随输入的增加而自适应大小。
这里写图片描述


特点

  • 线性表的顺序存储结构是一种随机存取的存储结构,因此只要确定了存储线性表的起始位置,线性表中任意数据元素都可以随机存取
  • 线性表的插入或者删除操作,是一种牵一发而动全身的操作,插入元素需要将带插入位置后面的所有元素后移一位,删除元素反之

一 设置数据结构体

typedef int ElemType;
// 定义结构体
typedef struct SeqList_tag
{
    ElemType * elem;        //线性表的起始地址
    int length;             //线性表的长度
    int size;               //线性表现有的长度  
}SeqList;

elem作为线性表的起始地址,内部存储的是线性表的第一个元素,可以根据这个地址,通过指针运算,找到后面的元素

二 初始化线性表

int InitList (SeqList * L)
{
    // 1.1 分配一块内存
    L->elem = (SeqList *) malloc (LIST_INIT_SIZE * sizeof (ElemType));
    if (L->elem == NULL)
    {
        return -1;
    } 
    // 1.2 结构体相关元素的初始化
    L->length = 0;
    L->size   = LIST_INIT_SIZE;

    return 0;
}

三 插入一个元素

// 6 在L中的第i个位置前插入新的元素e
int ListInsert (SeqList * L, int pos, int val)
{
    ElemType * newbase;
    ElemType * p; 
    ElemType * q;
    // 6.1 首先判断链表L是否为空且插入的位置是否正确,如果错误,返回-1,结束程序
    if ((pos < 1) || (pos > L->length + 1))
    {
        return -1;  
    }   
    // 6.2 判断当前是否还有空间存储新插入的元素,如果没有的话,使用realloc添加分配内存
    if (L->length >= L->size)
    {
        newbase = (ElemType *) realloc (L->elem, (LISTINCREMENT + L->size) * sizeof (ElemType));
        if (newbase == NULL)
        {
            return -1;
        }
        L->elem = newbase;
        L->size += LISTINCREMENT;
    }
    // 6.3  插入元素
    // 6.3.1 首先找到带插入元素的位置 ,直接进行指针插入运算 
    q = L->elem + pos - 1;
    // 6.3.2 将pos位置的元素都向后移动一位,为插入的元素留下存储空间
    for (p = L->elem + L->length - 1; p >= q; --p)
    {
        *(p - 1) = * p; 
    } 
    // 6.3.3 插入元素
    *q = val;
    // 6.3.4 总的长度 + 1
    L->length += 1; 
    return 0;
}

四 删除一个元素

ElemType ListDelete (SeqList * L, int pos)
{
    ElemType * p;              // 存放待删除元素的地址
    ElemType * q;              // 存放线性表的最后一个元素的地址
    ElemType val;             // 保存待删除元素的值
    if (pos < 1 || pos > L->length)
    {
        return 10086;
    }

    p = L->elem + pos - 1;
    val = *p;
    q = L->elem + L->length - 1;

    for (; p <= q; p ++)
    {
        *(p - 1) = * p; 
    }

    L->length -= 1;
    return val;
} 

查看某一个位置存放的元素内容

ElemType GetElem (SeqList * L, int pos)
{
    if (pos < 1 || pos > L->length)
    {
        return -1;
    }
    return * (L->elem + pos - 1);
}

C语言中 -> 和 . 的区别
a->b 的含义是 (*a).b

猜你喜欢

转载自blog.csdn.net/NaLaEur/article/details/81736273
今日推荐