考研数据结构笔记——2.顺序表

顺序表

假定线性表的元素类型为ElemType,线性表的存储类型描述为

#define MaxSize 50   //定义线性表的最大长度
typedef struct{
    ElemType data[MaxSize];     //顺序表的元素
    int length;     //顺序表的当前长度
}SqList;     //顺序表的类型定义

顺序表的动态分配

#define InitSize 100
typedef struct{
    ElemType *data;     //指示动态分配数组的指针
    int MaxSize,length;     //数组的最大容量和当前个数
}SeqList;       //动态分配顺序表的类型定义

C++的动态分配语句为
L.data = new Elemtype[InitSize]

顺序表的特点:

  • 随机访问(最重要的特点),通过首地址和元素序号,在O(1)的时间里找到元素
  • 存储密度高,每个节点只存储数据元素
  • 顺序表逻辑上相邻的元素物理上也相邻,所以元素的插入和删除需要移动大量的元素

顺序表上基本操作的实现

插入操作

bool ListInsert(Sqlist &L,int i,Elemtype e){
    if(i < 1||i > L.length + 1)     //判断i的范围
        return false;
    if(L.length >= MaxSize)     //判断存储是否已满
        return false;
    for (int j = L.length;j >= i;j--){
        L.data[j] = L.data[j - 1];  //元素后移
    L.data[j - 1] = e;      //位置i(下标i-1)处放入e
    L.length++;     //顺序表长度加1
    return true;
    }
}
  • 最好情况:在表尾插入,没有移动元素,时间复杂度为O(1)
  • 最坏情况:在表头插入,移动全部元素,时间复杂度为O(n)
  • 平均情况:有n+1个位置可供插入,概率相等,移动元素个数从0到n,则平均次数为n/2
  • 线性表插入算法的平均时间复杂度为O(n)

删除操作

bool ListDelete(Sqlist &L,int i,Elemtype &e){
    if(i < 1||i > L.length)     //判断i的范围
        return false;
    e = L.data[i - 1];
    for (j = i;j < L.length;j++)
    L.data[j - 1] =L.data[j];   //位置i(下标i-1)处后的元素前移
    L.length--;     //顺序表长度减1
    return true;
}
  • 最好情况:删除表尾元素,不用移动元素,时间复杂度为O(1)
  • 最坏情况:删除表首元素,移动所有元素,时间复杂度为O(n)
  • 平均情况:有n个位置可供删除,概率相等,移动元素个数从0到n-1,则平均次数为(n-1)/2
  • 线性表删除算法的平均时间复杂度为O(n)

按值查找(顺序查找)

int LocateElem(Sqlist L,ElemType e){
    int i;
    for(i = 0;i < L.length;i++){
        if(L.data[i] == e)  //下标为i的元素等于e
            return i + 1;   //返回其位序i+1
    }
    return 0;   //退出循环,查找失败
}
  • 最好情况:查找的元素就在表头,时间复杂度为O(1)
  • 最差情况:查找的元素在表尾(或不存在),时间复杂度为O(n)
  • 平均情况:有n个位置可供查找,概率相等,查找次数从1到n,则平均次数为(1+n)/2
  • 线性表查找算法的平均时间复杂度为O(n)
    原文作者:ribose
    原文地址: https://www.jianshu.com/p/1ce56e0fdc51
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