当前位置:首页 > 数据结构与算法 > 正文内容

线性表的顺序结构(顺序表)

admin4年前 (2020-08-12)数据结构与算法9025

顺序表,线性表的一种,其存储时需要开辟一块足够大的连续的空间,数据之间的存放是相连的,中间没有空隙。

顺序表.jpg

顺序表的初始化:需要指定顺序表的大小,这个大小要足够大,还要将元素个数初始化为0。

按照位置查找元素:可以查找指定位置的元素,这个通过下标可以快速找到。常数时间复杂度。

查找指定元素的位置:给定一个元素,查找其所在的位置。这个可以从第一个元素开始,遍历所有元素进行查找,找到第一个后就可以返回。

插入元素:在指定位置插入元素。首先位置是要合法的,这个可以进行判断;在插入时,首先需要从最后一个元素开始,一直到插入位置的元素将它们向后移动一个位置。移动完毕后将要插入的元素写入到对应位置。当然元素个数也要相应的加一。

注:以上两图来自于LeetCode,链接:https://leetcode-cn.com/leetbook/read/array-and-string/yjcir/

删除元素:比插入要简单一点,直接将要删除元素后的元素向前移动一个位置就可以。元素个数要相应的减一。插入和删除要素要大量的进行元素的移动操作,这严重影响了顺序表的效率。

注:上图来自于LeetCode,链接:https://leetcode-cn.com/leetbook/read/array-and-string/yjcir/

以下代码根据某课程进行了少量的修改,有问题还请理解。

/*
线性表的顺序存储结构,数据在内存中是连续存储的,C语言中主要是通过数组来实现
其插入删除操作时,由于要进行大量的数据移动操作,涉及到大量的数据拷贝等工作,
所以效率比较低。以下代码实现了线性表顺序存储结构的初始化、查找、插入、删除等操作。
*/
#include <stdio.h>
#include <stdlib.h>

#define LIST_INIT_SIZE 100
#define LIST_INCREAMENT 10

typedef int ElemTYPE;

//顺序表的结构,包括数据,长度,表的大小
typedef struct SqList
{
    ElemTYPE *elem;
    int length;
    int list_size;
} SqList, *Ptr;

typedef Ptr SqListPtr;

//状态
typedef enum Status
{
    success,
    fail,
    range_error
} Status;

Status List_Init(SqListPtr L);                              //线性表顺序存储结构初始化生成一个空表
Status List_Retrivsl(SqListPtr L, int pos, ElemTYPE *elem); //按位置查找
Status List_Locate(SqListPtr L, ElemTYPE elem, int *pos);   //按值查找位置
Status List_Insert(SqListPtr L, int pos, ElemTYPE elem);    //插入元素
Status List_Delete(SqListPtr L, int pos);                   //删除元素
void print_data(SqListPtr L);                               //打印数据

