線性表的順序存儲(一)--數組表示

一、線性表的概念:
    1、線性表是一種最簡單、最常用的數據結構,通常一個線性表是由n(n>=0)個性質相同的數據元素組成的有限序列,長度即爲元素的個數n,當n=0時,稱該表爲空表。
    2、非空的線性結構的特點:它具有惟一的第一個數據元素和最後一個數據元素;並且除了第一個元素以外,其他數據元素都只有一個前驅和一個後繼。
    3、線性表的主要存儲結構:順序存儲結構 和 鏈式存儲結構。(本篇主要總結順序存儲結構)
 
二、線性表的順序表示和實現
   順序存儲結構的存儲可以用一維數組表示,具有固定長度。
   也可以用動態分配的存儲結構,可以合理地利用空間。
  
 (一)一維數組表示
  數據結構: 
typedef int datatype;
#define LIST_MAXSIZE 100
typedef struct
{
    datatype data[LIST_MAXSIZE];
    int length;
}Sqlist;

  基本操作:
/*表的初始化*/
void InitList(Sqlist *L)
{
    L->length() = 0;
}
/*求表長*/
int ListLength(Sqlist *L)
{
    return L->length;
}
/*求表中的第i個節點*/
datatype GetElem(Sqlist *L,int i)
{
    if(i<1 || i>L->length)
        Error("position error");
    return L->data[i-1];
}
/*查找節點x在表中的第一個位置*/
int Search(int x,Sqlist *L)
{
    int i;
    for(i=0;i<L->length;i++)
        if(x == L->data[i])
            break;
    if(i == L->length)
        return 0;
    else
        retrun i+1;
}
/*在線性表中的第i個位置之前插入元新元素e*/
Status Insert_Sq(Sqlist *L,int i,datatype e)
{
    datatype * q, *p;
    if(i<1 || i>L->length)
        return ERROR;
    if(L->length > LIST_MAXSIZE-1)
        retrun ERROR;
    q = &(L->data[i-1])
//插入的位置

    for(p=&(L->data[L->length-1]);p>=q;--p)
    {
        *(p+1) = *p;
    }
    *q = e;
    ++L->length;
    return OK;
}
/*第i個節點的刪除*/
Status Delete_Sq(Sqlist *L,int i)
{
    datatype * p,*q;
    if(i<1 || i>L->length)
        return ERROR;
    p = &(L->data[i-1])
//要刪除節點的位置

    q = &(L->data[L->length-1])
//表尾元素的位置

    for(;p<q;p++)
    {
        *p = *(p+1);
    }
    --L->length;
    return OK;
}
歸併操作:
/*已知線性表La和Lb非遞減排序,歸併La和Lb得到Lc的數據元素也按非遞減排序*/
Void MergeList(Sqlist *La,Sqlist *Lb,Sqlist *Lc)
{
    int La_len,Lb_len,i=j=1,k=0;
    datatype ai,bj;
    La_len = ListLength(La);
    Lb_len = ListLength(Lb);
    while((i<=la_len)&&(i<=lb_len))
    {
        ai = GetElem(La,i);
        bj = GetElem(Lb,j);
        if(ai < bj)
        {
            k++;
            i++;
            ListInsert(Lc,ai);
        }
        else
        {
             k++;
             j++;
             ListInsert(Lb,bj);
        }
    }
    while(i<=La_len)
    {
         ai = GetElem(La,i);
         i++;
         k++;
         ListInsert(Lc,ai);
    }
    while(j<=Lb_len)
    {
         bj = GetElem(Lb,j);
         j++;
         k++;
         ListInsert(Lc,bj);
    }
    Lc->length = k;
}

以上算法在《數據結構(c語言版)》陳明編著清華大學出版  33頁上分了三種情況,ai<bj,ai=bj,ai>bj.其實ai=bj這種情況沒必要單獨列出來,當然這樣思路更清晰點,程序如下:
 
/*已知線性表La和Lb非遞減排序,歸併La和Lb得到Lc的數據元素也按非遞減排序*/
Void MergeList(Sqlist *La,Sqlist *Lb,Sqlist *Lc)
{
    int La_len,Lb_len,i=j=1,k=0;
    datatype ai,bj;
    La_len = ListLength(La);
    Lb_len = ListLength(Lb);
    while((i<=la_len)&&(i<=lb_len))
    {
        ai = GetElem(La,i);
        bj = GetElem(Lb,j);
        if(ai < bj)
        {
            k++;
            i++;
            ListInsert(Lc,ai);
        }
        else
        if(ai == bj)
        {
            k++;
            ListInsert(Lc,ai);
            i++;
            k++;
            ListInsert(Lc,bi);
            j++;
        }
        else
        {
             k++;
             j++;
             ListInsert(Lb,bj);
        }
    }
    while(i<=La_len)
    {
         ai = GetElem(La,i);
         i++;
         k++;
         ListInsert(Lc,ai);
    }
    while(j<=Lb_len)
    {
         bj = GetElem(Lb,j);
         j++;
         k++;
         ListInsert(Lc,bj);
    }
    Lc->length = k;
}

利用基本運算清除線性表中重複出現的多餘節點
void Purge(List *L)
{
    int i,k;
    datatype x,y;
    for(i=1;i<ListLength(L);i++)
    {
        x = GetElem(L,i);
        k = i+1;
        while(k<=ListLength(L))
        {
             y = GetElem(L,k);
             if(x==y)
                 Delete(L,k);
             else
                 k++;
        }
    }
}
該算法的關鍵是Delete()算法中 會自動把l->length減1。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章