c語言 雙鏈表封裝 (無頭連結串列)2020-12-15
阿新 • • 發佈:2020-12-16
//標頭檔案 //#pragma once #ifndef HH_H #define HH_H #include <stdio.h> struct node { struct node *next, *prev; }; //h 結構體型別 list #define container_of(ptr, type, member) \ (type *)((char *)ptr - ( (unsigned int)&( (type *)0 )->member ) ) //遍歷 void showlist(struct node *h, void (*print)(struct node *)); //頭插 void insert_Head(struct node **h, struct node *n); //未插 void insert_Tail(struct node **h, struct node *n); //排序 void sort_list(struct node **h, int (*fp2)(struct node *, struct node *)); //刪除查詢 void find_node(struct node **h, struct node *goal, int(*fp1)(struct node *, struct node *)); //銷燬 void destroy_list(struct node **h, void *(*fp)(struct node *)); #endif
//原始檔 #include "hh.h" void showlist(struct node *h, void (* print)(struct node *)) { printf("=====open=====\n"); struct node *p = NULL; while(h) { p = h; print(h); h = h->next; } printf("=====prev=====\n"); while(p) { print(p); p = p->prev; } } void insert_Head(struct node **h, struct node *n) { n->next = *h; if(*h != NULL) { (*h)->prev = n; } *h = n; } void insert_Tail(struct node **h, struct node *n) { if(*h == NULL) { *h = n; return ; } struct node *p = *h; while(p->next) { p = p->next; } p->next = n; n->prev = p; } void sort_list(struct node **h, int (*fp)(struct node *, struct node *)) { struct node *newhead = NULL; struct node *min = NULL; struct node *p = NULL; while(*h) { min = *h; p = min; while(p->next) { if(fp(min, p->next) > 0) // if(min->val > p->next->val) { min = p->next; }else { p = p->next; } } if(*h == min) { (*h) = (*h)->next; }else { min->prev->next = min->next; if(min->next) { min->next->prev = min->prev; } } min->next = NULL; min->prev = NULL; insert_Tail(&newhead, min); } *h = newhead; } void find_node(struct node **h, struct node *goal, int(*fp1)(struct node *, struct node *)) { struct node *newhead = NULL; while(fp1(*h, goal) == 0) { struct node *tmp = *h; (*h) = (*h)->next; (*h)->prev = NULL; tmp->next = NULL; tmp->prev = NULL; insert_Tail(&newhead, tmp); } struct node *p = *h; while(p->next) { struct node *t = p->next; if((fp1)(t, goal) == 0) { struct node *tmp = p->next; p->next = t->next; if(t->next != NULL) { t->next->prev = p; } tmp->next = NULL; tmp->prev = NULL; insert_Tail(&newhead, tmp); }else { p = p->next; } } *h = newhead; } void destroy_list(struct node **h, void *(*fp)(struct node *)) { while(*h) { struct node *p = *h; *h = (*h)->next; p = fp(p); } }
//測試檔案 #include <stdio.h> #include <stdlib.h> #include "hh.h" struct hao { int data; int val; int idx; struct node list; }; void print(struct node *h) { struct hao *p = container_of(h, struct hao, list); printf("idx %d val %d data %d\n", p->idx, p->val, p->data); } int cmp_val1(struct node *n1, struct node *n2) { struct hao *p1 = container_of(n1, struct hao, list); struct hao *p2 = container_of(n2, struct hao, list); return p1->val - p2->val; } int cmp_data1(struct node *n1, struct node *n2) { struct hao *p1 = container_of(n1, struct hao, list); struct hao *p2 = container_of(n2, struct hao, list); return p1->data - p2->data; } struct hao goal = { .list.next = NULL, .list.prev = NULL, .val = 8 }; void *destroy_node(struct node *h) { struct hao *t = container_of(h, struct hao, list); t->list.next = NULL; t->list.prev = NULL; free(t); t = NULL; return NULL; } int main () { srand(time(NULL)); int arr[] = {8,8,1,2,8,8,3,8,4,8,8}; int i = 0; struct node *head = NULL; struct hao *newnode = NULL; while(i < sizeof(arr)/sizeof(int)) { newnode = (struct hao *)malloc(sizeof(struct hao)); newnode->val = arr[i]; newnode->data = rand()%100; newnode->idx = i; newnode->list.next = NULL; newnode->list.prev = NULL; // insert_Head(&head, &newnode->list); insert_Tail(&head, &newnode->list); i++; } // showlist(head, print); //遍歷 // sort_list(&head, cmp_data1);//排序 // showlist(head, print); find_node(&head, &goal.list, cmp_val1); showlist(head, print); destroy_list(&head, destroy_node); return 0; }
//container_of
#include <stdio.h>
#include <stdlib.h>
struct student
{
struct student *next;
struct student *prev;
};
struct node
{
struct student list;
int val;
int data;
};
void insert_Tail(struct student **h, struct student *n)
{
if(*h == NULL)
{
*h = n;
return ;
}
struct student *p = *h;
while(p->next)
{
p = p->next;
}
p->next = n;
n->prev = p;
}
#define container_of(ptr, type, member) \
(type *)( (char *)ptr - ( (unsigned int)&( (type *)0 )->member ) )
void showlist(struct student *h)
{
while(h)
{
struct node *t = container_of(h, struct node, list);
// struct node *t = (struct node*)( (char*)h-( (unsigned int)&((struct node*)0)->list ) );
// int offset = (unsigned int)&((struct node *)0)->list - (unsigned int)((struct node *)0);
// struct node *s = malloc(sizeof(struct node));
// int offset = (unsigned int)&s->list - (unsigned int)s;
// struct node *t = (struct node *)( (char *)h - offset );
printf("val %d\n", t->val );
// struct node *p = (struct node *)h;
// printf("val %d\n", p->val );
// printf("val %d\n",*( (unsigned int *)((char*)h+8) ) );
h = h->next;
}
}
int main ()
{
struct student *head = NULL;
struct node *newhead = NULL;
int i = 0;
while(i < 10)
{
newhead = (struct node *)malloc(sizeof(struct node));
newhead->val = i;
newhead->list.next = NULL;
newhead->list.prev = NULL;
insert_Tail(&head, &newhead->list);
i++;
}
showlist(head);
return 0;
}