1. 程式人生 > >線性表與13個基本操作的實現

線性表與13個基本操作的實現

一、巨集定義解釋
ElemType :線性表資料元素資料型別
LIST_INIT_SIZE : 線性表初始資料元素容量
Status :函式返回值(一般替換int型)
error :0
INFEASIBLE :0
OK :0

二、線性表結構體

typedef struct 
{
   ElemType *elem;      //儲存空間基址
   int      length;     //當前資料元素個數
   int      listsize;   //當前分配的最大資料元素容量
}SqList;

三、13個基本操作
分別是:
建立線性表,清空線性表,銷燬線性表
判空線性表,判滿線性表,獲得當前資料元素個數
獲得指定位置的資料元素,定位符合一定條件的資料元素
獲得一個數據元素的前驅,獲得一個元素的後繼
插入資料元素,刪除資料元素
遍歷線性表
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;
  }