数据结构与算法基础 之线性表(一)


 
 

前言

  线性表有两种物理存储结构:顺序存储结构和链式存储结构,现在了解一下顺序存储结构。

 

一、顺序线性表

线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。顺序存储结构封装需要三个属性:

  • 存储空间的起始位置,数组data,它的存储位置就是线性表存储空间的存储位置。
  • 线性表的最大存储容量:数组的长度MaxSize。
  • 线性表的当前长度:length。

 

二、代码实例

linearlist.h

#ifndef __LINEAR_LIST_
#define __LINEAR_LIST_
  
#define MAX_SIZE 100 
 
typedef int ElemType;
 
typedef struct _sqList {
    ElemType data[MAX_SIZE];  
    int length;      
}sqList_s, *sqList_p;
  
int initList(sqList_s **list);
int isFullList(sqList_p list);
int isEmptyList(sqList_p list);
int lengthList(sqList_p list);
int addListOfTail(sqList_p list, ElemType value);
int addList(sqList_p list, ElemType value, int i);
int getElemList(sqList_p list, int i, ElemType *e);
int deleteList(sqList_p list, int i, ElemType *e);
int clearList(sqList_p list); 
 
 
#endif

linearlist.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linearlist.h"
 
int initList(sqList_s **list)
{
    *list = (sqList_s *)malloc(sizeof(sqList_s));
    if (NULL == *list) {
         perror("malloc error");
         return -1;
     }
  
     memset((*list)->data, 0, MAX_SIZE);
     (*list)->length = 0;
  
     return 0;
}
 
int isFullList(sqList_p list)
{
    return list->length == (MAX_SIZE - 1);
}
 
int isEmptyList(sqList_p list)
{
    return list->length == 0;
}
 
int lengthList(sqList_p list)
{
    return list->length;
}
 
int addListOfTail(sqList_p list, ElemType value)
{
    if (list == NULL)
        return -1;
 
    if (isFullList(list))
        return -1;
 
    list->data[list->length ++] = value;
 
    return 0;
}
 
int addList(sqList_p list, ElemType value, int i)
{
    int k;
 
    if (list == NULL)
        return -1;
 
    if (isFullList(list))
        return -1;
 
    for(k = list->length - 1 ; k >= i; k --)
        list->data[k + 1] = list->data[k];
 
    list->data[i] = value;
    list->length ++;
 
    return 0;
}
 
int getElemList(sqList_p list, int i, ElemType *e)
{
    if (NULL == list || i < 0 || i > list->length)
        return -1;
 
    *e = list->data[i];
 
    return 0;
}
  
int printfList(sqList_p list)
{   
    int i;
     
    for (i = 0; i < list->length; i++)
        printf("%d\t", list->data[i]);
     
    printf("\n");
     
    return 0;
}
 
#if 1
/*测试*/
int main()
{   
    int i;
    ElemType e ; 
    sqList_p l = NULL ;
     
    initList(&l);
     
    printf("It is empty?  %s\n", (isEmptyList(l) ? "yes" : "no"));
    for(i = 0; i < MAX_SIZE - 5; i++)
        addListOfTail(l, i);
     
    printf("It is full?  %s\n", isFullList(l)==1 ? "yes" : "no");
     
    getElemList(l, 18, &e);
    printf("list[18] is %d\n", e);
     
    printf("length: %d\n", lengthList(l));
    printfList(l);
    addListOfTail(l, 100); 
    printf("length: %d\n", lengthList(l));
    printfList(l); 
    addList(l, 99, 4);
    printf("length: %d\n", lengthList(l));
    printfList(l);
 
    deleteList(l, 5, &e);
    printf("value: %d  length: %d\n", e, lengthList(l));
    printfList(l); 
    freeList(l);
    return 0;
}
 
#endif

 

三、分析

现在我们分析一下,插入和删除的时间复杂度:

  • 最好的情况:插入和删除操作刚好要求在最后一个位置操作,因为不需要移动任何元素,所以此时的时间复杂度为O(1)。
  • 最坏的情况:如果要插入和删除的位置是第一个元素,那就意味着要移动所有的元素向后或者向前,所以这个时间复杂度为O(n)。
  • 至于平均情况,就取中间值O((n-1)/2)。 按照前边游戏秘籍指导,平均情况复杂度简化后还是O(n)。

线性表顺序存储结构的优缺点:
  线性表的顺序存储结构,在存、读数据时,不管是哪个位置,时间复杂度都是O(1)。而在插入或删除时,时间复杂度都是O(n)。这就说明,它比较适合元素个数比较稳定,不经常插入和删除元素,而更多的操作是存取数据的应用。

 

四、总结

那我们接下来给大家简单总结下线性表的顺序存储结构的优缺点:
优点:

  • 无须为表示表中元素之间的逻辑关系而增加额外的存储空间。
  • 可以快速地存取表中任意位置的元素。

缺点:

  • 插入和删除操作需要移动大量元素。
  • 当线性表长度变化较大时,难以确定存储空间的容量。
  • 容易造成存储空间的“碎片”。

 
 
 
 
 
 
 
关注公众号"小败日记",搬砖过程遇到的问题,大家一起探讨,资源共享

小败日记公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值