• 线性表的基础(一)


    线性表的存储结构分为:顺序表和链表

    今天我们先介绍顺序表:

    线性表的顺序存储是指在内存中用地址连续的一块存储空间顺序存放线性表的各个元素,用这种存储方式存储的线性表也称为顺序表。

    因为用连续的一块存储空间来存放,所以用数组 datatype data [MAXSIZE] 来存储,其中MAXSIZE是一个根据实际问题定义的足够大的整数。

    顺序表的初始化:

    SeqList*init-SeqList()

    {   SeqList *L;

         L= (SeqList*)malloc(sizeof(SeqList)); //  L为指针变量,通过此操作获得顺序表的存储空间

         L->last = -1;//last起一个指针的作用,始终指向线性表中最后一个元素的位置,所以当表空时last的值为-1

         return L;

    }

    设调用函数为主函数,主函数对初始化函数的调用如下

    main()

    {

     SeqList*L;

     L= Init-SeqList();

    ...

    }

    当然在初始化之前要将指针last 和 数据存储区data封装成一个结构体作为顺序表的类型:

    typedef struct

    {

         datatype data [MAXSIZE];

          int last;

    }SeqList;

    所以也就容易知道

    线性表的表长表示为:(*L).last+1,记为:L->last+1。

    线性表中数据元素顺序存储的基址为:L->data。

    线性表中数据元素的存储或表示为:L->data[0]] ~ L->data[L->last]。

    线性表的插入

    线性表的插入是指在表的第i个位置插入一个值为x的新元素,插入后使原表长为n的表成为表长为n+1条

    顺序表上完成这一操作需要以下步骤。

    1.将a[i]~a[n]顺序向下移动,为新元素让出位置。

    2.将x置入空出的第i个位置。

    3.修改last指针(相当于修改表长),使之仍指向最后一个元素。

    下面是算法:

    int Insert-SeqList(SeqList*L,int i,datatape x)

    {

    int j;

    if(L->last == MAXSIZE -1)

    {   printf("表满");

         return (-1);      //表空间已满不能插入

    }

    if(i<1 || i> L->last + 2)

    {  printf("位置错");

       return(0);

    }

    for(j=L->last;j>=i-1;j--)

    L->data[j+1] = L->data[j];    //结点移动

    L->data[i-1]=x;                    //新元素插入

    L->last++;                           //last 仍指向最后元素 ,修改表长

    return(1);

    }

    性能分析:顺序表的插入运算,时间组要消耗在了数据的移动上,在第i个位置上插入,从a[i]~a[n]都要向后移动一个位置,也就一共需要移动n-i+1个元素,而 i>= 1 && i<=n+1 所以平均下来就移动了 n/2次,时间复杂度为O(n)。

    本算法注意以下问题。

    1.顺序表的存储区域有MAXSIZE个存储单元,所以在向顺序表中做插入时先检查表的空间是否满了,在表满的情况下做插入会产生溢出错误。

    2.检验插入位置的有效性,这里i的有效范围是:i>= 1 && i<=n+1 ,其中n为表长。

    3.注意数据移动的方向。

    线性表的删除

    线性表的删除运算是指将表中第i个元素从线性表中去掉,删除后使原表长为n的线性表成为表长为n-1的线性表

    顺序表上完成这一操作需要以下步骤。

    1.将a[i+1]~a[n]顺序向前移动,为新元素让出位置。

    2.修改last指针相当于修改表长)使之仍指向最后一个元素。

    算法如下:

    int Delete-SeqList(SeqList*L,int i)

    {

    int j;

    if(i<1 || i> L->last + 1)    //检验表空及删除位置的合法性

    {  printf("不存在第i个元素");

       return(0);

    }

    for(j=i;j<=L->last;j++)

    L->data[j-1] = L->data[j];    //结点移动

    L->last--;                           //last 仍指向最后元素 ,修改表长

    return(1);

    }

    性能分析:顺序表的删除运算,时间组要消耗在了数据的移动上,删除第i个元素时,从a[i+1]~a[n]都要向前移动一个位置,也就一共需要移动n-i个元素,而 i>= 1 && i<=n 所以平均下来就移动了 n/2次,时间复杂度为O(n)。

    本算法注意以下问题。

    1.删除第i个元素,i的取值为 i>= 1 && i<=n,否则第i个元素不存在,因此,要检查删除位置的有效性。

    2.当表空时不能做删除,因表空时L->last =-1,条件(i<1 || i> L->last + 1)也包括了对表空的检查。

    3.删除完a[i]之后,该数据已不存在,如果需要,先取出a[i],再做删除。

    线性表的按值查找

    线性表的按值查找是指在线性表中查找与给定值x相等的元素。在顺序表中完成该运算最简单的方法是:从第一个元素起依次和x比较,直到找到一个与x相等的数据元素,返回他在顺序表中的存储下标或序号(二者差一,即序号=下标+1),或者查遍整个表都没有找到与x相等的元素,返回-1。

    算法如下

    int Location-SeqList(SeqList*L,datatype x)

    {    int i= 0;

          while(i<=L->last && L->data[i] != x)

            i++;

           if(i>L->last)

            return -1;    // 查找失败,返回值为-1。

            else

            return i;      // 查找成功,返回存储位置。

    }

     性能分析:本算法的主要运算是给定值x与表中的元素相比较。显然,比较的次数与x在表中的位置有关,也与表长有关。当a[1]=x时,比较一次成功。当a[n]=x时,比较n次成功,所以平均下来就移动了 n/2次,时间复杂度为O(n)。

    当然,查找失败的情况下,需要比较n次。显然时间复杂度为O(n)。

    ============================================================================================================================================================

  • 相关阅读:
    echarts官网上的动态加载数据bug被我解决。咳咳/。
    jquery中的jsonp和js中的jsonp还有配合php实现的jsonp。
    jquery中的done和always解决ajax问题
    vue2.0使用watch监听对象属性
    gulp配合vue压缩代码格式化
    支持flv的播放神器
    前端组件化-Web Components【转】
    自定义异步加载资源插件
    【leetcode刷题笔记】Two Sum
    【leetcode刷题笔记】Longest Common Prefix
  • 原文地址:https://www.cnblogs.com/Luyang233/p/10054279.html
Copyright © 2020-2023  润新知