順序表
順序表
(順序儲存結構)及初始化詳解
順序表,全名順序儲存結構,是線性表的一種。通過《什麼是線性表》一節的學習我們知道,線性表用於儲存邏輯關係為“一對一”的資料,順序表自然也不例外。
不僅如此,順序表對資料的物理儲存結構也有要求。順序表儲存資料時,會提前申請一整塊足夠大小的物理空間,然後將資料依次儲存起來,儲存時做到資料元素之間不留一絲縫隙。
例如,使用順序表儲存集合 {1,2,3,4,5}
,資料最終的儲存狀態如圖 1 所示:
圖 1 順序儲存結構示意圖
由此我們可以得出,將“具有 ‘一對一’ 邏輯關係的資料按照次序連續儲存到一整塊物理空間上”的儲存結構就是順序儲存結構。
通過觀察圖 1 中資料的儲存狀態,我們可以發現,順序表儲存資料同陣列非常接近。其實,順序表儲存資料使用的就是陣列。
順序表的初始化
使用順序表儲存資料之前,除了要申請足夠大小的物理空間之外,為了方便後期使用表中的資料,順序表還需要實時記錄以下 2 項資料:
- 順序表申請的儲存容量;
- 順序表的長度,也就是表中儲存資料元素的個數;
提示:正常狀態下,順序表申請的儲存容量要大於順序表的長度。
因此,我們需要自定義順序表,C 語言實現程式碼如下:
typedef struct Table{
int * head;//宣告瞭一個名為head的長度不確定的陣列,也叫“動態陣列”
int length;//記錄當前順序表的長度
int size;//記錄順序表分配的儲存容量
}table;
注意,head 是我們宣告的一個未初始化的動態陣列,不要只把它看做是普通的指標。
接下來開始學習順序表的初始化,也就是初步建立一個順序表。建立順序表需要做如下工作:
- 給 head 動態資料申請足夠大小的物理空間;
- 給 size 和 length 賦初值;
因此,C 語言實現程式碼如下:
#define Size 5 //對Size進行巨集定義,表示順序表申請空間的大小
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;
}
我們看到,整個順序表初始化的過程被封裝到了一個函式中,此函式返回值是一個已經初始化完成的順序表。這樣做的好處是增加了程式碼的可用性,也更加美觀。與此同時,順序表初始化過程中,要注意對物理空間的申請進行判斷,對申請失敗的情況進行處理,這裡只進行了“輸出提示資訊和強制退出”的操作,可以根據你自己的需要對程式碼中的 if 語句進行改進。
通過在主函式中呼叫 initTable 語句,就可以成功建立一個空的順序表,與此同時我們還可以試著向順序表中新增一些元素,C 語言實現程式碼如下:
#include <stdio.h>
#include <stdlib.h>
#define Size 5
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;
}
//輸出順序表中元素的函式
void displayTable(table t){
for (int i=0;i<t.length;i++) {
printf("%d ",t.head[i]);
}
printf("\n");
}
int main(){
table t=initTable();
//向順序表中新增元素
for (int i=1; i<=Size; i++) {
t.head[i-1]=i;
t.length++;
}
printf("順序表中儲存的元素分別是:\n");
displayTable(t);
return 0;
}
程式執行結果如下:
順序表中儲存的元素分別是:
1 2 3 4 5
可以看到,順序表初始化成功。
順序表的基本操作
我們學習了順序表及初始化的過程,本節學習有關順序表的一些基本操作,以及如何使用 C 語言實現它們。
順序表插入元素
向已有順序表中插入資料元素,根據插入位置的不同,可分為以下 3 種情況:
- 插入到順序表的表頭;
- 在表的中間位置插入元素;
- 尾隨順序表中已有元素,作為順序表中的最後一個元素;
雖然資料元素插入順序表中的位置有所不同,但是都使用的是同一種方式去解決,即:通過遍歷,找到資料元素要插入的位置,然後做如下兩步工作:
- 將要插入位置元素以及後續的元素整體向後移動一個位置;
- 將元素放到騰出來的位置上;
例如,在 {1,2,3,4,5}
的第 3 個位置上插入元素 6,實現過程如下:
-
遍歷至順序表儲存第 3 個資料元素的位置,如圖 1 所示:
圖 1 找到目標元素位置 -
將元素 3 以及後續元素 4 和 5 整體向後移動一個位置,如圖 2 所示:
圖 2 將插入位置騰出 -
將新元素 6 放入騰出的位置,如圖 3 所示:
圖 3 插入目標元素
因此,順序表插入資料元素的 C 語言實現程式碼如下:
//插入函式,其中,elem為插入的元素,add為插入到順序表的位置
table addTable(table t,int elem,int add)
{
//判斷插入本身是否存在問題(如果插入元素位置比整張表的長度+1還大(如果相等,是尾隨的情況),或者插入的位置本身不存在,程式作為提示並自動退出)
if (add>t.length+1||add<1) {
printf("插入位置有問題\n");
return t;
}
//做插入操作時,首先需要看順序表是否有多餘的儲存空間提供給插入的元素,如果沒有,需要申請
if (t.length==t.size) {
t.head=(int *)realloc(t.head, (t.size+1)*sizeof(int));
if (!t.head) {
printf("儲存分配失敗\n");
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 函式。並且,在實現後續元素整體後移的過程,目標位置其實是有資料的,還是 3,只是下一步新插入元素時會把舊元素直接覆蓋。
順序表刪除元素
從順序表中刪除指定元素,實現起來非常簡單,只需找到目標元素,並將其後續所有元素整體前移 1 個位置即可。
後續元素整體前移一個位置,會直接將目標元素刪除,可間接實現刪除元素的目的。
例如,從 {1,2,3,4,5}
中刪除元素 3 的過程如圖 4 所示:
圖 4 順序表刪除元素的過程示意圖
因此,順序表刪除元素的 C 語言實現程式碼為:
table delTable(table t,int add){
if (add>t.length || add<1) {
printf("被刪除元素的位置有誤\n");
return t;
}
//刪除操作
for (int i=add; i<t.length; i++) {
t.head[i-1]=t.head[i];
}
t.length--;
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
}
順序表更改元素
順序表更改元素的實現過程是:
- 找到目標元素;
- 直接修改該元素的值;
順序表更改元素的 C 語言實現程式碼為:
//更改函式,其中,elem為要更改的元素,newElem為新的資料元素
table amendTable(table t,int elem,int newElem){
int add=selectTable(t, elem);
t.head[add-1]=newElem;//由於返回的是元素在順序表中的位置,所以-1就是該元素在陣列中的下標
return t;C
}
以上是順序表使用過程中最常用的基本操作,這裡給出本節完整的實現程式碼:
#include <stdio.h>
#include <stdlib.h>
#define Size 5
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("初始化失敗\n");
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("插入位置有問題\n");
return t;
}
if (t.length>=t.size) {
t.head=(int *)realloc(t.head, (t.size+1)*sizeof(int));
if (!t.head) {
printf("儲存分配失敗\n");
}
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("被刪除元素的位置有誤\n");
return t;
}
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;
}
程式執行結果為:
原順序表:
1 2 3 4 5
刪除元素1:
2 3 4 5
在第2的位置插入元素5:
2 5 3 4 5
查詢元素3的位置:
3
將元素3改為6:
2 5 6 4 5
相關文章
- 順序表應用5:有序順序表歸併
- 順序表應用6:有序順序表查詢
- 第2章 順序表及其順序儲存
- 順序表的學習
- 順序表的實現
- Java實現順序表Java
- 順序表的堆排序排序
- 順序表有序插入資料
- DS順序表--類實現
- 資料結構 - 線性表 - 順序表資料結構
- 順序表實現二分排序排序
- 考研資料結構-線性表-順序表資料結構
- 線性表-順序表C語言實現C語言
- 線性表的順序儲存-順序表,對“突然的自我”的否定,對自我的揚棄
- 線性表的使用——順序實現
- 隨筆:MySQL 普通3表join順序MySql
- C++ 運算子優先順序表C++
- 連結串列,樹,順序表操縱
- 線性表之順序儲存結構
- python運算子及優先順序順序Python
- 5-順序表查詢及插入問題
- Script載入順序 & 外部樣式表的阻塞
- 第3章 順序表的鏈式儲存
- 11 線性表的順序儲存結構
- 資料結構與演算法 | 線性表 —— 順序表資料結構演算法
- 資料結構實驗一:順序表的建立與操作實現、順序表實現約瑟夫環問題資料結構
- SpringBoot配置檔案優先順序載入順序Spring Boot
- 資料結構_順序表_順序表的初始化、插入、刪除、修改、查詢列印(基於C語言實現)資料結構C語言
- UML順序圖
- 順序查詢
- 順序結構
- 順序刷題
- 2.1第二章作業1-順序表
- 順序表的基本方法實現C語言版C語言
- 線性表的順序儲存C++程式碼C++
- c運算子優先順序表-最全c語言運算子優先順序和結合性對照表C語言
- python演算法與資料結構-順序表(37)Python演算法資料結構
- 能否在Oracle資料庫表中指定列順序OKOracle資料庫