c语言数据结构(3)

来源:互联网 发布:基于java的oa审批流程 编辑:程序博客网 时间:2024/05/21 11:34

 1 最坏情况和平均情况

    我们要是查找一个具有n个元素的数组中的某一个数字时,可能会有很多种情况,最好的情况就是第一个就被查到,最坏的情况是查到第n个的时候才查到,所以,我们根据这个,也得出了最坏时间复杂度和平均时间复杂度,在最坏时间复杂度的保证下,保证不会再坏了我们一般提到的运行时间都是最坏运行时间,平均运行时间是表示在第n/2次找到元素,这是最有意义的运行时间,因为这是期望中的运行时间.

   2 算法的空间复杂度

   算法的空间复杂度由算法所需的存储空间实现,算法的空间复杂度公式如下:S(n)=O(f(n));其中f(n)表示n所占的空间的函数,记作空间复杂度,若输入数据所占空间只取决问题本身,我们仅仅需要分析算法在实现时所需要的存储单元即可,如果存储单元相对于我们输入的数据来说是一个常数,那么我们称这个算法为原地工作,空间复杂度记作O(1),这本书主要讲得还是时间复杂度

   第三章,线性表

 1,线性表的定义

   线性表是零个或多个元素的有限序列,其中,序列表示元素之间必须要有顺序,不能有插队,就像是一条排的整整齐齐的队伍一样,元素数量也是有限的,在线性表中,若存在元素a1,a2,......ai-1,ai,ai+1,.....an-1,an.ai-1是ai的直接前驱元素,ai是ai-1的直接后继元素,线性表的元素个数定义为线性表的长度

   线性表的抽象数据定义如下:

   ADT 线性表(list)

DATA 

   在线性表中,除了第一个元素,每个元素都有且只有一个直接前驱元素,除了最后一个元素,每个元素都有且只有一个直接后继元素,数据元素之间是一对一的关系

    operation

    InitList (*l) //初始化操作,新建一个线性表

   ListEmpty(l)  //若线性表为空,返回true,否则返回false

   ClearList //清空线性表

    GetElem(l,i,*e)  //将线性表第i个元素值返回给e

    LocateElem(l,e) // 在线性表l中查找元素e,如果查到了,返回这个元素在线性表中的序号,没查到返回0

    ListInsert(*l,i,e)  //在线性表l中的第i个位置插入e 

   ListDelete(*l,i,e)  //删除线性表中第i个位置的元素e,返回值e

    ListLength(l)    //返回线性表的长度

   EndADT  (PS:ADT是指一个数学模型以及定义在该模型的操作,一般情况如下

ADT

{
数据对象:(数据元素集合)
数据关系:(数据关系二元组结合)
基本操作:(操作函数的罗列)
})
线性表的物理结构:
   线性表的物理结构有两种,第一种是顺序存储结构,也就是用一段连续的存储单元来存储线性表的数据元素,类似于c语言中的数组,线性表的顺序结构存储代码如下
  #define MAXSIZE 20
   typedef int ElemType;  //Elemtype表示int
   typedef struct

    ElemType date [MAXSIZE]; //ElemType是我们在c语言中,是"元素的类型"的简称
    int length;  //线性表的长度
}sqlist;
可以看出描述顺序存储结构的三个属性
存储空间的起始位置:数组data,数组的存储空间就是存储空间的存储位置
线性表的最大存储量,数组长度Maxsize
线性表的当前长度:length
线性表的长度
数组的长度就是存储的线性表的长度,一般数组的长度是不变的,在一些高级的编程语言中可以动态定义数组的长度,不过那样会对性能造成损耗,线性表的长度随着你插入,删除输入而改变,线性表的长度不是一成不变的.在任意时刻,线性表的长度应该小于数组的长度
地址的计算方法
   线性表中的第i个元素存储位置是i-1,像是第一个元素的元素a1的存储位置是a[0],我们设我们之前定义的数据类型所占空间是c,LOC表是获得存储位置的函数,在线性表中的第i个和第i+1个元素满足关系如下
LOC(ai+1)=LOC(ai)+c
LOC(ai)=LOC(a1)+(i-1)*c

获得元素操作

Getelem操作,返回在线性表中第i个位置的元素值,操作很简单,大致就是把这个位置的数据赋给另一个elemtype的类型指针,返回这个指针,就是在使用的过程中注意机种情况

1,线性表为空时 2.想找的位置小于1时 3,想找的位置超出线性表的长度,由于我们对这个函数赋的类型是int型,所以返回值可以设成1(true)或者是0(error)

插入操作

由于线性表的存储顺序,我们如果想要插入数据进入到表当中,就必须改变其他元素的位置,我们在实现插入数据操作的思路如下:

插入位置不合理,抛出异常. 线性表长度大于等于数组长度,抛出异常或者是动态增加容量.把想插入的第i个位置往后的所有元素位置向后挪一位.把元素插入i位置处. 表长加1

int listinsert (sqlist *l,int i,elemtype e)

{

    int k;

    if  (l->length==MAXSIZE) //线性表已满时,报错

  return 0; 

   if   (i<1 || i>l->length+1)  //插入位置有问题,位置小于1或者是插入位置过长

  return 0;

  if (i<=l->length)

  {

     for (k=l->length-1;k>=i-1;k--)

      l->data[k+1]=l->data[k];  //数据往后挪一位操作

 }

   l->data[i-1]=e;  //插入数据操作

 l->length++;  //表长加一操作

return 1;

}接下来实现的删除操作,在实现删除操作的同时,应该满足以下的条件:

1确定删除元素在表中的位置,如果删除位置不合理(小于1,超出表长等等),抛出异常

2把删除的元素去除,并把表中所有在这个元素之后的元素向前提一位

3表长减一 实现代码如下:

int listdelete (sqlist *l,int i,elmetype *e)

{

    int k;

    if (l->length==0)

       return 0;

  if (i<1 || i>l->length)

      return 0;

  *e=l->data[i-1];

   if  (i<l->length)

   {

   for (k=i;k<l->length;k++)

     l->data[k-1]=l->data[k];

 }

   l-length--;

return 1;

}

0 0