数据结构与算法(1)线性表的顺序存储结构

转专业到计算机,最近在努力地提高自己的编程能力。数据结构与算法可以说是程序员的内功心法,我也下定决心学好这项内容,因此准备写下这一路的体会。一来鞭策自己不要中途懈怠、半途而废,二来以备将来查看方便。在博客中如果出现错误的话,还望各路大侠不吝赐教 O(∩_∩)O


1 线性表

1.1 概念

  • 线性表是最为简单且常见的数据类型,满足线性结构:
    • 存在唯一的第一个数据元素
    • 存在唯一的最后一个元素
    • 除第一个元素外,其余元素都有唯一的前驱元素
    • 除最后一个元素外,其余元素都有唯一的后继元素
  • 线性表中的数据元素属于同一数据类型。这个数据类型可以是简单的基本数据类型也可以是复杂的结构。
  • 在线性表按照存储形式区分可以分为顺序存储结构和链式存储结构,在本篇博客中主要介绍顺序存储结构(顺序表),所谓的顺序存储结构指的是数据元素存储是按照地址连续的方式进行存储的,在C语言中数组就是这样的类型,因此我们可以使用数组来模拟实现顺序存储结构

1.2 C实现顺序表

#define MAX_SIZE 100

typedef char ElemType;
typedef struct{
    ElemType data[MAX_SIZE];
    int length;
}SqList;
  • 我们使用了结构来描述这样一个线性表,数据元素使用数组进行存储,因此是顺序存储结构。
  • 我们可以构建更为复杂的线性表,并不局限于这里的数据元素的类型,ElemType
    可以是非常复杂的结构。
  • 这个线性表有一个长度属性,便于我们之后对这个线性表的操作

1.3 顺序表的基本操作

  • 顺序表的初始化操作
void InitList(SqList *L)
{
    L->length = 0;
}
  • 判断是否为空
bool ListEmpty(SqList L)
{
    if (L.length == 0){
        return true;
    }
    else{
        return false;
    }
}
  • 得到顺序表的长度
int ListLength(SqList L)
{
    return L.length;
}
  • 打印顺序表数据内容
void DispList(SqList L)
{
    int i;
    if (ListEmpty(L)){         
        printf("空表\n");
    }
    else{
        for (i = 0; i < L.length; ++i){
            printf("%c ", L.data[i]);
        }
        printf("\n");
    }
}
  • 根据索引得到数据内容
bool GetElem(SqList L, int i, ElemType *e)
{
    int j = 0;
    if (i < 1 || i > L.length)
        return false;
    else{
        *e = L.data[i - 1];
        return true;
    }
}
  • 根据数据内容得到索引值
int LocateElem(SqList L, ElemType e)
{
    int i = 0;
    while (i < L.length && L.data[i] != e)
        ++i;

    if (i >= L.length)
        return 0;   //没有找到
    else
        return i + 1;
}
  • 在顺序表中插入元素
bool ListInsert(SqList *L, int i, ElemType e)
{
    int j;
    if (i < 1 || i >L->length + 1)      //第一个可以插入位置为1, 最后一个可以插入位置为length + 1
        return false;

    for (j = L->length; j >= i; --j){
        L->data[j] = L->data[j - 1];
    }

    L->data[i - 1] = e;
    L->length++;            //特别注意,当插入一个元素之后,对应的长度要进行加1操作
    return true;
}
  • 在顺序表中删除元素
bool ListDelete(SqList *L, int i, ElemType *e)
{
    int j;
    if (i < 1 || i > L->length)
        return false;
    else{
        *e = L->data[i - 1];
        for (j = i; j < L->length ; ++j)
            L->data[j - 1] = L->data[j];
        L->length--;        //特别注意删除了一个元素之后,顺序表的长度需要减少1
        return true;
    }
}

总结:

  1. 顺序表的特点是逻辑上相邻的两个元素在物理位置上也是相邻的,因此可以随机存取表中的任一元素
  2. 顺序表的插入和删除的时间复杂度是O(n), 求表长和取第 i 个元素的时间复杂度是O(1)。在进行删除和插入操作的时候,移动的元素很多,时间复杂度比较大。

你可能感兴趣的:(数据结构与算法(1)线性表的顺序存储结构)