int main()
{
    SqListPtr list;
    printf("initial data
");
    List_Init(list);
    printf("insert 5 data:
");
    ElemTYPE data;
    for (int i = 1; i < 6; i++)
    {
        scanf("%d", &data);
        List_Insert(list, i, data);
    }
    print_data(list);

    printf("
");
    printf("delete data:
");
    int pos;
    scanf("%d", &pos);
    List_Delete(list, pos);
    print_data(list);
    printf("
");

    ElemTYPE elem;

    printf("the position you will find:
");
    scanf("%d", &pos);
    List_Retrivsl(list, pos, &elem);
    printf("%d
", elem);

    printf("the element you will find:
");
    scanf("%d", &elem);
    List_Locate(list,elem,&pos);
    printf("%d
",pos);

    system("pause");
    return 0;
}

Status List_Init(SqListPtr L)
{
    Status s = success;
    L->list_size = LIST_INIT_SIZE;
    L->length = 0;
    L->elem = (ElemTYPE *)malloc(sizeof(ElemTYPE) * L->list_size);
    if (L->elem == NULL)
    {
        s = fail;
    }
    return s;
}

Status List_Retrivsl(SqListPtr L, int pos, ElemTYPE *elem)
{
    Status s = range_error;
    if (L)
    {
        if ((pos - 1) >= 0 && (pos - 1) < L->length)
        {
            *elem = L->elem[pos - 1];
            s = success;
        }
    }
    return s;
}

Status List_Locate(SqListPtr L, ElemTYPE elem, int *pos)
{
    Status s = range_error;
    if (L)
    {
        for (int i = 0; i < L->length; ++i)
        {
            if (L->elem[i] == elem)
            {
                *pos = i + 1;
                s = success;
                break;
            }
        }
    }
    else
    {
        s = fail;
    }
    return s;
}

Status List_Insert(SqListPtr L, int pos, ElemTYPE elem)
{
    Status s = range_error;
    if ((pos - 1) >= 0 && (pos - 1) <= L->length)
    {
        for (int i = L->length - 1; i >= pos - 1; --i)
        {
            L->elem[i + 1] = L->elem[i];
        }
        L->elem[pos - 1] = elem;
        L->length++;
        s = success;
    }
    else
    {
        s = fail;
    }

    return s;
}

Status List_Delete(SqListPtr L, int pos)
{
    Status s = range_error;
    if ((pos - 1) >= 0 && (pos - 1) <= L->length)
    {

        if (L && L->length > 0)
        {
            for (int i = pos; i < L->length; ++i)
            {
                L->elem[i - 1] = L->elem[i];
            }
            L->length--;
            s = success;
        }
    }
    else
    {
        s = fail;
    }
    return s;
}

void print_data(SqListPtr L)
{
    for (int i = 0; i < L->length; i++)
    {
        printf("%d ", L->elem[i]);
    }
}


扫描二维码推送至手机访问。

版权声明:本文由lovedm.club发布,如需转载请注明出处。

本文链接:http://lovedm.club/?id=74

分享给朋友:
返回列表

上一篇:线性表

下一篇:单链表

“线性表的顺序结构(顺序表)” 的相关文章

单链表

单链表

单链表存储一个直接后继的地址,用一组任意的存储单元存储线性表中的元素。数据域(数据元素)+指针域(指示后继元素存储位置) = 结点,如下图:a和b是两个结点,其中a的指针域保存了指向b的地址。以结点的序列表示线性表 称为链表以线性表中第一个数据元素a1的存储地址作为线性表的地址,称作线性表的头指针。...

二分查找

二分查找

使用二分法对数组进行元素的搜索,返回查找的元素索引,当然使用二分搜索的前提是数组已经完成排序。原始数组有10个元素,要搜索的元素是11。整个排序过程如下:首先原始数组如下:第一次两个指针位置如下:低指针和高指针分别指向数组元素的最低处和最高处,也就是指向索引0位置和索引 length-1处,中点指向...

C# 二叉树

C# 二叉树

这里实现了二叉树的创建与插入结点,前中后序遍历的递归实现以及前序遍历的非递归实现,层序遍历的非递归实现。插入结点时采用二叉排序树的方式,没有处理有相同结点时的情况,按下面代码中插入结点时,构成的二叉树如下:using System; using System.Collectio...

以层序插入二叉树结点

这里以层序插入二叉树的结点,以先序遍历输出。上一篇关于二叉树的内容在这里:http://lovedm.club/?id=110using System; using System.Collections.Generic; namespace BTree {...

中缀表达式转后缀表达式

中缀表达式转后缀表达式

转换过程如下:1、运算数:直接输出;2、左括号:压入堆栈;3、右括号:将栈顶的运算符弹出并输出,直到遇到左括号(出栈,不输出);4、运算符:若优先级大于栈顶运算符时,则把它压栈;若优先级小于等于栈顶运算符时,将栈顶运算符弹出并输出;再比较新的栈顶运算符,直到该运算符大于栈顶运算符优先级为止,然后将该...