一、线性表

线性结构:在数据元素的非空有限集中:

    (1)存在唯一的一个被称为“第一个”的数据元素;

    (2)存在唯一的一个被称作“最后一个”的数据元素;

    (3)除第一个外,集合中的每个元素均只有一个前驱;

    (4)除最后一个之外,集合中每个数据元素均只有一个后继。

线性表是最常用且最简单的一种数据结构。简言之,一个线性表是n个数据元素的有限序列。其中,每个元素的具体含义在不同的情况下各不相同可以是一个数或一个符号甚至是一本书或更复杂的信息。如:字母表:(A,B,C,D,...Z)     数列(1,2,3,...n)均为线性表。

复杂的线性表中,一个数据元素可以由若干个数据项(item)组成。在这种情况下常把数据元素称为记录(record),含有大量记录的线性表又称为文件(file)。


线性表结构体

typedef struct 
{
   ElemType *elem;      //存储空间基址
   int      length;     //当前数据元素个数
   int      listsize;   //当前分配的最大数据元素容量
}SqList;


基本操作 :

建立线性表,清空线性表,销毁线性表 
判空线性表,判满线性表,获得当前数据元素个数 
获得指定位置的数据元素,定位符合一定条件的数据元素 
获得一个数据元素的前驱,获得一个元素的后继 
插入数据元素,删除数据元素 
遍历线性表 
1、建立线性表 
初始条件:一个未初始化的线性表结构体
Status InitList(SqList &L)
{
    L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
    //申请存储空间
    if(!L.elem)
    exit(0);
    L.length=0;//空表的长度为0
    L.list=LIST_INT_SIZE;//初始数据元素存储容量
    return OK;
 }

2、清空线性表 
初始条件:线性表存在 
操作结果:清空线性表(将当前元素个数赋值0,遍历不出任何一个元素,相当于清空线性表)

Status ClearList(SqList &L)
{
    L.length=0;
    return Ok;
}

3、销毁线性表 
初始条件:线性表已存在 
操作结果:销毁线性表

Status Destroy(SqList &L)
{
    free(L.elem);
    L.elem=NULL;
    L.length=0;
    L.listsize=0;
    return OK;
}

4、判空线性表 
初始条件:线性表存在 
操作结果:线性表为空返回true,不为空返回false

bool ListEmpty(SqList L)//不需要对线性表的成员变量进行改变,所以不使用引用
{
    return (L.length==0)?true:false;
}

5、判满线性表 
初始条件:线性表存在 
操作结果:若线性表已满返回true,否则返回false

bool ListFull(SqList L)
{
    return (L.length==L.listsize)?true:false;
}

6、获取线性表当前元素个数 
初始条件:线性表已存在 
操作结果:返回线性表当前元素个数

int ListLength(SqList L)
{
    return L.length;
 }

7、获得指定位置的数据元素 
初始条件:线性表存在 
操作结果:获得指定位置的数据元素并赋值给e

Status GetElem(SqList L,int i, ElemType &e)
{
    if(i<1||i>L.length)
    exit(error);
    e=*(L.elem+i-1);//(基址+i-1)即为第i个元素的地址
    return OK;
}

8、定位元素(获得符合一定条件的数据元素的位序) 
初始条件:线性表已存在 
操作结果:返回L中第一个与e满足关系的元素的位序,若不存在返回0 
(注意:compare()表示一个关系判定函数,满足返回值为1,否则返回值为2,使用函数指针,方便调用)

int LocateElem(SqList L,ElemType e,status(*compare)(ElemType,ElemType))
{
    Elem *p=L.elem; //P的初值为第一个元素的存储位置
    int i=1;//i的初值为第一个元素的位序
    while(i<=L.length&&!compare(*p++,e))//越界或已找到满足条件的元素
    //i的最大可能值为L.length+1
    {
        if(i<=L.length)
        return i;
        else
        return 0;
    }

9、返回前驱 
初始条件:线性表已存在,数据元素存在前驱 
操作结果:查找数据元素,若线性表中有该元素且前驱存在,将前驱拷贝给一个与数据元素数据类型相同的变量;若前驱不存在,上述变量无定义

//返回前驱,equal要提前声明 
Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e)
{
   int a;
   a=LocateElem(L,cur_e,equal);
   if(!a||a==1)
   {
    cout<<"查找失败"<<endl;
    return error;
   }
   pre_e=*(L.elem+a-2);
   return OK;
 }

10、返回后继 
初始条件:线性表已存在,数据元素存在后继 
操作结果:查找数据元素,若线性表中有该元素且后继存在,将后继拷贝给一个与数据元素数据类型相同的变量;若后继不存在,上述变量无定义

Status NextElem(SqList L,ElemType cur_e,ElemType &next_e)
{
    int a;
    a=LocateElem(L,cur_e,equal);
    if(!a||a==L.length)
    {
      cout<<"查找失败"<<endl;
      return error;
    }
    next_e=*(L.elem+a);
    return OK;

 }

11、插入一个数据元素 
初始条件:线性表存在 
操作结果:在L中第i个元素之前插入新的元素e,L的长度加1

Status ListInsert(SqList &L,int i,ElemType e)
{
    ElemType *newbase,*q,*p;
    if(i<1||i>L.length+1)//i值不合法
    return error;
    if(L.length>=L.listsize) //当前存储空间已满,增加分配
    {
        if(!(newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType))))
        exit(0);//分配存储空间失败
        L.elem=newbase;//新基址
        L.listsize+=LISTINREMENT;//增加存储容量
    }
        q=L.elem+i-1;//q为插入位置
        for(p=L.elem+L.length-1;p>=q;--p)
        { *(p+1)=*p;//给插入位置之后的元素赋值达到之后元素后移一位的效果
        }
        *q=e;//插入e
        ++L.length;
        return OK;
 }

12、删除元素 
初始条件:线性表已存在 
操作结构:删除第i个数据元素并返回其值,L的长度减1

Status ListDelete(SqList &L,int i,ElemType &e)
{
    ElemType *p,*q;
    if(i<1||i>L.length)//i值不合法
    return error;
    p=L.elem+i-1;//p为被删除元素的位置
    e=*p;//被删除元素的值赋给e
    q=L.elem+L.length-1;//表尾元素的位置
    for(++p;p<=q;++p)
    *(p-1)=*p;
    L.length--;
    return OK;
}    


13、遍历线性表 
初始条件:线性表已存在 
操作结果:依次对L的每个元素使用函数f(),f()可以是输出函数,一旦操作失败,则操作失败

Status ListTraverse(SqList L, void(*f)(ElemType&))
{
    ElemType *p=L.elem;
    int i;
    for(i=1;i<=L.length;i++)
    f(*p++);
    cout<<endl;
    return OK;
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值