线性表的定义和基本操作

这篇具有很好参考价值的文章主要介绍了线性表的定义和基本操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

线性表的定义和基本操作

一、线性表的定义

线性表(Linear List)是具有相同数据类型的n(n>=0)个数据元素的有限序列,其中n为表长,当n=0时线性表是一个空表。若用L命名线性表,则其一般表示为

L = (a1,a2,...,ai,ai+1,...,an)

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

a1是表头元素;an是表尾元素。

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

二、线性表的基本操作

InitList(&L):初始化表。构造一个空的线性表L,分配内存空间。

DestroyList(&L):销毁操作。销毁线性表,并释放线性表L所占有的内存空间。

ListInsert(&L,i,e):插入操作。在表L中的第i个位序(位置)上插入制定元素e。

ListDelete(&L,i,&e):删除操作。删除表L中第i个位序(位置)的元素,并用e返回删除元素的值。

LocateElem(L,e):按值查找操作。在表L中查找具体给定关键字值的元素。

GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值。

其他常用操作:

Length(L):求表长操作。返回线性表L的长度,即L中数据元素的个数。

PrinList(L):输出操作。按前后顺序输出线性表L的所有元素值。

Empty(L):判空操作。若L为空表,则返回true,否则返回false。

Tips:

对数据的操作(记忆思路)——创(Init)销(Destroy)、增(Insert)删(Delete)改(Alter)查(Query)

C语言函数的定义

实际开发中,可根据实际需求定义其他的基本操作

函数名和参数的形式、命令都可改变

什么时候需要传入“&”——对参数的修改结果需要“带回来”

三、初始化代码实践

1、顺序表静态分配
#include <stdio.h>
// 顺序表存储空间静态分配
#define MaxSize 10      // 定义最大长度
typedef int ElemType;   // int类型重命名为ElemType,方便后续调整
typedef struct{         // 定义结构体
    ElemType data[MaxSize];         // 用静态的数组存放数据元素
    ElemType length;                // 数组长度
}SqList;
void InitList(SqList &L){           // 初始化顺序表
    L.length=0;                     // 长度赋值,没有设置数据元素的默认值
}
int main() {
    SqList L;           // 声明一个顺序表
    InitList(L);    // 初始化顺序表
    for (int i = 0; i < MaxSize; i++) {
        // 尝试违规打印整个data数组
        printf("data[%d]=%d\n", i, L.data[i]);
    }
    return 0;
}

线性表的定义和基本操作,408数据结构,算法,c++,数据结构

#include <stdio.h>
// 顺序表存储空间静态分配
#define MaxSize 10      // 定义最大长度
typedef int ElemType;   // int类型重命名为ElemType,方便后续调整
typedef struct{         // 定义结构体
    ElemType data[MaxSize];         // 用静态的数组存放数据元素
    ElemType length;                // 数组长度
}SqList;
void InitList(SqList &L){          // 初始化顺序表
    for(int i=0;i<MaxSize;i++){    // 设置数据元素的默认值,否则内存中会有遗留的“脏数据”
        L.data[i]=0;
    }
    L.length=0;                     // 长度赋值,没有设置数据元素的默认值
}
int main() {
    SqList L;           // 声明一个顺序表
    InitList(L);    // 初始化顺序表
    for (int i = 0; i < L.length; i++) {    //按照数据长度进行打印
        // 尝试违规打印整个data数组
        printf("data[%d]=%d\n", i, L.data[i]);
    }
    return 0;
}
2、顺序表动态分配
#include <stdio.h>
#include <stdlib.h>
// 顺序表存储空间动态分配
#define InitSize 10      // 顺序表初始长度
typedef int ElemType;   // int类型重命名为ElemType,方便后续调整
typedef struct{         // 定义结构体
    ElemType *data;     // 用静态的数组存放数据元素
    ElemType MaxSize;   // 顺序表最大容量
    ElemType length;    // 顺序表数据长度
}SqList;
void InitList(SqList &L){           // 初始化顺序表
    // 用malloc函数申请一片连续的存储空间
    L.data = (ElemType *) malloc(InitSize * sizeof(ElemType));
    L.MaxSize = InitSize;
    L.length = 0;
}
void IncreaseSize(SqList &L, ElemType len){
    ElemType *p=L.data;
    L.data = (int *) malloc((L.MaxSize + len) * sizeof(ElemType));
    for (ElemType i = 0; i < L.length; i++) {
        L.data[i]=p[i];     // 将数据复制到新区域
    }
    L.MaxSize=L.MaxSize+len;    // 顺序表最大长度增加len
    free(p);            // 释放原来的内存空间
}
int main() {
    SqList L;           // 声明一个顺序表
    InitList(L);    // 初始化顺序表
    IncreaseSize(L, 5);
    return 0;
}
3、特点

