1. 程式人生 > 其它 >c語言 雙鏈表封裝 (無頭連結串列)2020-12-15

c語言 雙鏈表封裝 (無頭連結串列)2020-12-15

技術標籤:連結串列c語言

//標頭檔案

//#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;
}