1. 程式人生 > 其它 >c語言順序表實現

c語言順序表實現

順序表作為資料結構的入門,是需要我們掌握的,下面我們就來實現一下靜態順序表。為了方便,這裡使用到了c++的引用。

1.首先是這個結構體

typedef struct {
    ElemType data[MaxSize];//靜態順序表
    int length;
}SqList; 

結構體裡面有兩個元素,一個是資料的靜態陣列,maxsize和elementtype都是巨集定義。已經在程式碼開始之前宣告好了。

注意,這裡我們用typedef將其重新命名為了Sqlist,方便後續使用。

2.接下來就是插入操作。

//插入操作
bool ListInsert(SqList& L, int
i, ElemType e) { if (i<1 || i>L.length + 1) {//判斷插入位置是否合法 return false; } if (L.length > MaxSize) {//陣列滿了! return false; } for (int j = L.length; j >= i; j--) {//反迴圈實現指定陣列元素向後移動。就是前面的賦值給後面的,所以是j-1. L.data[j] = L.data[j - 1]; } L.data[i - 1] = e;//
指定位置插入。 L.length++;//插入後長度+1. return true; }

這裡函式的引數列表裡用到了c++的&,即對主函式裡的L取別名,在函式裡面的修改會直接帶回到主函式裡面去。當然也可以用指標實現,後續會進行更新。

這個插入是在第 i 位插入 e 這個元素,作用於L順序表。首先判斷插入位置合法性以及判斷陣列是否已滿,這裡滿了是沒辦法的,因為是靜態陣列,想要解決需要通過malloc函式實現動態陣列開闢,這個後面會更新,這裡先討論靜態順序表,理解他的思想。

最關鍵的就是這個迴圈,他會將指定位置後面的元素全部往後挪一位,我們看一看就是把第i位賦值給i+1位,但是這樣是不是有可能丟掉一位?那麼就將j-1賦值給第j位。

之後就是常規操作,把目標元素e賦值給L。

最後長度+1.

 

3.接下來是刪除操作。

//按位刪除
bool ListDelete(SqList& L,int i,ElemType &e) {
    if (i<1 || i>L.length + 1) {//判斷刪除位置是否合法
        return false;
    }
    if (L.length == 0) {
        return false;
    }
    e = L.data[i - 1];//取得被刪除的元素e。
    for (int j = i; j < L.length; j++) {
        L.data[j - 1] = L.data[j];//從i的位置開始,所有元素從後往前移,所以是j賦給j-1.
    }
    L.length--;//刪除元素順序表長度減一。
    return true;
}

 

4.這裡是按位刪除,傳入的引數是順序表L,位置i,刪除的值e。

仍然是常規操作判斷刪除的位置是否合法,這個不要忘了。

這裡將e帶回是為了main函式裡的操作。之後就是這一位被刪除。實際上並不是把他給刪了,是把他之後的所有元素全部往後挪一位,然後他後面的就把它給覆蓋了,最後長度減一。這個挺有意思。

然後就是查詢操作。

/按值查詢
int LocateElem(SqList& L, int e) {
    int i;
    for (i = 0; i < L.length; i++) {//遍歷順序表
        if (L.data[i] == e) {
            return i + 1;//加一是為了輸出位序。
        }
        else {
            return 0;
        }
    }
}

這裡的查詢只用了兩個引數,順序表L和e元素。

查詢的原理就是遍歷,從頭到尾遍歷一遍,只要找到了就返回這是哪一位。這裡加一是返回的位序,返回下標的話就無須加一。

找到就返回這個位序,找不到就返回0.最後進入主函式處理。

 

5.接下來就是主函式。

//主函式
int main() {
    SqList L;
    bool ret;//檢視返回值
    ElemType del;//要刪除的值
    int element_get = 0;//查詢返回的元素位置
    L.data[0] = 0;//初始化
    L.data[1] = 1;
    L.data[2] = 2;
    L.length = 3;//順序表的長度初始化,理解為組合操作吧。
    
    ret = ListInsert(L,2,60);//往第二個位置插入 60 這個元素。
     if (ret) {
        printf("插入成功,當前順序表為:\n");
        PrintList(L); 
    }
    else {
        printf("插入失敗,當前順序表為:\n");
    }
    ret = ListDelete(L, 1, del);//刪除第一個位置元素,並把元素值輸出。
    if (ret) {
        printf("刪除成功,當前順序表為:\n");
        PrintList(L);
    }
    else {
        printf("刪除失敗,當前順序表為:\n");
        PrintList(L);
    }
    element_get = LocateElem(L, 1);//獲取查詢函式的返回值。
    if (element_get == 0) {
        printf("未找到,當前線性表元素為:");
        PrintList(L);
    }
    else{
        printf("已找到,位序為:%d",element_get);
    }
    return 0;
}   

線性表的初始化這裡是手動進行的,直接用成員運算子賦值即可。這裡的失敗和成功都是通過返回值來進行判斷的,還請仔細閱讀。

其實這裡操作的都是我們最開始初始化的這個L,這就是引用&存在的理由,有了它就沒有指標那麼麻煩的去保證每個函式的修改會落實到主函式這裡。