线性表(一)——顺序表

在前一篇文章中我们讲解了线性表的定义以及线性表的特性,知道了线性表的两种存储结构:一种是顺序存储结构,一中是链式存储结构。本文将分析讨论线性表顺序存储结构的实现。

线性表-概述
线性表(一)——顺序表
线性表(二)——单链表的表示和实现
线性表(三)——双向链表的表示和实现

1、顺序表的存储结构

顺序表是线性表中的一种,顺序存储结构的线性表称作顺序表。实现顺序存储结构的方式是使用数组。数组把线性表的数据元素存储在一块连续地址空间的内存单元中,这样线性表中逻辑相邻的数据元素在物理存储地址上也是相邻的。数组有静态数组和动态数组两种,不同之处在于前者的存储空间的申请和释放是由系统自动完成的,后者的存储空间的申请和释放是由用户通过调用系统函数自己完成的。不管是静态数组还是动态数组,其功能都是向系统申请一块连续地址的有限空间,只是申请空间的方式不同而已。本文主要讨论静态数组方法实现的顺序表。
如下图所示是顺序表的存储结构示意图。其中a_0,a_1,a_2,···a_{MaxSize-1}表示顺序表中存储的数据元素,list表示用于存储顺序表数据元素的数组,MaxSize表示数组list的最大存储个数,size表示顺序表当前存储数据元素的个数。

用C语言描述上图所示的结构,定义如下:

typedef struct {
    DateType list[MaxSize];
    int size;
}SeqList;

其中DateType表示数据元素的数据类型,MaxSize表示数组的最大容量,list表示顺序表的数组成员,size表示顺序表中当前存储的数据元素的个数,且必须满足size\leqMaxSize。

2、顺序表的操作实现

2.1 初始化ListInitiate(L)

/*初始化列表*/
void ListInitiate(SeqList *L) {
    L->size = 0;
}

2.2 获取顺序表长度ListLength(L)

/*获取列表的长度*/
int ListLength(SeqList L) {
    return L.size;
}

2.3 插入数据ListInsert(L,index,x)

在顺序表L的第index(0\leq index \leq size)个位置前插入数据元素值x,插入成功返回1,插入失败返回0。

/*
 * 插入元素
 * */
int ListInsert(SeqList *L, int index, DataType x) {
    if (L->size >= MaxSize) {
        printf("顺序表结构数据已满");
        return 0;
    } else if (index < 0 || index > L->size) {
        printf("插入数据的位置不合法");
        return 0;
    } else {
//        从后向前依次后移数据,为插入数据做准备
        for (int i = L->size; i > index; i--) {
            L->list[i] = L->list[i - 1];
        }
        L->list[index] = x;//插入x
        L->size++;//元素的个数添加1
        return 1;
    }
}

从上面的程序看,在index正确的前提下,首先把存储单元size-1至存储单元为index中的数据元素依次后移,然后把数据元素x插入到存储单元index中,最后把数据元素个数加1。这个操作称做是前插入,即在顺序表的第index个位置前插入数据元素,还可以有后插入操作,即在顺序表的第index个位置后插入数据元素。

2.4 删除数据ListDelete(L,index,x)

删除顺序表L的第index(0\leq index \leq size-1)个位置上的数据元素并保存到x中,删除成功返回1,删除失败返回0。

int ListDelete(SeqLsit *L, int index, DataType *x) {

    if (L->size <= 0) {
        printf("顺序表中已经没有可以删除的元素");
        return 0;
    } else if (index < 0 || index > L->size - 1) {
        printf("删除数据的位置不合法");
        return 0;
    } else {
        *x = L->list[index];
        for (int i = index + 1; i <= L->size - 1; i++) {
            L->list[i - 1] = L->list[I];
        }
        L->size--;
        return 1;
    }
}

当顺序表非空且参数index正确时,首先把存储单元index中的数据元素存放到x中,然后从前向后依次千亿从存储位置index到存储位置size-1中的数据元素,最后把数据元素个数减1。

2.5 取数据元素ListGet(L,index,x)

取顺序表L中第index个数据元素存与x中,成功返回1,失败返回0。

int ListGet(SeqLsit *L, int index, DataType *x) {
    if (index < 0 || index > L->size - 1) {
        printf("数据的位置不合法");
        return 0;
    } else {
        *x = L->list[index];
        return 1;
    }
}

2、顺序表的操作效率

从上面的分析来看,顺序表的插入和删除是顺序表中时间复杂度最高的操作。在顺序表中插入一个数据元素时,算法中时间复杂度最高的操作是循环移动数据元素。循环移动数据元素的效率和插入数据元素位置i有关,最坏情况是i=0,需移动size个数据元素;最好的情况是i=size,需要移动0个数据元素。设P_i是在第i个位置插入一个数据元素的概率,设顺序表中的数据元素个数为n,当顺序表的任何位置上插入数据元素的概率相等时,有P_i=1/(n+1),则像顺序表插入一个数据元素需要移动的数据元素的平均次数为:
E_{is} = \sum\limits_{i=0}^n P_{i}(n-i) = \frac{1}{n+1} \sum\limits_{i=0}^n (n-i) = \frac{n}{2}

从顺序表中删除一个数据元素时,算法中时间复杂度最高的操作也是循环移动数据元素。循环移动数据元素的效率与删除数据元素的位置i有关,最坏的情况是i=0,需要移动size-1个数据元素;最好的情况是i=size,需要移动0个数据元素。设q_i是删除第i个位置数据元素的概率,设顺序表的数据元素个数为n,当删除顺序表任何位置上数据元素的概率相等时,有q_i=1/n,则删除顺序表任意位置数据元素所需要移动数据元素的平均次数为:
E_{dl} = \sum\limits_{i=0}^{n-1} q_{i}(n-i) = \frac{1}{n} \sum\limits_{i=0}^{n-1} (n-i) = \frac{n-1}{2}

根据上面的分析可知,在顺序表中插入和删除一个数据元素的平均时间复杂度为O(n)
顺序表的其他操作与数据元素的个数n无关,所以顺序表的查询元素和获取元素的时间复杂度为O(1)
顺序表的主要优点是:算法简单,内存单元利用率较高。主要缺点是:需要预先确定数据元素的最大个数。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容