順序表的基本操作及C語言完整實現
阿新 • • 發佈:2018-12-16
對順序表進行操作,大致可分為以下幾類:
以上操作各自的原理及實現如下所示。
實現程式碼:
無論在順序表的什麼位置插入資料元素,解決辦法都是:找到要插入的位置,將後續資料元素整體向後移動一個位置,最後直接在騰出來的位置上插入資料元素。
實現程式碼:
前移的過程中被刪除元素被後一個元素覆蓋掉,間接實現了刪除操作。 實現程式碼:
- 表的建立;
- 表中新增(新增)資料元素;
- 表中刪除資料元素;
- 表中查詢指定資料元素;
- 表中更改某資料元素;
以上操作各自的原理及實現如下所示。
順序表的建立
順序表的建立,也就是順序表進行初始化,在預先申請記憶體空間的同時,給變數 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; }
順序表插入元素
插入資料元素,無非三種情況:- 在表頭插入
- 在表的中間某個位置插入
- 直接尾隨順序表,作為表的最後一個元素
無論在順序表的什麼位置插入資料元素,解決辦法都是:找到要插入的位置,將後續資料元素整體向後移動一個位置,最後直接在騰出來的位置上插入資料元素。
實現程式碼:
//插入函式,其中,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