新手向超詳細的C語言實現(xiàn)動態(tài)順序表
一、各個函數(shù)接口的實現(xiàn)
1.1 不太好‘'李姐‘'的“容量檢測函數(shù)”
對順序表進行插入數(shù)據(jù)時,需要判斷順序表的容量是否充足,增加數(shù)據(jù)的同時需要反復地檢測容量,所以推薦直接將以上步驟封裝成一個函數(shù)。
函數(shù)實現(xiàn)算法:若容量大小 == 有效數(shù)據(jù)大小,則為現(xiàn)有順序表增容一倍的空間。
但是需要注意的是:初始順序表后,容量為0,則需開辟4個有效數(shù)據(jù)的空間。
void SeqListCheckCapacity(SLT* psl) { assert(psl); if (psl->size == psl->capacity) { size_t newcapacity = psl->capacity == 0 ? 4 : (psl->capacity) * 2; psl->a = (SQDatatype*)realloc(psl->a, sizeof(SQDatatype) * newcapacity); psl->capacity = newcapacity; } }
1.2 在任意位置插入的函數(shù)"坑!"
算法實現(xiàn):首先檢測容量,再通過想要插入的下標找到位置,將包括該下標的元素以及其后的所有元素往后挪一步,最后在該下標位置放入數(shù)據(jù)。
void SeqListInsert(SLT* psl, size_t pos, SQDatatype x) { assert(psl); assert(pos >= 0 && pos <= psl->size); SeqListCheckCapacity(&psl); int end = psl->size - 1; while (end >= pos) { psl->a[end + 1] = psl->a[end]; end--; } psl->a[pos] = x; psl->size++; }
考慮到下標pos一定是個非負整數(shù),故使用size_t類型。
如果利用該函數(shù)進行頭插,即pos == 0;在while循環(huán)的最后一步,即end == pos時,end--后end變成-1,再回到while循環(huán)的判斷條件時,end會出現(xiàn)整形提升的情況,即-1變成無符號整形,約為21億。
end出現(xiàn)整形提升的原因在于pos是size_t類型。
解決方法就是保證while循環(huán)中和pos比較的式子為非負數(shù)即可。
void SeqListInsert(SLT* psl, size_t pos, SQDatatype x) { assert(psl); assert(pos >= 0 && pos <= psl->size); SeqListCheckCapacity(psl); int end = psl->size; while (end >= pos + 1) { psl->a[end] = psl->a[end - 1]; end--; } psl->a[pos] = x; psl->size++; }
1.3 在任意位置刪除數(shù)據(jù)的函數(shù)
算法思路:把指定元素之后的所有元素全部向前挪動一步。
void SeqListErase(SLT* psl, size_t pos) { assert(psl); assert(pos >= 0 && pos < psl->size); size_t begin = pos; if (begin == psl->size - 1) { psl->size--; return; } while (begin < psl->size - 1) { psl->a[begin] = psl->a[begin + 1]; begin++; } psl->size--; }
上述代碼中if條件語句用于判斷是否為尾刪。
注意:避免負數(shù)與無符號數(shù)通過操作符連接,避免有符號數(shù)變成負數(shù)后被整型提升為無符號數(shù)或者強制轉(zhuǎn)換。
1.4 其余簡單的接口函數(shù)
初始化函數(shù)
void SeqListInit(SLT* psl) { assert(psl); psl->a = NULL; psl->capacity = psl->size = 0; }
銷毀函數(shù)
void SeqListDestory(SLT* psl) { assert(psl); if (psl->a) { free(psl->a); psl->a = NULL; } psl->capacity = psl->size = 0; }
打印函數(shù)
void SeqListPrint(SLT* psl) { assert(psl); int i = 0; for (i = 0; i < psl->size; i++) { printf("%d ", psl->a[i]); } printf("\n"); }
尾插
void SeqListPushBack(SLT* psl, SQDatatype x) { assert(psl); SeqListCheckCapacity(psl); psl->a[psl->size] = x; psl->size++; }
頭插
void SeqListPushFront(SLT* psl, SQDatatype x) { assert(psl); SeqListCheckCapacity(psl); int i = 0; for (i = psl->size - 1; i >= 0; i--) { psl->a[i + 1] = psl->a[i]; } psl->a[0] = x; psl->size++; }
尾刪
void SeqListPopBack(SLT* psl) { assert(psl); psl->size--; }
頭刪
{ assert(psl); assert(psl->size > 0); int begin = 0; while (begin < psl->size - 1) { psl->a[begin] = psl->a[begin + 1]; begin++; } psl->size--; }
通過數(shù)據(jù)查找下標
int SeqListFind(SLT* psl, SQDatatype x) { assert(psl); int begin = 0; while (begin < psl->size) { if (x == psl->a[begin]) return begin; begin++; } return -1; }
二、順序表結(jié)構(gòu)體聲明與定義
typedef int SQDatatype;
重定義可方便以后更換元素類型時修改
typedef struct SeqList { SQDatatype* a; int size; int capacity; }SLT;
重定義可以讓定義結(jié)構(gòu)體對象(變量)時,免去代碼的冗余。
如struct SeqList s1;可修改為SLT s1;
三、頭文件的調(diào)用
- #include<stdio.h>標準輸入輸出
- #include<assert.h>斷言錯誤,避免空指針對程序的影響
- #include<stdlib.h>動態(tài)函數(shù)
到此這篇關(guān)于新手向超詳細的C語言實現(xiàn)動態(tài)順序表的文章就介紹到這了,更多相關(guān)C語言動態(tài)順序表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言 如何求兩整數(shù)的最大公約數(shù)與最小公倍數(shù)
這篇文章主要介紹了C語言中如何求兩整數(shù)的最大公約數(shù)與最小公倍數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11一道超經(jīng)典的C++結(jié)構(gòu)體的題目
以下小編就為大家介紹一道超經(jīng)典的關(guān)于C++結(jié)構(gòu)體的題目。需要的朋友可以過來參考下2013-09-09用C語言實現(xiàn)從文本文件中讀取數(shù)據(jù)后進行排序的功能
這是一個十分可靠的程序,這個程序的查錯能力非常強悍。程序包含了文件操作,歸并排序和字符串輸入等多種技術(shù)。對大家學習C語言很有幫助,有需要的一起來看看。2016-08-08Qt圖形圖像開發(fā)之Qt曲線圖美化QChart QScatterSeries 空心點陣圖,鼠標移動到上面顯示數(shù)值,鼠標移開
這篇文章主要介紹了Qt圖形圖像開發(fā)之Qt曲線圖美化QChart QScatterSeries 空心點陣圖,鼠標移動到上面顯示數(shù)值,鼠標移開數(shù)值消失效果實例,需要的朋友可以參考下2020-03-03