线性表

应用:多项式的表示

什么是线性表

多项式表示问题给出的启示:

  同一个问题可以有不同的表示(存储)方法

  有一类共性问题 : 有序线性序列的租住和管理

“线性表(Linear List)” : 由同类型数据元素构成有序序列的线性结构

  表中元素个数称为线性表的长度

  线性表没有元素时,称为空表

  表起始位置称为表头,表结束位置称为表尾

线性表的抽象数据类型描述

类型名称 : 线性表(List)

数据对象集: 线性表是 n(>=0) 个元素构成的有序序列(a_1, a_2, a_3, ...., a_n)

操作集: 线性表L属于List, 整数i表示位置, 元素X属于ElementType

线性表基本操作主要有:

  List MakeEmpty(): 初始化一个空性表L;

  ElementType FindKth(int K, List L): 根据位序K, 返回相应元素;

  int Find(ElementType X, List L) : 在线性表L中查找X的第一次出现位置;

  void Insert(ElementType X, int i, List L): 在位序i前插入一个新元素X;

  void Delete(int i, List L) : 删除指定位序i的元素;

  int Length(List L) : 返回线性表L的长度n;

线性表的顺序存储实现

  利用数组的连续存储空间顺序存放线性表的各元素

#define MAXSIZE    <............>

typedef struct LNode  *List;

struct LNode{

  ElementType Data[MAXSIZE];

  int Last;

};

struct LNode L;

List PtrL;

  访问下标为i的元素:L.Data[i] 或 PtrL->Data[i]

  线性表的长度: L.Last+1 或PtrL->Last+1

主要操作的实现

初始化(建立空的顺序表)

List MakeEmpty()

{

  List PtrL;

  PtrL = ( List )malloc( sizeof( struct LNode ) );

  PtrL->Last = -1;

  return PtrL;

}

查找

int Find(ElementType K, List PtrL)

{

  int i = 0;

  while( i <= PtrL->Last && PtrL->Data[i] != X)

    i++;

  if( i > PtrL->Last) return -1; //如果没有找到, 返回-1

  else return i;//找到后返回的是存储位置

}

插入(第 i (1 <= i <= n+1)个位置上插入一个值为X的新元素)

这里的要注意的是, 这里的代码是采用的从1开始计数的设计

插入操作的具体实现

需要注意这里的是, 这里的位置是从1开始计数(就是人类默认的第一位置的元素就是第一个,对于计算机中来说,还可以有从0开始计数,普遍的来说,在计算机中大都是从0开始计数的)

void Insert ( ElementType X, int  i, List PtrL)

{

  int j;

  if ( PtrL->Last == MAXSIZE - 1){ //表的空间已满, 不能插入新的元素(这里的MAXSiZE - 1是能插入进去的最后的一个位置, 而MASIZE代表的是表中元素最多的元素个数)

    printf ( " 表满 ");

    return ;

  }

  if ( i < 1 || i > PtrL->Last+2){

/*对于 PtrL->Last 表示的数链表中数组元素的最后一个元素的位置信息(这里的位置信息时采用从0开始计数的),因此要是采用从1开始计数的话,这个位置就是第PtrL->Last + 1 位置上的元素, 但是要插入元素的范围是在(1 <= i <= n+1) 即, 第一位置开始, 到第n + 1位置开始, 因此这里的最后一个位置要插入的位置(第n+1位置)用PtrL->Last表示的话就是PtrL->Last + 2位置,

所以这里判断的i 的范围,就可以很容易的知道这里的范围的含义。*/

    printf ( " 位置不合法 ");

    return;

  }

  for ( j = PtrL->Last; i >= i - 1; j--)

    PtrL->Data[j + 1] = PtrL->Data[j];//将a_i .... a_n 倒序向后移动

  PtrL->Data[i - 1]  = X;//新元素插入

  PtrL->Last++;//Last仍指向最后元素

  return;

}

//插入的另一个版本, 这里采用的计数就是在0开始进行计数的

void  Insert(List L, Elementype X, Position P)

{
    /*在L的指定位置P前插入一个新元素X*/
    Position i;
    
    if(L->Last == MAXSIZE -1)
    {
        /*表空间已满,不能插入*/
        printf("表满");
        return FALSE;
    }

  

    if( P < 0 || P > L->Last + 1){//这里是变化的不同之处,这里的采用的就是从0开始计数判断插入位置的合法性
        //检查插入位置时候合法
        printf("位置不合法");
        return FALSE;
    }
    for( i = L->Last; i >= P; i--)
        L->Data[i+1] = L->Data[i]; //将位置P以及以后位置往后移动
    L->Data[P] = X;//新元素插入
    L->Last++;//Last 仍指向最后一个元素
    return ;
}

删除(删除表的第 i (1 <= i <=n)个位置上的元素)

