线性表

线性表是一种有限序列,具有每个元素最多一个前驱和后继的逻辑特性。顺序表和链表是两种常见的存储结构,顺序表支持随机访问但插入删除效率低,链表插入删除快但不支持随机访问。链表插入删除要考虑不同位置的操作,带头结点和不带头结点的情况有所不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 线性表综述:
线性表是具有相同特性数据元素的一个有限序列
该序列中所包含元素的个数叫做线性表的长度
当一个线性表有序时,成为有序表,属于逻辑结构
线性表的逻辑特征:
对于至少含有一个元素的线性表来说
除起始元素没有前驱元素外,其他元素都有一个唯一前驱
除终端元素没有后继元素外,其他元素都有一个唯一后继
在线性表中,每个元素最多只有一个前驱和后继元素
线性表存储结构:
线性表有顺序和链式两类存储结构,前者成为顺序表,后者成为链表
顺序表特点:
无需为元素间的逻辑关系儿增加额外的存储空间
可以随机存取表中的任何一个元素,但是要占用连续的空间
而且插入和删除元素时需要移动大量的元素,平均需要移动n/2个元素
链表特点:
不仅存储每个节点的信息,而且也存储节点之间的关系(通过指针)
链表的地址可以是不连续的,不支持随机访问,插入和删除比较快
链表中的第一个节点的存储位置通常被成为头指针
如果链表有头结点,头指针为头结点的地址
如果没有头结点,头指针为开始节点的地址
通常用头指针来标识一个链表
1、顺序表程序:

//线性表存储空间的初始分配量 
#define LIST_INIT_SIZE 10
//顺序存储结构的分配增量 
#define LIST_INCREMENT 5
typedef int ElemType;
//顺序存储结构体
struct SqList
{
    ElemType* elem;     //存储空间基址
    int length;         //数据元素当前长度 
    int listsize;       //当前分配的总容量(元素个数) 
};
/*******基础操作********/
//初始化顺序表
void InitList(SqList* L)
{
    L->elem = (ElemType*)malloc(sizeof(ElemType)*LIST_INIT_SIZE); 
    if (L->elem == NULL)
    {
        printf("空间申请失败!\n");
        exit(-1); 
    }
    L->length = 0;
    L->listsize = LIST_INIT_SIZE;
}
//销毁顺序表
void DestroyList(SqList* L)
{
    free(L->elem);
    L->elem = NULL;
    L->length = 0;
    L->listsize = 0; 
}
//清空顺序表
void ClearList(SqList* L)
{
    L->length = 0;
}
//判空
int EmptyList(SqList* L)
{
    if (L->length == 0)
        return 1;
    return 0; 
}
//顺序表长
int ListLength(SqList* L)
{
    return L->length;
}
//得到顺序表第index元素
int GetElem(SqList* L, int index, ElemType* e)
{
    //要找的元素不在顺序表范围内 
    if (index<1 || index>L->length) 
        return -1;
    *e = L->elem[index-1];
    return 1; 
}
//返回元素的位置
int LocateElem(SqList* L, ElemType* e)
{
    for (int i=0; i<L->length; ++i)
    {
        //元素相等 
        if (L->elem[i] == *e) 
            return i;
    }
    return -1;
}
//返回元素的前驱
int PriorElem(SqList* L, ElemType* e)
{
    int index = LocateElem(L, e);
    //第一个元素没有前驱 
    if (index == -1 || index == 0)
        return -1;
    return index-1; 
}
//返回元素的后继
int NextElem(SqList* L, ElemType* e)
{
    int index = LocateElem(L, e);
    //最后一个元素没有后继 
    if (index == -1 || index == L->length-1)
        return -1;
    return index+1; 
}
//顺序表插入
int ListInsert(SqList* L, int index, ElemType* e)
{
    //判断插入位置是否合法
    if (index<1 || index>L->listsize)
        return -1; 
    //判断空间是否满
    if (L->length == L->listsize)
    {
        L->elem = (ElemType*)realloc(L->elem, (L->listsize+LIST_INCREMENT)*sizeof(ElemType)); 
        if (L->elem == NULL)
            exit(-1); 
        L->listsize += LIST_INCREMENT;
    }
    //开始插入
    for (int i=L->length-1; i>=index-1; --i)
    {
        //循环后移 
        L->elem[i+1] = L->elem[i]; 
    }
    //插入 
    L->elem[index-1] = *e; 
    //长度++
    L->length++; 

    return 1;
}
//顺序表删除
int ListDelete(SqList* L, int index)
{
    //判断删除位置是否合法
    if (index<1 || index>L->length)
        return -1;
    //开始删除
    for (int i=index-1; i<L->length; ++i)
    {
        L->elem[i] = L->elem[i+1]; 
    }
    --L->length;

    return 1;
}
//顺序表遍历
void ListTraverse(SqList* L)
{
    for (int i=0; i<L->length; ++i)
    {
        cout << L->elem[i] << ' '; 
    }
    cout << endl;
}
/*******进阶操作********/
//合并两个顺序表
//将所有在顺序表Lb中,但不在La中的元素插入到La中 
void Union(SqList* La, SqList* Lb)
{
    int lena = ListLength(La);
    int lenb = ListLength(Lb); 
    for (int i=0; i<Lb->length; ++i)
    {
        //在La中没有出现就插入 
        if (LocateElem(La, &(Lb->elem[i])) == -1) 
            ListIn
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值