随机访问:即可以在O(1)时间内找到第i个元素。

存储密度高:每个节点只存储数据元素。

扩展容量不方便:即便采取动态分配的方式实现,拓展长度的时间复杂度也比较高。

插入、删除操作不方便:需要移动大量的元素。

四、插入和删除

1、顺序表插入实践
#include <stdio.h>

#define MaxSize 10      // 指定大小
typedef int ElemType;
typedef struct{
    ElemType data[MaxSize];
    ElemType length;
}SqList;

bool InsertList(SqList &L, ElemType position, ElemType element){
    if (position < 1 || position > L.length + 1) {      // 判断插入是否合理
        return false;
    }
    if (L.length >= MaxSize) {          // 判断插入是否合理
        return false;
    }
    for (ElemType i = L.length; i >= position; i--) {   // 循环从最后一位开始,到插入的位序,减减
        L.data[i] = L.data[i-1];        // 将前一位值向后移一位
    }
    L.data[position-1] = element;       // 插入的位置附上要插入的值,注意数组下标和位序是相差一位的
    L.length++;                         // 插入一个元素之后,数组的长度是要加1
    return true;
}

void PrintList(SqList L){
    for (ElemType i = 0; i < L.length; i++) {
        printf("data[%d]=%d\n",i,L.data[i]);
    }
}
int main() {
    SqList L;   // 初始化
    for (ElemType i = 0; i < 6; i++) {      // 数组赋值
        L.data[i]=i*2;
    }
    L.length=6;
    bool ret;
    ret = InsertList(L, 6, 20); // 调用插入
    if (ret) {          // 判断是否正常插入
        printf("insert element success\n");
        PrintList(L);
    } else {
        printf("insert element failed\n");
    }
    return 0;
}

线性表的定义和基本操作,408数据结构,算法,c++,数据结构

插入操作的时间复杂度

最好情况:新元素插入到表尾,按照以上例子为插入位序为6的位置,不需要移动元素,循环0次,最好时间复杂度=O(1)

最坏情况:新元素插入到表头,需要将原有的n个元素全部都向后移动,循环n次,最坏时间复杂度=O(n)

平均情况:假设新元素插入到任何一个位置的概率相同,即i=1,2,3,…,length+1的概率都是
p = 1 n + 1 p=\frac{1}{n+1} p=n+11
i=1,循环n次,i=2,循环n-1,…,i=n+1,循环0次
平均循环次数 = n p + ( n − 1 ) p − ( n − 2 ) p + . . . + 1. p = n ( n + 1 ) 2 ⋅ 1 n + 1 = n 2 平均循环次数=np+(n-1)p-(n-2)p+...+1.p=\frac{n(n+1)}{2}·\frac{1}{n+1}=\frac{n}{2} 平均循环次数=np+(n1)p(n2)p+...+1.p=2n(n+1)n+11=2n
平均时间复杂度=O(n)

2、顺序表删除实践
#include <stdio.h>

#define MaxSize 10      // 指定大小
typedef int ElemType;
typedef struct{
    ElemType data[MaxSize];
    ElemType length;
}SqList;

bool DeleteList(SqList &L, ElemType position, ElemType &element){
    if (position < 1 || position > L.length + 1) {      // 判断删除是否合理
        return false;
    }
    element = L.data[position-1];       // 删除的数据,注意数组的下标和位序的关系
    for (ElemType i = position; i <L.length; i++) {   // 循环从要删除的位序开始,结束条件为到数组长度减一位的位置
        L.data[i-1] = L.data[i];        // 将删除位序的值向前移动
    }
    L.length--;                         // 删除一个元素之后,数组的长度是要减1
    return true;
}

