顺序表_线性表考研笔记

顺序表———线性表考研笔记


1.1顺序表的定义

用顺序存储的方式实现线性表

  • 顺序存储:逻辑上相邻的元素物理位置上也相邻
  • 元素之间的关系通过存储单元的邻接关系实现

1.2顺序表的实现

1.2.1静态分配

顺序表的长度不可以改变

1.2.1.1 数据对象的定义
#define MaxSize 10//定义最大长度
typedef struct{
    
    
	ElemType data[MaxSize];//静态的数组存放数据元素
	int Length;//顺序表的当前长度
}SqList;
1.2.1.2 数据元素的初始化 InitList(&L)
  • 把每个数据元素的值设为默认值(可省略)
  • 顺序表初始长度设为0(不可省略
    • 遍历、打印顺序表的元素需要用到顺序表实际长度非MaxSize)作循环条件
void InitList(SqList *L){
    
     //传元素的指针才能在调用函数内部修改该元素的值
    for (int i = 0;i < MaxSize; ++i)
        L->data[i] = 0;
    L->Length = 0;//顺序表初始长度为0
}
1.2.1.3 数据元素的插入 ListInsert(&L, i , e)
  • 在表中的第i个位置(位序)上插入指定元素e

  • 插入成功返回True,插入失败返回False

  • 时间复杂度的分析

    • 最好情况(O(n)=1)
    • 平均情况(O(n)=n)
    • 最坏情况(O(n)=n)
  • 注意事项

    • 数据元素移动方式:从表尾元素开始依次向前
    • 注意位序和数组下标的关系(位序为i,数组下标为i-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[i-1] = e;//在位置i插入e
    L->Length += 1;//表长加一    
    return true;
}
1.2.1.4 数据元素的删除 ListDelete(&L, i , &e)
  • 删除表L中第i个位置的元素(表修改->传表的地址),并用e返回删除元素的值(传元素的地址)

  • 删除成功返回True,删除失败返回False

  • 时间复杂度的分析

    • 最好情况(O(n)=1)
    • 平均情况(O(n)=n)
    • 最坏情况(O(n)=n)
  • 注意事项

    • 数据元素移动方式:从靠前的元素开始依次向后
bool ListDelete(SqList *L;int i,ElemType &e){
    
    
    if (i < 1 || i > L->Length)//判断i的范围是否有效
        return false;
    e = L->data[i-1];//将被删除的元素赋值给e(注意位序与下标的关系)
    for(int j = i; j < L->Length ; ++j)
        L->data[j-1] = L->data[j];//将第i个位置后的元素前移(移动元素下标从i开始)
    L.Length -= 1;//线性表长度减1
    return true;//成功删除
}
1.2.1.5 数据元素的按位查找 GetElem(L, i )
  • 按位查找操作:获取表L中第i个位置(位序)的元素的值
  • 时间复杂度O(1)
ElemType GetElem(SqList L,int i){
    
    
    if (i < 1 || i > L->Length)//判断i的范围是否有效
        return false;    
    return L.data[i-1];//位序和数组下标关系
}
1.2.2动态分配
  • 利用malloc函数动态分配一片连续的存储区域
  • 然后通过指向该片存储区域的起始位置的指针实现对元素的操作
1.2.2.1数据对象的定义
typedef struct{
    
    
	ElemType *data;//指示动态分配数组的指针(顺序表的首元素)
    int Maxsize;//顺序表的最大长度
	int Length;//顺序表的当前长度
}SeqList;
1.2.2.2 动态数组的初始化 InitList(&L, InitSize)
void InitList(SeqList *L,int InitSize){
    
    
	L->data = (ElemType *)malloc(sizeof(ElemType)*InitSize);//动态分配存储空间
    L->Length = 0;
    L->Maxsize = InitSize;
}
1.2.2.3 增加动态数组的长度 IncreaseSize(&L, Len)
  • 重新申请内存空间,将原内存空间的元素复制到新的内存空间
  • 释放原内存空间
#include <stdlib.h> //malloc、free函数的头文件
void IncreaseSize(SeqList *L, int Len){
    
    
    ElemType *q = L->data;//指向顺序表动态数组首元素
    L->data = (ElemType *)malloc(sizeof(ElmeType)*Len);//重新申请内存空间
    for (int i =0; i < L->Length; ++i)
        L->data[i] = q[i];//复制元素    
    L->MaxSize += Len;//顺序表的最大长度增加Len
    free(q);//释放原来的内存空间
}
1.2.2.4 数据元素的按位查找 GetElem(L, i )
  • 按位查找操作:获取表L中第i个位置(位序)的元素的值
  • 时间复杂度O(1)
ElemType GetElem(SeqList L,int i){
    
    
    if (i < 1 || i > L->Length)//判断i的范围是否有效
        return ERROR;
    return L.data[i-1];//位序和数组下标关系
}
1.2.2.4 数据元素的按值查找 GetElem(L, e)
  • 按值查找操作:在表L中查找具有给定关键字值的元素

  • 成功:返回第一个元素值等于e的位序;失败:返回0

  • 时间复杂度 最好O(1) 最坏O(n) 平均O(n)

int LocateElem(SeqList L,ElemType e){
    
    
    for (int i = 0; i < L.Length; ++i)
        if (L.data[i] == e)
            return i+1;//位序和数组下标关系
    return 0;
}

1.3顺序表的代码注意

  1. 位序和数组下标的关系(位序为i,数组下标为i-1

  2. 移动元素是从表尾元素开始移动还是从靠前元素开始移动

  3. 判断位置i是否合法(程序健壮性):不合法返回ERROR(宏定义)

    • 位置比表头元素还前
    • 插入位置比表尾元素后一个位置还后(顺序表元素存放是连续的,不能中间空了没有元素)
    • 表是否已经满(不能再插入元素)
  4. 结构类型的数据元素不能直接比较,需依次对比各个分量来判断两个结构体是否相等自定义判断函数

猜你喜欢

转载自blog.csdn.net/jimmy33777/article/details/105594762