相比一般链表,这种链表实现起来更加方便,也比较灵活
这个实现是从下面这个视频里学到的:
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;
}