相比一般鏈表,這種鏈表實現起來更加方便,也比較靈活
這個實現是從下面這個視頻裏學到的:
https://www.bilibili.com/video/av70711015?p=10
類似於Linux內核中的鏈表,不過是單向鏈表,並且把用於鏈接的節點放在首部
數據結構及接口(Improved_Header_List.h)
#ifndef IMPROVED_HEADER_LIST_H_INCLUDED
#define IMPROVED_HEADER_LIST_H_INCLUDED
/*注意:
在編寫鏈表時,我們並不考慮數據的內存申請釋放問題。
用戶使用時數據定義在棧上或堆上。
如果必須在鏈表內考慮釋放問題,那麼可以對函數RemoveByPos
和 Destroy進行改寫,添加參數,讓用戶傳參作爲標識
來決定是否釋放內存
如不懂可參考:
https://www.bilibili.com/video/av70711015?p=13
從6:45開始觀看
*/
#include <stdlib.h>
#include <stdio.h>
typedef struct Node{
struct Node *next;
}Node;
typedef struct HeaderList{
Node head;
int Hsize;
}HeaderList;
typedef void(*PRINTNODE)(Node*);
HeaderList* Create_HeaderList(void);
void Destroy_HeaderList(HeaderList* hlist);
void InsertByPos_HeaderList(HeaderList *hlist,int pos,Node *data);
void RemoveByPos_HeaderList(HeaderList *hlist,int pos);
void Clear_HeaderList(HeaderList *hlist);
Node* GetByPos_HeaderList(HeaderList *hlist,int pos); // 不存在時有可能返回NULL
int GetSize_HeaderList(HeaderList *hlist);
void Print_HeaderList(HeaderList *hlist,PRINTNODE print);
#endif // IMPROVED_HEADER_LIST_H_INCLUDED
功能實現(Improved_Header_List.c)
#include "Improved_Header_List.h"
HeaderList* Create_HeaderList(void){
HeaderList *hlist = (HeaderList*)malloc(sizeof(HeaderList));
hlist->head.next = NULL;
hlist->Hsize = 0;
return hlist;
}
void Destroy_HeaderList(HeaderList* hlist){ //TODO:Check it
if(hlist == NULL){
fprintf(stderr,"The list doesn't exist,can't Destroy it!\n");
return;
}
free(hlist);
}
void InsertByPos_HeaderList(HeaderList *hlist,int pos,Node *data){
if(hlist == NULL){
fprintf(stderr,"The list doesn't exist,can't InsertByPos!\n");
return;
}
if(pos<=0 || pos>hlist->Hsize){
pos = hlist->Hsize; //友好處理
}
Node *prev = &(hlist->head);
for(int i=0;i<pos;i++)
prev = prev->next;
Node *back = prev->next;
prev->next = data;
data->next = back;
hlist->Hsize ++;
}
void RemoveByPos_HeaderList(HeaderList *hlist,int pos){
if(hlist == NULL){
fprintf(stderr,"The list does NOT EXIST,can't RemoveByPos!\n");
return;
}
if(pos<=0 || pos>hlist->Hsize-1){
fprintf(stderr,"The pos is INVALID,can't RemoveByPos!\n");
return;
}
Node *prev = &(hlist->head);
for(int i=0;i<pos;i++)
prev = prev->next;
Node *back = prev->next->next;
prev->next = back;
/*不銷燬出鏈表的數據,若用堆需要自行
對數據進行內存管理*/
hlist->Hsize --;
}
void Clear_HeaderList(HeaderList *hlist){
if(hlist == NULL){
fprintf(stderr,"The list does NOT EXIST,can't Clear it!\n");
return;
}
if(hlist->Hsize == 0){
fprintf(stderr,"The list is EMPTY,can't Clear it!\n");
return;
}
while(hlist->Hsize != 0)
RemoveByPos_HeaderList(hlist,0);
}
Node* GetByPos_HeaderList(HeaderList *hlist,int pos){
if(hlist == NULL){
fprintf(stderr,"The list does NOT EXIST,can't GetByPos!\n");
return NULL;
}
if(pos<0 || pos>hlist->Hsize-1){
fprintf(stderr,"The pos is INVALID,can't GetByPos!\n");
return NULL;
}
Node *p = &(hlist->head);
for(int i=0;i<=pos;i++)
p = p->next;
return p;
}
int GetSize_HeaderList(HeaderList *hlist){
if(hlist == NULL){
fprintf(stderr,"The list does not EXIST,can't GetSize!\n");
return 0;
}
return hlist->Hsize;
}
void Print_HeaderList(HeaderList *hlist,PRINTNODE print){
if(hlist == NULL){
fprintf(stderr,"The list does not EXIST,can't Print it!\n");
return;
}
if(hlist->Hsize == 0){
fprintf(stderr,"The list is EMPTY,can't Print it!\n");
return ;
}
printf("\nThe size of the list is:%d.\n\n",hlist->Hsize);
Node *p = &(hlist->head);
for(int i=0;i<hlist->Hsize;i++){
p = p->next;
print((void*)p);
}
printf("\n");
}
功能測試(main.c)
#include "Improved_Header_List.h"
typedef struct DataType{
Node node; //用於將鏈表中的元素串起來
int seq;
int randNum;
}DataType;
void test_HeaderList();
void printData(Node *data){
DataType *p = (DataType*)data;
printf("seq:%d\trandNum:%d\n",p->seq,p->randNum);
}
int main()
{
test_HeaderList();
return 0;
}
void test_HeaderList(){
DataType data[10];
for(int i=0;i<10;i++){
data[i].seq = i;
data[i].randNum = rand()%50+1;
}
HeaderList* hlist = Create_HeaderList();
for(int i=0;i<10;i++)
InsertByPos_HeaderList(hlist,0,(Node*)&data[i]);
RemoveByPos_HeaderList(hlist,11); // Expect error
Print_HeaderList(hlist,printData);
printf("print data4:\n");
Node* data4 = GetByPos_HeaderList(hlist,4);
printData(data4);
printf("\n");
Destroy_HeaderList(hlist);
hlist = NULL;
}