线性表——最基础的数据结构

简介: 1、什么是线性表2、线性表的分类3、顺序表和链表的创作实现和基本操作4、顺序表和链表的对比

线性表——最基础的数据结构

1、什么是线性表?

​ 在学习线性表之前,我们首先需要了解线性表是什么

​ 线性表是最基本、最简单、也是最常用的一种数据结构。线性表(linear list)是数据结构中的一种,一个线性表是n个具有相同特性的数据元素的有限序列。

​ 线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储,但是把最后一个数据元素的尾指针指向了首位结点)

​ 我们说“线性”和“非线性”,只在逻辑层次上讨论,而不考虑存储层次,所以双向链表和循环链表依旧是线性表。

2、线性表的分类

数据结构——线性表图1.png

(图片来自网络,侵删)

3、顺式结构

定义:

​ 线性表的顺序存储是指在内存中用地址连续的一块存储空间依次存放线性表的数据元素,用这种存储形式存储的线性表称为顺序表。

其储存方式如下图所示:

数据结构——线性表图2.jpg

顺序存储的实现方式:

#include<iostream>
#define MAXSIZE 100        //定义最大储存空间
#define ElemType int        //定义数据类型
#define ERROR 0
#define TRUE 1
#define OVERFLOW -1

using namespace std;

//定义顺序表
typedef struct LNode *List;
struct LNode{
    ElemType Data[MAXSIZE];
    int Last;
};

创建一个空的顺序表:

List MakeEmpty(){
    //构造一个空的线性表Ptrl
    List L
    L= new LNode;    //分配存放顺序表的空间
    L->Last = 0;
    return L;
}

输入顺序表/初始化顺序表

void MakeList(List Ptrl)
{
    int i;
    cin >> n;        //输入需要的表长
    for(i = 0; i < n; i++){
        cin >> Ptrl->Data[i];    
    }
    L->Last = n;        //设置表长
}

销毁/删除顺序表:

void DestroyList(List Ptrl)
{
    delete Ptrl;
}

按数据元素查找:

