1. 程式人生 > >順序表的基本操作及C語言完整實現

順序表的基本操作及C語言完整實現

順序表進行操作,大致可分為以下幾類:
  1. 表的建立;
  2. 表中新增(新增)資料元素;
  3. 表中刪除資料元素;
  4. 表中查詢指定資料元素;
  5. 表中更改某資料元素;

以上操作各自的原理及實現如下所示。

順序表的建立

順序表的建立,也就是順序表進行初始化,在預先申請記憶體空間的同時,給變數 size 和 length 賦初值:

table initTable(){
    table t;
    t.head=(int*)malloc(Size*sizeof(int));//構造一個空的順序表,動態申請儲存空間
    if (!t.head) //如果申請失敗,作出提示並直接退出程式
    {
        printf("初始化失敗");
        exit(0);
    }
    t.length=0;//空表的長度初始化為0
    t.size=Size;//空表的初始儲存空間為Size
    return t;
}

順序表查詢元素

在陣列中查詢某個資料元素時,可以採取多種查詢演算法,例如二分查詢、插值查詢、斐波那契查詢演算法等。

具體的查詢演算法以及各自的時間複雜度後續章節會介紹。

根據順序表中儲存的資料的特點,選擇合適的演算法。這裡,採用順序查詢演算法(普通的遍歷演算法)。

實現程式碼:

//查詢函式,其中,elem表示要查詢的資料元素的值
int selectTable(table t,int elem){
    for (int i=0; i<t.length; i++) {
        if (t.head[i]==elem) {
            return i+1;
        }
    }
    return -1;//如果查詢失敗,返回-1
}

順序表中更改元素

順序表中更改資料元素,最簡單直接的方式就是:呼叫查詢演算法找到該資料元素的位置,直接在該位置上更改。

實現程式碼:
//更改函式,其中,elem為要更改的元素,newElem為新的資料元素
table amendTable(table t,int elem,int newElem){
    int add=selectTable(t, elem);
    t.head[add-1]=newElem;//由於返回的是元素在順序表中的位置,所以-1就是該元素在陣列中的下標
    return t;
}

順序表插入元素

插入資料元素,無非三種情況:
  1. 在表頭插入
  2. 在表的中間某個位置插入
  3. 直接尾隨順序表,作為表的最後一個元素

無論在順序表的什麼位置插入資料元素,解決辦法都是:找到要插入的位置,將後續資料元素整體向後移動一個位置,最後直接在騰出來的位置上插入資料元素。

實現程式碼:
//插入函式,其中,elem為插入的元素,add為插入到順序表的位置
table addTable(table t,int elem,int add)
{
    //判斷插入本身是否存在問題(如果插入元素位置比整張表的長度+1還大(如果相等,是尾隨的情況),
    //或者插入的位置本身不存在,程式作為提示並自動退出)
    if (add>t.length+1||add<1) {
        printf("插入位置有問題");
        return t;
    }
    //做插入操作時,首先需要看順序表是否有多餘的儲存空間提供給插入的元素,如果沒有,需要申請
    if (t.length==t.size) {
        t.head=(int *)realloc(t.head, (t.size+1)*sizeof(int));
        if (!t.head) {
            printf("儲存分配失敗");
            return t;
        }
        t.size+=1;
    }  
    //插入操作,需要將從插入位置開始的後續元素,逐個後移
    for (int i=t.length-1; i>=add-1; i--) {
        t.head[i+1]=t.head[i];
    }
    //後移完成後,直接將所需插入元素,新增到順序表的相應位置
    t.head[add-1]=elem;
    //由於添加了元素,所以長度+1
    t.length++;
    return t;
}

注意:在此程式中,當陣列儲存空間不足時,使用realloc函式每次額外多申請 1 個int型的儲存空間,這麼做還不是最優。最好的辦法就是每次發現空間不夠時,多申請幾個記憶體空間,這麼做的好處是:在後續做插入操作過程中不需要每次都執行realloc函式,提高了程式的執行效率。

順序表刪除元素

在陣列中刪除元素時,只需將該元素所在位置後的所有資料元素整體前移 1 個位置即可。
前移的過程中被刪除元素被後一個元素覆蓋掉,間接實現了刪除操作。 實現程式碼:
table delTable(table t,int add){
    if (add>t.length || add<1) {
        printf("被刪除元素的位置有誤");
        exit(0);
    }
    //刪除操作
    for (int i=add; i<t.length; i++) {
        t.head[i-1]=t.head[i];
    }
    t.length--;
    return t;
}

完整的程式

#include <stdio.h>
#include <stdlib.h>
#define Size 4
typedef struct Table{
    int * head;
    int length;
    int size;
}table;

table initTable(){
    table t;
    t.head=(int*)malloc(Size*sizeof(int));
    if (!t.head)
    {
        printf("初始化失敗");
        exit(0);
    }
    t.length=0;
    t.size=Size;
    return t;
}

table addTable(table t,int elem,int add)
{
    if (add>t.length+1||add<1) {
        printf("插入位置有問題");
        return t;
    }
    if (t.length>=t.size) {
        t.head=(int *)realloc(t.head, (t.size+1)*sizeof(int));
        if (!t.head) {
            printf("儲存分配失敗");
        }
        t.size+=1;
    }
    for (int i=t.length-1; i>=add-1; i--) {
        t.head[i+1]=t.head[i];
    }
    t.head[add-1]=elem;
    t.length++;
    return t;
}
table delTable(table t,int add){
    if (add>t.length || add<1) {
        printf("被刪除元素的位置有誤");
        exit(0);
    }
    for (int i=add; i<t.length; i++) {
        t.head[i-1]=t.head[i];
    }
    t.length--;
    return t;
}
int selectTable(table t,int elem){
    for (int i=0; i<t.length; i++) {
        if (t.head[i]==elem) {
            return i+1;
        }
    }
    return -1;
}
table amendTable(table t,int elem,int newElem){
    int add=selectTable(t, elem);
    t.head[add-1]=newElem;
    return t;
}
void displayTable(table t){
    for (int i=0;i<t.length;i++) {
        printf("%d",t.head[i]);
    }
    printf("\n");
}
int main(){
    table t1=initTable();
    for (int i=1; i<=Size; i++) {
        t1.head[i-1]=i;
        t1.length++;
    }
    printf("原順序表:\n");
    displayTable(t1);
   
    printf("刪除元素1:\n");
    t1=delTable(t1, 1);
    displayTable(t1);
   
    printf("在第2的位置插入元素5:\n");
    t1=addTable(t1, 5, 2);
    displayTable(t1);
   
    printf("查詢元素3的位置:\n");
    int add=selectTable(t1, 3);
    printf("%d\n",add);
   
    printf("將元素3改為6:\n");
    t1=amendTable(t1, 3, 6);
    displayTable(t1);
    return 0;
}
輸出結果:
原順序表:
1234
刪除元素1:
234
在第2的位置插入元素5:
2534
查詢元素3的位置:
3
將元素3改為6:
2564