目錄
一.什么是順序表?
二.靜態順序表和動態順序表的不同點
三.什么是靜態順序表
四:函式介面實作
1.初始化結構體
2.列印資料
3.頭插資料
4.尾插資料
5.頭刪資料
6.尾刪資料
附:原碼鏈接
一.什么是順序表?
順序表是用一段物理地址連續的存盤單元依次存盤資料元素的線性結構,一般情況下采用陣列存盤,在陣列上完成資料的增刪查改,其中順序表又分為:靜態順序表和動態順序表,
簡單來說:順序表:連續的物理空間存盤---是陣列 ,資料必須是從頭開始,依次存盤,
二.靜態順序表和動態順序表的不同點
1. 靜態順序表:使用定長陣列存盤,
2. 動態順序表:使用動態開辟的陣列存盤,
其中,因為動態順序表是動態開辟的,所以最后還要釋放(free)空間,下面我們來看看是怎么用靜態順序表進行增刪查改操作的,至于動態順序表,請看筆者的下一篇文章!
三.什么是靜態順序表
首先靜態順序表是用陣列存盤的,我們還要標識有多少個有效數字,所以我們可以定義一個結構體,
struct SeqList { int arr[50]; //陣列用來存盤資料 int size; //標識有效資料個數 };
為了方便后續更改資料型別以及陣列的大小,我們用#define宏定義陣列大小,typedef將資料型別進行重命名,這樣的話以后要更改型別,或者更改陣列大小只需更改一處位置即可,增加了程式的可維護性,
->
//注意:#define后面不加分號 //typedef后面加分號 #define Max_size 10 typedef int SeqlistType; typedef struct Seqlist { SeqlistType arr[Max_size]; //定長陣列 SeqlistType size; //有效個數 }SQ;
四:函式介面實作
1.初始化結構體
起初沒有有效數字,所以我們定義size為0,用menset初始化陣列,按位元組個數初始化,
注意事項:我們創建結構體變數,傳參如果只傳值,對形參的改變并不會影響實參,形參只是實參的一份臨時拷貝,所以我們要傳結構體變數的地址,用結構體指標接收,!!!
void SeqlistInit(SQ* s) { memset(s->arr, 0, sizeof(SeqlistType) * Max_size); s->size = 0; //最初沒有有效數字 }
2.列印資料
注意:列印只需遍歷陣列即可,不會對結構體進行修改,所以傳值,傳址都可以!
方法1:傳值
void SeqlistPrint(SQ s) { int i = 0; for (i = 0; i < s.size; i++) { printf("%d ", s.arr[i]); } printf("\n"); }
方法2:傳址
void SeqlistPrint(SQ* s) { int i = 0; for (i = 0; i < s->size; i++) { printf("%d ", s->arr[i]); } }
3.頭插資料
注意:因為陣列是定長陣列,所以插入資料時要先保證陣列中還有空位置,要進行判斷!
頭插:即把資料放到arr[0]的位置,只需要把原來陣列的資料向后移動即可,插入資料后,有效個數要記得+1.
注意:要從最后邊開始移動,如果從前面開始移動,會造成把后面的資料覆寫掉,
void SeqlistPushFront(SQ* s,SeqlistType x) { //要保證不越界 if (s->size == Max_size) { printf("滿了\n"); return ; } int i = 0; //把資料后移 for (i = s->size; i > 0; i--) { s->arr[i ] = s->arr[i-1]; } //插入 s->arr[0] = x; //有效數字+1 s->size++; }
4.尾插資料
同理,尾插也要保證資料還有空位置,
尾插資料只需把資料放入到陣列的arr[ps->size]位置即可,陣列的下標從0開始,而size是用來標識有效個數的,
插入前:
插入后:
->代碼實作
//尾插 void SeqlistPushBack(SQ* s ,SeqlistType x) { //要保證不越界 if (s->size == Max_size) { printf("滿了\n"); return; } s->arr[s->size] = x; s->size++; }
5.頭刪資料
頭刪:即去掉陣列arr[0]的元素, ->將后面的元素向前覆寫, 這次不同于頭插,這次要從前開始覆寫!!! 洗掉一個元素 ->size--
//頭刪 void SeqlistPopFront(SQ* s) { int i = 0; for (i = 0; i < s->size; i++) { s->arr[i] = s->arr[i+1]; } s->size--; }
6.尾刪資料
因為size是標識有效個數的,用size來控制列印,只需要size--,就相當于把最后一位資料給去掉了,但最后一個資料還在陣列空間內,但是我們已經訪問不到了,
void SeqlistPopBack(SQ* s) { s->size--; }
注意事項:
1.傳參是傳值還是傳地址的問題,
傳值:形參是實參的一份臨時拷貝,對形參的修改并不會影響實參,
傳地址:對形參的修改就是對實參的修改,
2.插入資料前要先判斷陣列是否滿了,否則會造成資料越界問題,
3.size是用來標識有效個數的,插入/洗掉資料后,size也要發生變化,
原碼(含游戲選單):
SeqList.h 檔案總放函式宣告以及型別重定義之類的
#define _CRT_SECURE_NO_WARNINGS 1 #pragma once //在.h檔案中 #include<stdio.h> #include <string.h> //注意:#define后面不加分號 //typedef后面加分號 #define Max_size 10 typedef int SeqlistType; //創建結構體型別 typedef struct Seqlist { SeqlistType arr[Max_size]; //定長陣列 SeqlistType size; //有效個數 }SQ; //要改變結構體內容就傳地址,不改變內容傳地址,傳值都可以 //初始化結構體 void SeqlistInit(SQ* s); //列印結構體 void SeqlistPrint(SQ s); //頭插 void SeqlistPushFront(SQ* s, SeqlistType x); //尾插 void SeqlistPushBack(SQ* s,SeqlistType x); //頭刪 void SeqlistPopFront(SQ* s); //尾刪 void SeqlistPopBack(SQ* s);
在Seqlist.檔案中實作介面函式
#define _CRT_SECURE_NO_WARNINGS 1 #pragma once #include"Seqlish.h" //初始化結構體 void SeqlistInit(SQ* s) { memset(s->arr, 0, sizeof(SeqlistType) * Max_size); s->size = 0; //最初沒有有效數字 } //列印結構體 傳值時 void SeqlistPrint(SQ s) { int i = 0; for (i = 0; i < s.size; i++) { printf("%d ", s.arr[i]); } printf("\n"); } 傳地址時 //void SeqlistPrint(SQ* s) //{ // int i = 0; // for (i = 0; i < s->size; i++) // { // printf("%d ", s->arr[i]); // } //} //頭插 void SeqlistPushFront(SQ* s,SeqlistType x) { //要保證不越界 if (s->size == Max_size) { printf("滿了\n"); return ; } int i = 0; //把資料后移 for (i = s->size; i > 0; i--) { s->arr[i ] = s->arr[i-1]; } //插入 s->arr[0] = x; //有效數字+1 s->size++; } //尾插 void SeqlistPushBack(SQ* s ,SeqlistType x) { //要保證不越界 if (s->size == Max_size) { printf("滿了\n"); return; } s->arr[s->size] = x; s->size++; } //尾刪 void SeqlistPopBack(SQ* s) { s->size--; } //頭刪 void SeqlistPopFront(SQ* s) { int i = 0; for (i = 0; i < s->size; i++) { s->arr[i] = s->arr[i+1]; } s->size--; }
在test.c檔案中測驗介面有無問題 (含游戲選單)
#define _CRT_SECURE_NO_WARNINGS 1 #pragma once #include"Seqlish.h" void menu() { printf("************************************\n"); printf("*******1.頭插資料 2.尾插資料********\n"); printf("*******3.頭刪資料 4.尾刪資料********\n"); printf("******** 0.exit ********\n"); } int main() { //定義結構體變數 SQ s1; SeqlistInit(&s1); int input = 0; int n = 0; do { menu(); printf("請輸入你的選擇->\n"); scanf("%d", &input); switch (input) { case 1:printf("進行頭插操作,請輸入你要插入的數字->\n"); scanf("%d", &n); //頭插 SeqlistPushFront(&s1, n); printf("插入后順序為:->"); SeqlistPrint(s1); break; case 2: printf("進行尾插操作,請輸入你要插入的數字->\n"); scanf("%d", &n); //尾插 SeqlistPushBack(&s1, n); printf("插入后順序為:->"); SeqlistPrint(s1); break; case 3 : if (s1.size > 0) { printf("進行頭刪操作,原順序為:->"); SeqlistPrint(s1); printf("洗掉后->"); SeqlistPopFront(&s1); SeqlistPrint(s1); } else printf("請先插入資料\n"); break; case 4: if (s1.size > 0) { printf("進行尾刪操作,原順序為:->"); SeqlistPrint(s1); printf("洗掉后->"); SeqlistPopBack(&s1); SeqlistPrint(s1); } else printf("請先插入資料\n"); break; case 0: printf("退出成功\n"); break; default:printf("選擇錯誤,重新選擇\n"); break; } } while (input); }
附:原碼鏈接
歡迎大家到我的gitee獲取原碼檔案!
https://gitee.com/maple-that-never-stays-up-late/my_code-source/tree/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84
下一篇博客,我將帶大家深入了解動態順序表~歡迎各位大佬關注,如有錯誤歡迎批評指正!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/293364.html
標籤:其他



->代碼實作