int Find(List Ptrl, ElemType X)
{
    int i = 0;
    while(i <= Ptrl->Last && Ptrl->Data[i] != X)
        i++;
    if (i > Ptrl->Last)
         return ERROR;
    else
        return i;

顺序表的插入:

bool Insert(List Ptrl, ElementType X, int i)
{
    int j;

    if (Ptrl->Last >= MAXSIZE-1)        //判断空间是否已满
    {
        cout << "NO SPACE";
        return OVERFLOW;
    }
    if (i < 1 ||i > Ptrl->Last+2)        //判断是否非法输入
    {
        cout << "ILLEGAL INPUT";
        return ERROR;
    }
    for (j = Ptrl->Last; j >= i-1; j--)        //将位置i后面的元素后移一个位置
    {
        Ptrl->Data[j+1] = Ptrl->Data[j];
    }
    Ptrl->Data[i-1] = X;    //插入数据
    Ptrl->Last++;    //顺序表长度加1
    return TRUE;
}

顺序表的删除:

bool Delete(List Ptrl, int i)
{
    int j;

    if (i < 1 ||i > Ptrl->Last+1)        //判断是否非法输入
    {
        cout << "ILLEGAL INPUT";
        return ERROR;
    }
    for (j = i; j <= Ptrl->Last; j++)        //将位置i后面的元素前移一个位置
    {
        Ptrl->Data[j-1] = Ptrl->Data[j];
    }
    Ptrl->Last--;    //顺序表长度减1
    return TRUE;
}

4、链式结构

定义:

​ 线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的。这就意味着,这些元素可以存在内存未被占用的任意位置。

其储存方式如下图所示:

数据结构——线性表图3.png

链式结构的实现方式:

#include<iostream>
#define MAXSIZE 100        //定义最大储存空间
#define ElemType int        //定义数据类型
#define ERROR 0
#define TRUE 1
#define OVERFLOW -1

using namespace std;

//定义链表
typedef struct LNode *List;
struct LNode{
    ElemType Data;
    List *Next;
};

求一个链表的表长:

int length(List Ptrl){
    List P = Ptrl;    int j = 0;
    while(P){
        P = P->Next;    //指向下一个结点
        j++;        //当前P指向的是第j个节点    
        }
    return j;}

查找第K项:

List FindKth(int K, List Ptrl){
    List P = Ptrl;    int i = 1;    
       while(P != nullptr && i < K){
        P = P->Next;
        i++;
       }
    if(i == K)
        return P;
    else
        return NULL;
}

按值查找:

List Find(ElemType X, List Ptrl){
    List P = Ptrl;    int i = 1;
    while(P != nullptr && P->Data[i] != K){
        P = P->Next;
        i++;
    }
    if(P)
        return ERROR;
    else
        return P;
}

链表的插入:

List Insert(ElemType X,  int i, List Ptrl){    List P, s;
    if(i == 1){        //新结点在第1位
        s = (List)malloc(sizeof(struct LNode));    //也可以这样去申请空间
         s = new(LNode);
        s->Data = X;
        s->Next = Ptrl;
        return s;
    }
    P = FindKth(i-1, Ptrl);    //查找第i-1个结点
    if(P == nullptr){    //第i-1个结点不存在,不能插入
        cout << "error";
        return nullptr;
    }
    else{
        s = (List)malloc(sizeof(struct LNode));
        s->Data = X;
        s->Next = P->Next;        //新结点插在第i-1个结点的后面
        P->Next = s;
        return Ptrl;    
        }
}

链表的删除:

List Delete(int i, List Ptrl){
    List P, s;
    if(i == 1){    //如果删除的是第1个结点
        s = Ptrl;    //s指向第1个结点
        if(Ptrl != nullptr)
            Ptrl = Ptrl->Next;        //从链表中删除
        else
            return nullptr;
        delete s;        //释放被删除结点所申请的空间,防止内存泄漏
        return Ptrl;
    }
    P = FindKth(i-1, Ptrl);    //查找第i-1个结点
    if(P == nullptr){
        cout << "error";
        return NULL;
    }
    else if(P->Next == nullptr){
        cout << "not instance";
         return nullptr;
        }
    else{
        s = P->Next;
        P->Next = s->Next;        //删除结点
        delete s;
        return Ptrl;
    }
}

5、顺式结构和链式结构的优缺点总结

1、顺序存储结构
优点:可以随机访问,在O(1)内查询、修改元素,存储容量高
缺点:在O(n)内插入和删除数据,修改困难,存储空间需要一次性获得,表示关系能力弱
2、链式存储结构
优点:空间任意,便于删改,表示关系的能力强,在O(1)内插入、删除元素
缺点:占用空间较多,必须通过指针来访问元素,在O(n)内查找、修改元素

相关文章
|
7月前
|
存储 C语言
数据结构中的线性表链式存储介绍及其基本操作
链式存储是线性表的一种重要存储方式,它通过节点和指针的结构,实现了灵活的动态存储管理。本文介绍了单向链表的基本操作,并提供了相应的C语言代码示例。理解和掌握链表的操作对学习和应用数据结构具有重要意义。希望这篇博客能帮助你更好地理解线性表的链式存储。
156 2
|
3月前
|
存储 Java
数据结构第二篇【关于java线性表(顺序表)的基本操作】
数据结构第二篇【关于java线性表(顺序表)的基本操作】
51 6
|
3月前
|
存储
【数据结构】线性表和顺序表
【数据结构】线性表和顺序表
32 1
|
2月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之王道第2.3章节之线性表精题汇总二(5)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
IKU达人之数据结构与算法系列学习×单双链表精题详解、数据结构、C++、排序算法、java 、动态规划 你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
7月前
|
算法
数据结构和算法学习记录——线性表之双向链表(上)-结点类型定义、初始化函数、创建新结点函数、尾插函数、打印函数、尾删函数
数据结构和算法学习记录——线性表之双向链表(上)-结点类型定义、初始化函数、创建新结点函数、尾插函数、打印函数、尾删函数
58 0
|
3月前
01(数据结构考研)线性表相关操作代码
01(数据结构考研)线性表相关操作代码
93 0
|
3月前
|
存储 C语言
数据结构之线性表的初始化及其操作
数据结构之线性表的初始化及其操作
52 0
|
4月前
|
存储 Java
java数据结构,线性表顺序存储(数组)的实现
文章介绍了Java中线性表顺序存储(数组)的实现。线性表是数据结构的一种,它使用数组来实现。文章详细描述了线性表的基本操作,如增加、查找、删除、修改元素,以及其他操作如遍历、清空、求长度等。同时,提供了完整的Java代码实现,包括MyList接口和MyLinearList实现类。通过main函数的测试代码,展示了如何使用这些方法操作线性表。
|
7月前
|
存储 测试技术
【数据结构】操作受限的线性表,栈的具体实现
【数据结构】操作受限的线性表,栈的具体实现
75 5
|
7月前
|
存储 测试技术
【数据结构】操作受限的线性表,队列的具体实现
【数据结构】操作受限的线性表,队列的具体实现
57 4
下一篇
开通oss服务