void PrintList(SqList L){
    for (ElemType i = 0; i < L.length; i++) {
        printf("data[%d]=%d\n",i,L.data[i]);
    }
}
int main() {
    SqList L;   // 初始化
    for (ElemType i = 0; i < 6; i++) {      // 数组赋值
        L.data[i]=i*2;
    }
    L.length=6;
    ElemType num;
    bool ret;
    ret = DeleteList(L, 2, num); // 调用插入
    if (ret) {          // 判断是否正常插入
        printf("delete element success!delete element is %d\n",num);
        PrintList(L);
    } else {
        printf("insert element failed\n");
    }
    return 0;
}

线性表的定义和基本操作,408数据结构,算法,c++,数据结构

最好情况:删除表尾元素,不需要移动元素,循环0次,最好时间复杂度=O(1)

最坏情况:删除表头元素,需要将后续n-1个元素全部向前移动,循环n-1次,最坏时间复杂度=O(n)

平均情况:假设删除任何一个元素的概率相同,即i=1,2,3,…,length+1的概率都是
p = 1 n p=\frac{1}{n} p=n1
i=1,循环n-1次,i=2,循环n-2,…,i=n,循环0次
平均循环次数 = ( n − 1 ) p − ( n − 2 ) p + . . . + 1. p = n ( n − 1 ) 2 ⋅ 1 n = n − 1 2 平均循环次数=(n-1)p-(n-2)p+...+1.p=\frac{n(n-1)}{2}·\frac{1}{n}=\frac{n-1}{2} 平均循环次数=(n1)p(n2)p+...+1.p=2n(n1)n1=2n1
平均时间复杂度=O(n)

3、顺序表查询实践
#include <stdio.h>

// 静态分配
#define MaxSize 10		// 定义最大长度

typedef int Element;

typedef struct{
    Element data[MaxSize];		// 用静态的“数组”存放数据元素
    int length;
}SqList;
	
int GetList(SqList L,int position){		// 查询该位序的值
    return L.data[position - 1];		// 位序和数组下标少一位
}