删除操作的实现 (这里也是有位置计数的为题,下面这个采用的是从第1个位置开始计数的)

void Delete( int i, List PtrL)

{

  int j;

  if ( i < 1 || i > PtrL->Last + 1){

    printf ( "不存在第%d个元素", i);

    return;

  }

  for ( j = i; j <= PtrL->Last; j++)

    PtrL->Data[j - 1] = PtrL->Data[j];//将a_(i+1) ..... a_n顺序向前移动

  PtrL->Last--;//Last仍指向最后元素

  return ;

}

//这里采用的计数位置是从0开始计数的

BOOL Delete(List L, Position P)
{
    //从L 中删除指定位置P的元素
    Position i;
    if ( P < 0 || P > L->Last){
        //检查空表集删除位置的合法性
        printf("位置%d不存在元素",P);
        return FALSE;
    }
    for( i = P + 1; i <= L->Last; i++)
        L->Data[i - 1] = L->Data[i];//将位置P+1及以后的位置往前移
    L->Last--;//last 指向最后一个元素
    return  TRUE;
}

完整测试代码:

/*list_array.c*/

#include <stdio.h>//printf
#include <stdlib.h>//malloc
#define MAXSIZE 2000
#define TRUE 1
#define FALSE 0
#define ERROR -1
typedef int BOOL;
typedef int Elementype;
typedef int Position;
typedef struct LNode* List;
//数组实现链表, 定义的数据结构
struct  LNode{
    Elementype Data[MAXSIZE];
    Position Last;
};
Position Length(List L);
/*init*/
List MakeEmpty()
{
    List L;
    L = (List)malloc(sizeof(struct LNode));
    L->Last = -1;
    return L;
}
/* 查找 */
Position Find(List L, Elementype X)
{
    Position i = 0;
    
    while( i <= L->Last && L->Data[i] != X)
        i++;
    if( i > L->Last){ 
        return ERROR; //如果没有找到,返回错误信息
    }else{
        return i;//找到后返回的是存储位置
    }
}
BOOL Insert(List L, Elementype X, Position P)
{
    /*在L的指定位置P前插入一个新元素X*/
    Position i;
    
    if(L->Last == MAXSIZE -1)
    {
        /*表空间已满,不能插入*/
        printf("表满");
        return FALSE;
    }
    if( P < 0 || P > L->Last + 1){
        //检查插入位置时候合法
        printf("位置不合法");
        return FALSE;
    }
    for( i = L->Last; i >= P; i--)
        L->Data[i+1] = L->Data[i]; //将位置P以及以后位置往后移动
    L->Data[P] = X;//新元素插入
    L->Last++;//Last 仍指向最后一个元素
    return TRUE;
}
BOOL Delete(List L, Position P)
{
    //从L 中删除指定位置P的元素
    Position i;
    if ( P < 0 || P > L->Last){
        //检查空表集删除位置的合法性
        printf("位置%d不存在元素",P);
        return FALSE;
    }
    for( i = P + 1; i <= L->Last; i++)
        L->Data[i - 1] = L->Data[i];//将位置P+1及以后的位置往前移
    L->Last--;//last 指向最后一个元素
    return  TRUE;
}
void PrintList(List L)
{
    Position i;
    for(i = 0; i < Length(L); i++)
        printf("%d ", L->Data[i]);
    printf("\n");
}
Position Length(List L)
{
    return L->Last + 1;
}
Elementype getElement(List L, Position P)
{
    return L->Data[P];
}
int main()
{
    List list;
    list = MakeEmpty();
    Position index = 0;
    for(int i = 10; i >= 0; i--)
    {
        if(Insert(list,i,index)){
            printf("    insert success\n");
        }else{
            printf("    insert failed\n");
        }
        index++;
    }
    PrintList(list);
    printf("this list length : %d\n", Length(list));
    printf("the positon 2 is : %d \n", getElement(list, 10));
    return 0;    
}

编译运行:

  gcc list_array.c
  ./a.exe
打印结果:

insert success
insert success
insert success
insert success
insert success
insert success
insert success
insert success
insert success
insert success
insert success
10 9 8 7 6 5 4 3 2 1 0
this list length : 11
the positon 2 is : 0

——————————————————————————————————线性表的顺序存储———————————————————————————————————

 

