0——靜態分配內存的順序表和動態分配內存的順序表的相同之處和不同之處
相同之處
-
基本操作邏輯相同:無論是靜態分配還是動態分配的順序表,其核心的操作邏輯是一致的。例如插入操作都需要將插入位置之后的元素依次后移,刪除操作都需要將刪除位置之后的元素依次前移,查找操作也都是通過遍歷或者直接定位來完成。
-
數據元素存儲方式相同:兩種順序表都是將數據元素依次存儲在連續的內存空間中,都可以通過數組下標來直接訪問元素,時間復雜度為?\(O(1)\)。
-
功能用途相同:都用于實現線性表的功能,支持數據的插入、刪除、查找等基本操作。
不同之處
-
內存分配方式:
-
靜態分配:在編譯時就確定了順序表的最大容量,使用數組來存儲元素,數組的大小在程序運行過程中不能改變。
-
動態分配:在程序運行時根據需要動態地分配內存空間,可以通過?
malloc
、realloc
?等函數來調整順序表的容量。
-
-
內存管理:
-
靜態分配:不需要手動管理內存,數組的內存空間由系統自動分配和釋放。
-
動態分配:需要手動管理內存,使用?
malloc
?分配內存,使用?free
?釋放內存,否則會造成內存泄漏。
-
-
表長限制:
-
靜態分配:順序表的最大長度是固定的,一旦達到最大長度就無法再插入新的元素。
-
動態分配:可以根據需要動態地調整順序表的容量,理論上只要系統有足夠的內存,就可以不斷地插入新的元素。
-
? ?純C語言代碼,不涉及C++? ?
代碼實現
0. 變量聲明
#include<stdio.h>
#include<stdlib.h>
#define InitSize 50 ?//初始容量
#define Increment 10 ?//每次擴容的增量
typedef int ElemType;
typedef struct SeqList {
?? ?ElemType* data; ?//動態分配數組的指針
?? ?int length; ? ? ?//順序表當前的長度(元素個數)
?? ?int capacity; ? ?//順序表當前容量
}SeqList;
1.初始化
void InitSeqList(SeqList* L) {L->data = (ElemType*)malloc(sizeof(ElemType) * InitSize);if (L->data == NULL){printf("內存分配失敗!\n");exit(1); // 退出系統操作}L->length = 0;L->capacity = InitSize;
}
2.擴容
void IncreaseCapacity(SeqList* L) {ElemType* newData = (ElemType*)realloc(L->data,(sizeof(ElemType)) * (InitSize + Increment));if (newData == NULL){printf("內存分配失敗!\n");exit(1); // 退出系統操作}L->data = newData;L->capacity += Increment;
}
3.插入
即:在第pos個位置插入value值,即在數組下標pos-1的位置插入value值
int InsertSeqList(SeqList* L,int pos ,ElemType value) {//1.判斷插入位置是否合法if (pos < 1 || pos > L->length + 1){printf("插入位置不合法!\n");return -1;}//2.判斷順序表存儲空間是否滿了if (L->length >= L->capacity){IncreaseCapacity(L); //空間不足,進行擴容操作}//3.將第pos個位置及往后的元素都后移一個位置,空出第pos個位置(這里采用逆序遍歷)for(int i = L->length; i >= pos; i++){L->data[i] = L->data[i - 1];}//4.插入數據L->data[pos - 1] = value;//5.表長加1L->length++;return 0; //插入成功
}
4.按位查找
即:返回第pos個位置對應的value值
int findValueByPos(SeqList* L, int pos, ElemType* value) {//1.判斷要查找的位置是否合理if (pos < 1 || pos > L->length){printf("查找位置不在當前順序表范圍內!\n");}//2.查找第pos個位置對應的value值*value = L->data[pos - 1];return 0; //查找成功
}
5.按值查找
即:返回value值對應的位序,即第幾個,下標是位序減1
int findPosByValue(SeqList* L, ElemType value) {for (int i = 0; i < L->length ; i++){if (L->data[i] == value) {return i + 1;}}return -1; //未在該順序表中找到該值
}
6.刪除
即:將第pos個的值賦值交給value變量存儲后騰開第pos個位置
? ? ?然后將第pos個后的數據都往前移動一個位置,填補第pos個位置
int deleteSeqList(SeqList* L, int pos,ElemType* value) {//1. 判斷刪除位置是否合理,即是否在存有數據的范圍內if (pos < 1 || pos > L->length){printf("待刪除位置不在合理范圍內!\n");return -1; }//2. 判斷空間是否為空if (L->length == 0){printf("當前空間未存有數據,無法完成刪除操作!\n");}//3.將要被刪除的數據賦值(轉存于)value變量*value = L->data[pos - 1];//4.將第pos個位置往后的元素都往前挪一個位置for (int i = pos; i < L->length; i++){L->data[i - 1] = L->data[i];}//5.表長減1L->length--;return 0; //刪除成功
}
7.注銷
void destroySeqList(SeqList* L) {if (L->data != NULL){free(L->data);L->data = NULL;L->length = 0;L->capacity = 0;}
}
8.打印
void printSeqList(SeqList* L) {if (L->length == 0){printf("當前順序表為空!\n");}else {for (int i = 0; i < L->length ; i++){if (i == L->length - 1) {printf("%d", L->data[i]);}else{printf("%d ", L->data[i]);}}printf("\n");}printf("--------------------------------------------------\n");
}
9.測試代碼
int main() {SeqList L;InitSeqList(&L);//插入數據測試if (InsertSeqList(&L,1,18) != 0){printf("插入失敗!\n");}if (InsertSeqList(&L,2,7) != 0){printf("插入失敗!\n");}if (InsertSeqList(&L,3,34) != 0){printf("插入失敗!\n");}printSeqList(&L); // 18 7 34//刪除數據測試ElemType value;if (deleteSeqList(&L, 2, &value) != 0){printf("刪除失敗!\n");}printSeqList(&L); // 18 34//按位查找測試,查找第1位的值是什么ElemType val;if (findValueByPos(&L,1,&val) == 0){printf("第1位的數據為:%d\n", val); //第1位的數據為:18}else{printf("查找失敗!\n");}//按值查找測試,查找18在順序表的第幾個位置int pos = findPosByValue(&L, 18);if (pos != -1){printf("值18在順序表的第%d個位置\n", pos); //值18在順序表的第1個位置}else{printf("查找失敗!\n");}//測試完記得執行銷毀操作,釋放空間內存destroySeqList(&L);return 0;
}
10.完整代碼
#include<stdio.h>
#include<stdlib.h>#define InitSize 50 //初始容量
#define Increment 10 //每次擴容的增量
typedef int ElemType;typedef struct SeqList {ElemType* data; //動態分配數組的指針int length; //順序表當前的長度(元素個數)int capacity; //順序表當前容量
}SeqList;// 操作1——初始化
void InitSeqList(SeqList* L) {L->data = (ElemType*)malloc(sizeof(ElemType) * InitSize);if (L->data == NULL){printf("內存分配失敗!\n");exit(1); // 退出系統操作}L->length = 0;L->capacity = InitSize;
}// 增加順序表的容量
void IncreaseCapacity(SeqList* L) {ElemType* newData = (ElemType*)realloc(L->data,(sizeof(ElemType)) * (InitSize + Increment));if (newData == NULL){printf("內存分配失敗!\n");exit(1); // 退出系統操作}L->data = newData;L->capacity += Increment;
}//操作2——插入:在第pos個位置插入value值,即在數組下標pos-1的位置插入value值
int InsertSeqList(SeqList* L,int pos ,ElemType value) {//1.判斷插入位置是否合法if (pos < 1 || pos > L->length + 1){printf("插入位置不合法!\n");return -1;}//2.判斷順序表存儲空間是否滿了if (L->length >= L->capacity){IncreaseCapacity(L); //空間不足,進行擴容操作}//3.將第pos個位置及往后的元素都后移一個位置,空出第pos個位置(這里采用逆序遍歷)for(int i = L->length; i >= pos; i++){L->data[i] = L->data[i - 1];}//4.插入數據L->data[pos - 1] = value;//5.表長加1L->length++;return 0; //插入成功
}// 操作3——按位查找,即返回第pos個位置對應的value值
int findValueByPos(SeqList* L, int pos, ElemType* value) {//1.判斷要查找的位置是否合理if (pos < 1 || pos > L->length){printf("查找位置不在當前順序表范圍內!\n");}//2.查找第pos個位置對應的value值*value = L->data[pos - 1];return 0; //查找成功
}// 操作4——按值查找,即返回value值對應的位序,即第幾個,下標是位序減1
int findPosByValue(SeqList* L, ElemType value) {for (int i = 0; i < L->length ; i++){if (L->data[i] == value) {return i + 1;}}return -1; //未在該順序表中找到該值
}// 操作5——刪除:將第pos個的值賦值交給value變量存儲后騰開第pos個位置
// 然后將第pos個后的數據都往前移動一個位置,填補第pos個位置
int deleteSeqList(SeqList* L, int pos,ElemType* value) {//1. 判斷刪除位置是否合理,即是否在存有數據的范圍內if (pos < 1 || pos > L->length){printf("待刪除位置不在合理范圍內!\n");return -1; }//2. 判斷空間是否為空if (L->length == 0){printf("當前空間未存有數據,無法完成刪除操作!\n");}//3.將要被刪除的數據賦值(轉存于)value變量*value = L->data[pos - 1];//4.將第pos個位置往后的元素都往前挪一個位置for (int i = pos; i < L->length; i++){L->data[i - 1] = L->data[i];}//5.表長減1L->length--;return 0; //刪除成功
}// 操作6——注銷
void destroySeqList(SeqList* L) {if (L->data != NULL){free(L->data);L->data = NULL;L->length = 0;L->capacity = 0;}
}//操作7——打印順序表中存放的數據
void printSeqList(SeqList* L) {if (L->length == 0){printf("當前順序表為空!\n");}else {for (int i = 0; i < L->length ; i++){if (i == L->length - 1) {printf("%d", L->data[i]);}else{printf("%d ", L->data[i]);}}printf("\n");}printf("--------------------------------------------------\n");
}int main() {SeqList L;InitSeqList(&L);//插入數據測試if (InsertSeqList(&L,1,18) != 0){printf("插入失敗!\n");}if (InsertSeqList(&L,2,7) != 0){printf("插入失敗!\n");}if (InsertSeqList(&L,3,34) != 0){printf("插入失敗!\n");}printSeqList(&L); // 18 7 34//刪除數據測試ElemType value;if (deleteSeqList(&L, 2, &value) != 0){printf("刪除失敗!\n");}printSeqList(&L); // 18 34//按位查找測試,查找第1位的值是什么ElemType val;if (findValueByPos(&L,1,&val) == 0){printf("第1位的數據為:%d\n", val); //第1位的數據為:18}else{printf("查找失敗!\n");}//按值查找測試,查找18在順序表的第幾個位置int pos = findPosByValue(&L, 18);if (pos != -1){printf("值18在順序表的第%d個位置\n", pos); //值18在順序表的第1個位置}else{printf("查找失敗!\n");}//測試完記得執行銷毀操作,釋放空間內存destroySeqList(&L);return 0;
}
11.運行截圖
如有問題,歡迎指出!
謝謝!