1. 程式人生 > 其它 >線性表的順序表示和實現(順序表)

線性表的順序表示和實現(順序表)

順序表:採用順序儲存結構的線性表稱為順序表

  1.順序表的儲存結構

#順序表是線性表的順序儲存表示法,其資料元素用一段連續的地址空間,類似陣列,其特點為邏輯上相鄰,物理次序也是相鄰的。

#假設順序表中每個元素佔用l個儲存單元,並且第一個元素所佔地址為儲存單元的基地址,線性表中第i+1個元素的儲存位置LOC(ai+1)和第i個元素的儲存位置LOC(ai)有以下關係

LOC(ai+1)=LOC(ai)+l

LOC(ai+1)=LOC(a1)+(i-1)*l

#define MAXSIZE 100         //儲存空間分配大小
typedef int ElemType;       //給int起別名ElemType
typedef struct { ElemType *elem; //儲存空間基地址,首地址.可以理解為順序表為一“動態陣列”,指標變數elem指向陣列的首地址。 int length; //當前長度,用於統計順序表的長度,元素個數。 }SqList;

Tip:①這裡的SqList,相當於給該自定義結構類取了一個別名,定義該自定義型別變數時就可像這樣SqList List;

  2.順序表的基本操作與實現

2.1.順序表的初始化  int InitList(SqList *L)

演算法步驟:①為順序表List分配一個預定義大小的陣列空間,elem指向這段空間的基地址。

②分配空間成功,將當前表長設定為0(未插入資料,表長為0);

//1.初始化順序線性表
int InitList(SqList *L)
{
(
*L).elem=(ElemType*)malloc(MAXSIZE*sizeof(ElemType));//分配儲存空間 if(!(*L).elem) { printf("\n分配空間失敗!!!"); return -1;//空間分配失敗 } (*L).length=0;//空表長度設定為0 printf("\n分配空間成功!!!"); return 0; }

Tip:①該順序表初始化函式所傳的引數為指標型別,需建立個指標變數L指向List(上面的SqList List),再將該指標變數L傳入。

   ②這裡用if( ! (*L).elem )判斷分配空間是否為空,c語言中,變數未賦值時其值是隨機的。因此我們再建立變數List後,將List.elem賦值為NULL;使該判斷有效。

   ③分配儲存空間後將List.length<==>(*L).length賦值為0,當前表為空表。

2.2.順序表的插入  int ListInsert(SqList *L,int i,ElemType e)

演算法步驟:①首先判斷位置i是否合法(合法範圍是1 <= i <= n+1)n為元素個數即順序表長度。

②判斷順序表的儲存空間是否已滿(這裡暫時不考慮擴充套件空間)。

③將第i個到第n個位置的元素依次向後移動一個位置。

④將要插入的元素e賦值到第i個位置。

⑤表長+1,完成插入。

//2.線性表中插入元素
int ListInsert(SqList *L,int i,ElemType e)
{
    if(i<1||i>(*L).length+1)
    {
        printf("\n插入位置違法!!!");
        return -1;
    }
    if((*L).length==MAXSIZE)
    {
        printf("\n順序表的儲存空間已滿!!!");
        return -1;
    }
    int j;
    for(j=(*L).length-1;j>=i-1;j--)
    {
        (*L).elem[j+1]=(*L).elem[j];
    }
    (*L).elem[i-1]=e;
    (*L).length++;
    printf("\n插入成功!!!");
    return 0;
}

Tip:①這裡移動順序標中第i到第n個元素採用的是下標表示法,elem[i-1]對應於第i個元素,這裡要注意。

2.3.順序表的取值  int GetElem(SqList List,int i,ElemType *e)

演算法步驟:①首先判斷取值位置i是否合法(1<= i >=n)

②若取值位置合法,將第i個元素List.elem[i-1]賦值給e。

//3.取出第i個元素的值
int GetElem(SqList List,int i,ElemType *e)
{
    if(i<1||i>List.length)
    {
        printf("\n所取位置違法!!!");
        return -1;
    }
    *e=List.elem[i-1];
    printf("\n取值成功!!!");
    return 0;
}

Tip:①這裡傳入的是ElemType *e,e是個指向ElemType型別變數的指標,接收該返回值即*e=List.elem[i-1]。

   ②想要接收第i個元素的值,就事先定義一個ElemType型別的變數e,再定義個該型別的指標變數pe指向變數e(pe>>e)。向函式傳入指標變數pe即可。

2.4.順序表的查詢  int LocateElem(SqList List,ELemType e)

演算法步驟:①從第一個元素開始,依次與查詢的元素e進行比較,若有e==List.elem[i],返回其位置i+1。

   ②未查到,查詢失敗。

//4.查詢線性表中有無與e值相同的元素,有返回其位置,無返回0
int LocateElem(SqList List,ElemType e)
{
    int i;
    for(i=0;i<List.length;i++)
    {
        if(List.elem[i]==e)
        {
            printf("\n查詢成功!!!");
            return i+1;
        }
    }
    printf("\n未找到");
    return 0;
}

Tip:①若所查詢的元素值在順序表中有多個,這裡只返回第一個的位置(從第一個元素開始比較)。

2.5.順序表的刪除  int ListDelete(SqList *L,int i)

演算法步驟:①先判斷刪除位置i的合法性(1<= i <=n)。

   ②將第i+1個到第n個元素依次向前移動一個位置

   ③刪除成功,表長-1。

//5.刪除i位置的元素
int ListDelete(SqList *L,int i)
{
    if(i<1||i>(*L).length)
    {
        printf("\n刪除位置違法!!!");
        return -1;
    }
    else
    {
        int j;
        for(j=i-1;j<(*L).length-1;j++)
        {
            (*L).elem[j]=(*L).elem[j+1];
        }
        (*L).length--;
        printf("\n刪除成功!!!");
        return 0;
    }
}

2.6.順序表的列印  int ListAll(SqList List)

演算法步驟:①首先判斷順序表是否為空表。

   ②若不為空表,從第一個元素List.elem[0]開始迴圈列印所有元素。

//列印線性表的所有元素
int ListAll(SqList List)
{
if(List.length==0)
{
printf("\n該表為空表");
return -1;
}
int i; printf("\n輸出表中所有元素:\n"); for(i=0;i<List.length;i++) { printf("%d ",List.elem[i]);
}
return 0; }

  3.主函式的實現

int main()
{
    int num,i;       //初始線性表元素個數num
    SqList List;
    SqList *L;
    L=&List;
    InitList(L);     //初始化順序表,建立空表
    printf("\n請輸入要輸入的線性表元素個數");
    scanf("%d",&num);
    for(i=0;i<num;i++)
    {
        printf("\n請輸入第%d個元素:",i+1);
        scanf("%d",&List.elem[i]);//給順序表一些元素賦一些值得到一個不為空的初始表
        List.length++;
    }
    printf("請輸入要插入的元素資料:");
    ElemType e;
    ElemType *pe;
    pe=&e;//指標pe指向變數e
    scanf("%d",&e);
    printf("請輸入要插入的位置:");
    scanf("%d",&i);
    ListInsert(L,i,e);//在位置i插入元素e
    ListAll(List);//順序表的列印
    printf("\n請輸入想要取出元素的位置:");
    scanf("%d",&i);
    if(GetElem(List,i,pe)==0)//取位置為i的元素
    {
        printf("\n位置合法查詢成功:%d位置的元素為%d",i,e);
    }else
    {
        printf("\n位置不合法查詢元素失敗");
    }
    printf("\n請輸入要查詢其位置的元素:");
    scanf("%d",&e);
    int locat=LocateElem(List,e);//查詢元素e的位置
    if(locat==0)
    {
        printf("\n線性表中無此元素");
    }
    else
    {
        printf("\n元素%d的位置為:%d",e,locat);
    }
    printf("\n請輸入要刪除元素的位置:");
    scanf("%d",&i);
    ListDelete(L,i);//刪除位置i的元素
    ListAll(List);//順序表的列印
    free(List.elem);//釋放順序表的記憶體空間
    return 0;
}

  4.結果演示

注意:本文章所有程式碼連起來,即可執行(當然開頭匯入兩個標頭檔案)。

#include<stdio.h>
#include<stdlib.h>