DataStructure之线性表以及其实现的更多相关文章

  1. C#实现数据结构——线性表(下)

    线性表链式存储结构 看了线性表的顺序存储,你肯定想线性表简是挺简单,但是我一开始怎么会知道有多少人排队?要分配多大的数组?而且插入和删除一个元素也太麻烦了,所有元素都要前移/后移,效率又低. 那怎么办 ...

  2. 线性表的顺序存储结构之顺序表类的实现_Java

    在上一篇博文——线性表接口的实现_Java中,我们实现了线性表的接口,今天让我们来实现线性表的顺序存储结构——顺序表类. 首先让我们来看下顺序表的定义: 线性表的顺序存储是用一组连续的内存单元依次存放 ...

  3. 线性表接口的实现_Java

    线性表是其组成元素间具有线性关系的一种线性结构,对线性表的基本操作主要有插入.删除.查找.替换等,这些操作可以在线性表的任何位置进行.线性表可以采用顺序存储结构和链式存储结构表示. 本接口的类属于da ...

  4. 线性表Linearlist

    顺序存储,链式存储,索引存储,散列存储 基本运算 SLIST         1.置空表 void SetNull(&L)     2.求长度 int Length(L)     3.取元素 ...

  5. 数据结构(Java描述)之线性表

    基础概念 数据结构:是相互之间存在一种或多种关系的数据元素的集合. 逻辑结构和物理结构 关于数据结构,我们可以从逻辑结构和物理结构这两个维度去描述 逻辑结构是数据对象中数据元素之间的关系,是从逻辑意义 ...

  6. JAVASE02-Unit04: 集合框架 、 集合操作 —— 线性表

    Unit04: 集合框架 . 集合操作 -- 线性表 操作集合元素相关方法 package day04; import java.util.ArrayList; import java.util.Co ...

  7. 数据结构代码整理(线性表,栈,队列,串,二叉树,图的建立和遍历stl,最小生成树prim算法)。。持续更新中。。。

    //归并排序递归方法实现 #include <iostream> #include <cstdio> using namespace std; #define maxn 100 ...

  8. Java集合类学习笔记(各种线性表性能分析)

    ArrayList.LinkedList是线性表的两种典型实现:基于数组的线性表和基于链的线性表. Queue代表了队列,Deque代表了双端队列. 一般来说,由于数组以一块连续内存区来保存所有的数组 ...

  9. 动态分配的顺序线性表的十五种操作—C语言实现

    线性表 定义:是最常用的,也是最简单的数据结构,是长度为n个数据元素的有序的序列. 含有大量记录的线性表叫文件 记录:稍微复杂的线性表里,数据元素为若干个数据项组成,这时把一个数据元素叫记录 结构特点 ...

随机推荐

  1. 连接池你用对了吗?一次Unexpected end of stream异常的排查

    能收获什么? 更加了解TCP协议 Redis与客户端关闭连接的机制 基于Apache Common连接池的参数调优 Linux网络抓包 情况简介 近期迁移了部分应用到K8s中,业务开发人员反馈说,会发 ...

  2. 固定定位下的div水平居中

    发现了一个之前未留意的知识点,做个笔记. 当一个块级元素的父元素开启了flex布局后,我们可以很轻松的将这个元素居中对齐,可以在父元素上加 justify-content: center; align ...

  3. Visual Studio Code编写C/C++代码常见问题

    我会把一些常见问题以及自己编写代码过程中遇到的问题以及解决方案放在这里,各位若是遇到的问题也可以在评论区留言. 一.头文件Error 不会影响编译运行,但会报Warm,如下图 解决方案是安装Inclu ...

  4. 模板引擎Velocity学习系列-#set指令

    #set指令 #set指令用于向一个变量或者对象赋值. 格式: #set($var = value) LHS是一个变量,不要使用特殊字符例如英文句号等,不能用大括号括起来.测试发现#set($user ...

  5. (七十)c#Winform自定义控件-饼状图

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  6. ASP.NET Core 3.0 : 二十五. TagHelper

    什么是TagHelper?这是ASP.NET Core 中新出现的一个名词,它的作用是使服务器端代码可以在Razor 文件中参与创建和呈现HTML 元素.(ASP.NET Core 系列目录) 一.概 ...

  7. [Pandas] 01 - A guy based on NumPy

    主要搞明白NumPy“为什么快”. 学习资源 Panda 中文 易百教程 远程登录Jupyter笔记本 效率进化 四步效率优化 NumPy 底层进行了不错的优化. %timeit 对于任意语句,它会自 ...

  8. 【linux】【redis】redis安装及开启远程访问

    系统环境:Centos7 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 1.yum安装过程参考:https ...

  9. Java基础之final、static关键字

    一.前言 关于这两个关键字,应该是在开发工作中比较常见的,使用频率上来说也比较高.接口中.常量.静态方法等等.但是,使用频繁却不代表一定是能够清晰明白的了解,能说出个子丑演卯来.下面,对这两个关键字的 ...

  10. .ssh/config 文件的解释算法及配置原则

    前言 SSH 是连接远程主机最常用的方式,尽管连接到耽搁主机的基本操作非常直接,但当你开始使用大量的远程系统时,这就会成为笨重和复杂的任务. 幸运的是,OpenSSH 允许您提供自定义的客户端连接选项 ...