數據結構之線性表

一、線性表的概念和定義

1、線性表的邏輯結構特點

線性表是一種最簡單的線性結構,是一個數據元素的有序(次序)集。

集合中必存在唯一的一個“第一元素”;

集合中必存在唯一的一個“最後元素”;

除最後元素之外,每個元素均有唯一的後繼;

除第一元素之外,每個元素均有唯一的前驅;

2、線性表的基本術語

線性表可描述爲n(n≥0)個具有相同特性的數據元素組成的有限序列。

常表示爲:L={a1 ,…, ai-1, ai, ai+1, …, an};ai必須具有相同特性,即屬於同一數據對象。

ai-1是ai的直接前驅元素,ai+1是ai的直接後繼元素;

數據元素ai在線性表中有確定的位置i,i稱爲位序;

線性表中數據元素的個數n稱爲線性表的長度,n=0時,線性表稱爲空表。

3、ADT定義

ADT   List{

數據對象:

    D={ai | ai∈ElemSet,i=1,2,...,n,n>=0}     {稱n爲線性表的表長;稱n=0時的線性表爲空表。}

數據關係:

R1={<ai-1,ai>|ai-1,ai∈D,i=2,...,n }    {設線性表爲(a1,a2,...,ai,...,an),    稱i爲ai在線性表中的位序。}

}

基本操作:

結構初始化操作

結構銷燬操作

引用型操作

加工型操作

}ADT List

GetElem(L,i,&e)

初始條件:

      線性表L已存在,且1<=i<=LengthList(L).

操作結果:

     用e返回L中第i個元素的值。

LocateElem(L,e,compare())

初始條件:

       線性表L已存在,e爲給定值,compare()是元素判定函數。

操作結果:

      返回L中第一個與e滿足關係compare()的元素的位序。若這樣的元素不存在,則返回值爲0.

ListTraverse(L,visit())

初始條件:

       線性表L已存在,visit()爲某個訪問函數

操作結果:

      依次對L的每個元素調用函數visit().一旦visit()失敗,則操作失敗。

PutElem(&L,i,&e)

初始條件:

       線性表L已存在,且1<=i<=LengthList(L).

操作結果:

       L中第i個元素賦值同e的值.

ListInsert(&L,i,e)

初始條件:

       線性表L已存在,且1<=i<=LengthList(L)+1

操作結果:

       在L的第i個元素之前插入新的元素e,L的長度增1.

ListDelete(&L,i,&e)

初始條件:

       線性表L已存在且非空,1<=i<=LengthList(L).

操作結果:

       刪除L的第i個元素,並用e返回其值,L的長度減1.

二、線性表的順序存儲實現——順序表

1.順序存儲(映像)方式

          以x的存儲位置和y的存儲位置之間某種關係表示邏輯關係<x,y>.最簡單的一種順序映像方法是:令y的存儲位置和x的存儲位置相鄰。

2.順序表的C語言描述

          #define  List_INIT_SIZE 100   //線性表存儲空間的初始分配容量

typedef struct

{

      ElemType *elem; //存放線性表的數組空間基地址

      int   length;    //當前長度(實際元素個數)

      int   listsize;  //當前分配的容量

}SqlList;//稱 順序表

順序表的基本形態

定義:sqList L;

空表

L.length==0 可插入不可刪除

表滿

L.length>=L.listsize 可刪除不可插入(空間再分配)

表不空不滿

0<L.lenth<L.listsize  可刪除可插入

3、線性表的基本操作在順序表中的實現

初始化:

       Status InitList_Sq(SqList&L)

        {

             L.elem=(ElemType*)malloc(List_INIT_SIZE*sizeof(ElemType));

             if(!L.elem)   exit(OVERFLOW);

             L.length=0;

             L.listsize=List_INIT_SIZE;

             return OK;

        }//InitList_Sq

int Locate(SqList L,ElemType e)

{  //在順序表L中查詢第一個等於e的數據元素,若存在,則返回它的位序,否則返回0

i=1;           //i的初值爲第1元素的位序

for(i<=L.length;i++)

     if(L.elem[i-1]==e)

         return i;

return 0;

}//Locate

Status  search_i(SqList L,int i,ElemType &e)

{//在順序表L中查找第i個元素,若存在用e返回其值並返回OK,否則返回ERROR

      if(i>0&&i<=L.length)

      {

             e=L.elem[i-1];

              return OK;

      }

else

       return ERROR;

}

線性表的插入操作(ListInsert(&L,i,e))的實現:

分析:

插入元素時,線性表的邏輯結構發生了什麼變化?

(a1,...,ai-1,ai,...,an)改變爲(a1,...,ai-1,e,ai,...,an)

<ai-1,ai>——><ai-1,e>,<e,ai>
需考慮的問題(步驟)
1.當前表是否已滿?
2.輸入(插入位置)是否有效?
3.插入元素

Status  ListInsert(SqList &L,int i,ElemType e)
{//在順序表L的第i個元素之前插入新的元素e,i的合法範圍爲1<=i<=L.length+1
if(i<1||i>L.length+1)   return ERROR;
if(L.length>=L.listsize)
{//空間再分配
       newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
        if(!newbase) exit(OVERFLOW);
        L.elem=newbase;//基地址更新
        L.listsize+=LISTINCREMENT;//表容量更新
}
        for(j=L.length;j>=i;j--)
        L.elem[j]=L.elem[j-1];//插入位置及之後的元素右移
        L.elem[i-1]=e;//插入e
        ++L.length;//表長+1
         return OK;     
}//ListInsert_Sq

線性表操作
       ListDelete(&L,i,&e)的實現:
分析:
刪除元素時,線性表的邏輯結構發生了什麼變化?
(a1,a2,...,ai,ai+1,...,an)改變爲(a1,a2,...,ai-1,ai+1,...an)
<ai-1,ai>,<ai,ai+1>——><ai-1,ai+1>
存儲空間(順序表)的變化:表的長度減少
Status  ListDelete_Sq(SqList &L,int i,ElemType &e)
{//在順序表L中刪除第i個元素,以引用參數e返回其值,若刪除成功返回ok;否則返回ERROR
      if(i<1||i>L.length)
      return ERROR;//i的值不合法
      e=L.elem[i-1];
      for(j=i;j<L.length;j++)
      L.elem[j-1]=L.elem[j];//元素前移
      --L.length;
       return OK;
}//ListDelete_Sq
順序表操作的效率分析
時間效率分析:
       算法時間主要耗費在移動元素的操作上,而移動元素的個數取決於插入或刪除元素的位置。
以插入爲例分析
       若插入在尾元素之後,則根本無需移動(特別快);
       若插入在首元素之前,則表中元素全部要後移(特別慢);
Status Del_k(SqList&L,int i,int k)
{//在順序表L中刪除自第i個開始的k個元素,操作成功返回ok,否則返回error;
     if(i>L.length||k>L.length-i+1)
      return ERROR;
      for(j=i+k-1;j<=L.length-1;j++)
      L.elem[j-k]=L.elem[j];//元素前移完成刪除
      L.Length-=k;//順序表長度減k
      return OK;
}
小結——順序表的特點:
優點:可以隨機存取表中任一元素,方便快捷;
缺點:在插入或刪除某一元素時,需要移動大量元素;需要預先確定數據元素的最大個數。
解決問題的思路:改用另一種線性存儲方式:鏈式存儲結構。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章