线性表 : 顺序表

线性表 linear list


线性表是具有 相同数据类型的n(n≥0)个数据元素的有限序列,其中n为表长,当n=0时,线性表是一个空表。

若用L命名线性表,则其一般表示为L = (a1, a2, … , ai , ai+1, … , an)

注:

ai是线性表中的“第i个”元素线性表中的位序 a1是表头元素;

an是表尾元素。

除第一个元素外,每个元素有且仅有一个直接前驱;除最后一个元素外,每个元素有且仅有一个直接后继

顺序表的定义

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

把逻辑上相邻的元素,存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现。

顺序表的基本操作

顺序表的实现:静态分配
//顺序表的实现-静态分配
typedef  struct {
    int data[MaxSize]; 
    //ElemType data[MaxSize]
    int length; //顺序表当前长度
}SqList; //sequence

//初始化一个顺序表
void InitList(SqList &L){
    L.length = 0;          //顺序表初始长度为0
}
//创建顺序表,输入元素
bool CreateList(SqList &L, int n)
{
	if (n<0 || n>MaxSize) return false;//非法判定
	for (int i = 0; i < n; i++)
	{
        printf("请输入顺序表第%d个元素:",i+1);
		scanf("%d", &L.data[i]);
		L.length++;
	}
	return true;
}

ElemType是一个抽象的概念,表示“数据元素的类型”,表示我们所要使用的数据元素应有的类型。

数据元素的大小:

sizeof(ElemType)

需要什么类型可以对它重定义:

typedef int ElemType;//定义ElemType为int类型
顺序表的实现:动态分配
#define InitSize 10 //定义初始长度
typedef  struct {
    int *data;
    int MaxSize;
    int length; //顺序表当前长度
}SeqList;
顺序表的实现
  1. 随机访问,在**O(1)**时间内找到任一元素
  2. 每个节点只存储数据元素**(区分链表)**
  3. 拓展容量不方便,,时间复杂度较高
  4. 插入、删除操作不方便
向顺序表中插入元素

在表L中的第i个位置上插入指定元素e

void ListInsert(SqList &L,int i,int e){
    for(int j=L.length;j>=i;j--){ 
        //将i和之后的元素后移
        L.data[j]=L.data[j-1];
    }
    //在位置i(对应数组下标i-1)放入e
    L.data[i-1]=e; 
    L.length++;
}

插入函数也可定义为bool函数

平均时间复杂度:O(n)

从顺序表中删除元素

删除表L中第i个位置的元素,并用e返回删除元素的值

bool ListDelete(SqList &L, int i,int &e){
    if(i<1 || i>L.length){
        return false;
    }
    e = L.data[i-1];       
    //将被删除的元素赋值给e
    for(int j = i; j < L.length; j++){ 
        //将第i个位置后的元素前移
        L.data[j-1] = L.data[j];
    }
    L.length--;
    return true;
}

平均时间复杂度:O(n)

顺序表的按位查找

获取表L中第i个位置的元素的值

int GetElem(SqList L, int i){
    return L.data[i-1];
}

由于顺序表的各个数据元素在内存中连续存放, 因此可以根据起始地址和数据元素大小立即找到 第 i 个元素

时间复杂度:O(1)

顺序表的按值查找

在表L中查找具有给定关键字值的元素

int LocateElem(SeqList L,int e){
    for(int i=0;i<L.length;i++)
        if(L.data[i]==e)
            return i+1; 
    //数组下标为i的元素值等于e,返回其位序i+1
    return 0; 
    //退出循环,说明查找失败
}

平均时间复杂度:O(n)

代码实现

#include <stdio.h>

#define MaxSize 10 

typedef  struct {
    int data[MaxSize]; 
    int length;            //线性表当前长度
}SqList;

//初始化线性表,构造一个空的顺序表
void InitList(SqList &L){
    L.length = 0;
}

//创建顺序表,输入元素
bool CreateList(SqList &L, int n)
{
	if (n<0 || n>MaxSize) return false;//非法判定
	for (int i = 0; i < n; i++)
	{
        printf("请输入顺序表第%d个元素:",i+1);
		scanf("%d", &L.data[i]);
		L.length++;
	}
	return true;
}
//插入 将e插入到第i个位置上
void ListInsert(SqList &L,int i,int e){
    for(int j=L.length;j>=i;j--){
        //将i和之后的元素后移
        L.data[j]=L.data[j-1];
    }
    //在位置i(对应数组下标i-1)放入e
    L.data[i-1]=e;
    L.length++;
}

//删除 删除第i个元素并把值赋给e返回
bool ListDelete(SqList &L, int i,int &e){
    if(i<1 || i>L.length){
        return false;
    }
    //将被删除的元素赋值给e
    e = L.data[i-1];      
    for(int j = i; j < L.length; j++){ 
        //将第i个位置后的元素前移
        L.data[j-1] = L.data[j];
    }
    L.length--;
    return true;
}
//得到顺序表中的第i个数字
int GetElem(SqList L, int i){
    return L.data[i-1];
}

//查找 查找第一个值为e的元素返回其位置(第i+1个)
int LocateElem(SqList L,int e){
    for(int i=0;i<L.length;i++)
        if(L.data[i]==e)
            return i+1; 
    return 0; 
}
//打印顺序表
void PrintList(SqList L){
    printf("顺序表中元素依次为:");
    for (int i = 0; i<L.length; i++)
	{
		printf("%d ", L.data[i]);
	}
    printf("\n");
}

//主函数
int main(){
    SqList L; 
    InitList(L); 
    if(CreateList(L,5)){
      PrintList(L);
      printf("此时顺序表的长度为:%d\n",L.length);
    }
    ListInsert(L,3,3);
    PrintList(L);
    printf("此时顺序表的长度为:%d\n",L.length);
    int e;
    if (ListDelete(L,5,e))
    {
        printf("原顺序表被删除第5个元素后,");
        PrintList(L);
        printf("此时顺序表的长度为:%d\n",L.length);
    }
    printf("顺序表中第3个数字是:%d\n",GetElem(L,3));
    printf("顺序表中值为5的数学位置在第%d个\n",LocateElem(L,5));
    printf("此时顺序表的长度为:%d\n",L.length);

    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值