int LocateList(SqList L,int num){		// 查询值在数据哪个位序
    for (int i = 0; i < L.length; i++) {
        if (L.data[i] == num) {
            return i+1;					// 返回位序和数组下标相差一位
        }
    }
}
int main() {
    SqList L;
    for (int i = 0; i < 5; i++) {
        L.data[i] = i*2;
    }
    L.length=5;
    int ret;
    ret = GetList(L, 3);
    printf("Get List num is %d\n", ret);

    ret = LocateList(L,4);
    printf("Locate List position is %d\n", ret);
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
// 动态分配
#define InitSize 10

typedef int Element;

typedef struct{
    Element *data;
    int MaxSize;
    int length;
}SqList;

void InitList(SqList &L){               // 初始化
    L.data = (int *) malloc(InitSize*sizeof(int));
    L.MaxSize = InitSize;
    L.length = 0;
}

int GetList(SqList L,int position){		// 查询该位序的值
    return L.data[position - 1];		// 位序和数组下标少一位
}

int LocateList(SqList L,int num){		// 查询值在数据哪个位序
    for (int i = 0; i < L.length; i++) {
        if (L.data[i] == num) {
            return i+1;					// 返回位序和数组下标相差一位
        }
    }
}
int main() {
    SqList L;
    InitList(L);
    for (int i = 0; i < 5; i++) {
        L.data[i] = i*2;
    }
    L.length=5;
    int ret;
    ret = GetList(L, 3);
    printf("Get List num is %d\n", ret);

    ret = LocateList(L,4);
    printf("Locate List position is %d\n", ret);
    return 0;
}

时间复杂度:

按位查找:O(1)

按值查找:最好时间复杂度:O(1),在第一个位置

​ 最坏时间复杂度:O(n),在最后一个位置

​ 平均时间复杂度:O(n),目标元素在每个位置的概率相同
O = ( 1 + 2 + . . . + n ) 1 n = n ( n + 1 ) 2 ⋅ 1 n = n + 1 2 = O ( n ) O=(1+2+...+n)\frac{1}{n}=\frac{n(n+1)}{2}·\frac{1}{n}=\frac{n+1}{2}=O(n) O=(1+2+...+n)n1=2n(n+1)n1=2n+1=O(n)文章来源地址https://www.toymoban.com/news/detail-735069.html

到了这里,关于线性表的定义和基本操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构-线性表的顺序表基本操作代码实现(超级详细清晰 C++实现)

    顺序表是用一段 物理地址连续的存储单元 依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。 顺序表: 可动态增长的数组,要求数据是连续存储的 特点: 随机访问 顺序既可以 静态分配 ,也可以 动态分配 。在静态分配时,由于数组

    2024年02月07日
    浏览(56)
  • 【玩转408数据结构】线性表——单链表的定义以及增删改查(线性表的链式表示 上)

            到这里我们已经了解到线性表是具有 相同数据类型 的 有限个数据元素 序列,而线性表的顺序存储也就是顺序表,顺序表的存储形式十分直观,我们在实现时使用数组进行实现,但顺序表在插入或者删除元素时需要移动大量元素,那么怎么样才能在插入删除元素时不

    2024年02月21日
    浏览(57)
  • 【数据结构】单链表——单链表的定义及基本操作的实现(头插、尾插、头删、尾删、任意位置的插入与删除)

    🧑‍💻作者: @情话0.0 📝专栏:《数据结构》 👦个人简介:一名双非编程菜鸟,在这里分享自己的编程学习笔记,欢迎大家的指正与点赞,谢谢!   顺序表可以随时存取表中的任意一个元素,它的存储位置可以用一个简单直观的公式表示,但是插入和删除操作需要移动

    2024年02月19日
    浏览(205)
  • 数据结构上机练习——单链表的基本操作、头文件、类定义、main函数、多种链表算法的实现,含注释

      头文件和源文件分开有很多好处:可以提高编译速度、提高代码的可维护性、提高代码的可重用性和可扩展性,同时也可以使代码结构更清晰,方便代码的管理和维护。 LinkList.h test.cpp                  (下面所有函数都默认在类中实现)   我们以

    2024年02月07日
    浏览(58)
  • 线性表的基本操作(初始化、创建、增、删、查)

    目录 顺序表 顺序表的定义和初始化 顺序表的基本操作 1.求表长 2.判空操作 3.创建顺序表 4.输出操作 5.插入操作 6.删除操作 7.按位查找操作 8.按值查找操作 单链表 单链表的定义 单链表的初始化 求表长 判空操作  尾插法建立单链表 头插法建立单链表 输出操作 前插操作 后插

    2024年02月08日
    浏览(45)
  • 数据结构---双向链表的基本操作

    头插法 遍历链表 尾插法 头删法 尾删法 按位置插入数据 按位置删除数据 dooublelinklist.c doublelinklist.h doublemain.c

    2024年02月22日
    浏览(53)
  • 【数据结构】——单链表的基本操作(带头结点)

            单链表解决了顺序表需要大量连续存储单元的缺点,但单链表附加指针域, 存储密度较顺序表低(考点!!) 。由于单链表的元素离散地分布在存储空间中,所以单链表是 非随机存取 的存储结构,即不能直接找到表中某个特定的结点。当查找某个特定结点时,需要

    2024年02月05日
    浏览(52)
  • 线性表的基本操作及在顺序存储及链式存储的实现

    一个数据结构的基本操作是指其最核心、最基本的操作。其他较复杂的操作可通过其基本操作来实现。线性表的主要操作如下 注意:1:基本操作的实现取决于采用哪种存储结构,存储结构不同,算法的实现也不同 2:“” 表示c++中的引用调用。若存入的变量是指针变量,且

    2024年02月13日
    浏览(43)
  • 【数据结构】C语言实现双链表的基本操作

    大家好,很高兴又和大家见面啦!!! 经过前面几个篇章的内容分享,相信大家对顺序表和单链表的基本操作都已经熟练掌握了。今天咱们将继续分享线性表的链式存储的第二种形式——双链表。在今天的内容中,咱们将介绍双链表的创建以及一些基本操作,接下来跟我一起

    2024年02月04日
    浏览(63)
  • 【数据结构】单链表的基本操作 (C语言版)

    目录 一、单链表 1、单链表的定义: 2、单链表的优缺点: 二、单链表的基本操作算法(C语言) 1、宏定义 2、创建结构体 3、初始化 4、插入 4、求长度 5、清空 6、销毁  7、取值 8、查找 9、删除 10、头插法创建单链表 11、尾插法创建单链表 三、单链表的全部代码(C语言)

    2024年01月22日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包