實現(xiàn)具有普適性的隊列創(chuàng)建方法
方法學了很久了,應(yīng)該把它記錄下來了,好記憶不如爛筆頭,什么事情久了都會有遺忘的現(xiàn)象,記下來總歸是好的。
1、為什么這么做
在編程中隊列的使用應(yīng)該是比較多的,在剛學習編程學習到都最基本的隊列創(chuàng)建方法,后來在編程中都會照著初學時的模版然后依照不同的數(shù)據(jù)去創(chuàng)建隊列。如果是這樣那么每次遇到新的要求可能就會重新寫一次代碼,做重復(fù)的事情是沒有意義的,所以我不應(yīng)該做重復(fù)的工作。應(yīng)該找到一種方法,且方法具有普適性,這樣才能更高效的完成工作。
2、該如何做
隊列的實現(xiàn)無非就是實現(xiàn)鏈表,最基本的鏈表的實現(xiàn)方式都會,但是很多鏈表都又一個共同的模式,在C語言中就是實現(xiàn)一個結(jié)構(gòu)體,在結(jié)構(gòu)體中定義一個結(jié)構(gòu)體指針作為尋找下一節(jié)點的參數(shù),然后就是結(jié)構(gòu)體的其他參數(shù)。就像尋寶游戲,每找到一個線索就會知道下一個線索的信息,一環(huán)扣一環(huán),最終找到寶藏。鏈表作用不是去尋寶,而是在每個線索點存放數(shù)據(jù)。仔細想一下,如果我們不在線索的節(jié)點放任何東西,那這條鏈還是不是環(huán)環(huán)相扣的呢?答案是肯定的,因為即使不放東西,對于鏈表的連接是沒有影響的。既然沒有影響,就可以想到其實鏈表的關(guān)鍵部分不是有沒有數(shù)據(jù),而是有沒有連接下一環(huán)的扣子。數(shù)據(jù)只是每一個扣子的附屬品。既然將數(shù)據(jù)剝離開了,隊列實現(xiàn)的普遍性的方法也就提煉出來。
3、具體實例
代碼是老大寫的,分享一下,學習一下這種思想。
queue.c實現(xiàn)
struct chain_t{
struct chain_t *next;
};
void mount(void **__chain, void *__p ){
struct chain_t **chain = (struct chain_t **)__chain;
struct chain_t *p = (struct chain_t *)__p;
if(p == NULL){return;}
if(*chain == NULL){
*chain = p;
*chain->next = NULL;
}else{
struct chain_t *q = NULL;
for(q = *chain; q->next != NULL;q=q->next);
q->next = p;
p->next = NULL;
}
}
void unmount(void **_chain, void *__p){
struct chain_t **chain = (struct chain_t **)__chain;
struct chain_t *p = (struct chain_t *)__p;
if(p == NULL){return;}
if(*chain == NULL){return;}
else{
struct chain_t *q = NULL;
if(*chain == p){*chain = p->next; p->next = NULL; return;}
else{
for(q = *chain; q->next != NULL; q=q->next){
if(q->next == p) {q->next = p->next;p->next = NULL; return;}
}
}
}
}
使用實例:
struct data_t{
struct data_t *next;
uint8_t data
};
struct data_t *queue = NULL;
struct data_t *p = (struct data_t *)malloc(sizeof(struct data_t));
if(p != NULL){
mount(&queue, p); // <! 將節(jié)點加入到隊列
}
unmount(&queue, p); // <! 將節(jié)點從隊列刪除
free(p); // <! **不要忘記釋放節(jié)點**