// 完成了单链表的所有操作: 增,删,前插,后插,回调遍历,复制,销毁,反转,排序
// 对于队列和栈就简单了,稍稍修改即可
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define list_create(A) list_init(A)
typedef struct node{
struct node *next;
void *data;
}node;
typedef struct {
node *head;
}list_t; // 单链表
typedef struct {
node *head;
node *tail;
}queue_t; // 队列
typedef struct {
node *top;
}stack_t; // 栈
inline static node *makenode(void *data);
inline static void freenode(node *p);
void list_init(list_t *list);
size_t list_length(list_t *list);
void list_destroy(list_t *list);
node *list_getnode(list_t *list, int id);
void list_add(list_t *list, void *data);
void list_insertBack(list_t *list, node *n, void *data);
void list_insertFront(list_t *list, node *n, void *data);
void list_del(list_t *list, node *del);
void list_traverse(list_t *list, void(*visit)(void *));
void list_reverse(list_t *list);
void list_sort(list_t *list, int(*cmpar)(const void *, const void *));
void list_copy(list_t *dest, list_t *src);
void list_add2(list_t *list, void *data);
void list_del2(list_t *list, node *del);
void list_insertFront2(list_t *list, node *n, void *data);
void disp(int n);
int cmpar(const void *data1, const void *data2);
int main(int argc, char **argv);
inline static node *makenode(void *data)
{
node *p;
if( (p = malloc(sizeof(*p))) == NULL){
perror("malloc");
exit(1);
}
p->next = NULL;
p->data = data;
return p;
}
inline static void freenode(node *p)
{
free(p);
}
// 初始化
void list_init(list_t *list)
{
list->head = NULL;
}
size_t list_length(list_t *list)
{
node *p;
int len;
for(p = list->head, len = 0; p; p = p->next, len++)
;
return len;
}
// 销毁一个链表
void list_destroy(list_t *list)
{
node *p;
for(p = list->head; p; p = p->next)
list_del(list, p);
}
// 按顺序编号获取某个节点
node *list_getnode(list_t *list, int id)
{
node *p;
int n;
for(p = list->head, n = 0; p; p = p->next, n++)
if(n == id)
return p;
return NULL; // 最后1个节点的后继或没有找到
}
// 添加
void list_add(list_t *list, void *data)
{
if(list->head == NULL){ // 特殊情况:头结点判断
list->head = makenode(data);
}else{
node *p = list->head;
while(p->next) // 获取最后一个节点
p = p->next;
p->next = makenode(data);
}
}
// 后插
void list_insertBack(list_t *list, node *n, void *data)
{
// assert(n);
if(n == NULL)
return;
node *ins = makenode(data);
ins->next = n->next;
n->next = ins;
}
// 前插
void list_insertFront(list_t *list, node *n, void *data)
{
node *ins = makenode(data);
ins->next = n;
if(n == list->head){ // 特殊情况:头结点判断
list->head = ins;
}else{ // 获取n的前驱
node *p;
for(p = list->head; p; p = p->next)
if(p->next == n){
p->next = ins;
return;
}
}
}
// 删除一个节点
void list_del(list_t *list, node *del)
{
if(del == NULL)
return;
node *p;
if(list->head == del){// 特殊情况:头结点判断
list->head = list->head->next;
}else{
for(p = list->head; p; p = p->next)
if(p->next == del){
p->next = del->next;
freenode(del);
}
}
}
// 遍历
void list_traverse(list_t *list, void(*visit)(void *))
{
node *p;
if(list->head == NULL){
puts("empty !");
return;
}
for(p = list->head; p; p = p->next)
visit(p->data);
puts("");
}
// 反转
void list_reverse(list_t *list)
{
node *tmp, *p, *head = NULL;
for(p = list->head; p; p = tmp){
tmp = p->next; // 暂存p的后继节点
p->next = head, head = p; // 将p插到head前
}
list->head = head;
}
// 排序
void list_sort(list_t *list, int(*cmpar)(const void *, const void *))
{
size_t len;
void **parr;
node *p;
int i;
len = list_length(list);
parr = malloc(sizeof(void *)*len);
for(p = list->head, i = 0; p; p = p->next, i++)
parr[i] = p->data;
qsort(parr, len, sizeof(void *), cmpar);
for(p = list->head, i = 0; p; p = p->next, i++)
p->data = parr[i];
free(parr);
}
// 复制一个链表
void list_copy(list_t *dest, list_t *src)
{
node *p;
for(p = src->head; p; p = p->next)
list_add(dest, p->data);
}
// -----------------------------------------------------
void list_add2(list_t *list, void *data)
{
node **p;
for(p = &list->head; *p; p = &(*p)->next)
; // 获取最后一个节点地址
*p = makenode(data);
}
void list_del2(list_t *list, node *del)
{
node **p;
for(p = &(list->head); *p; p = &(*p)->next){
if(*p == del){
*p = del->next;
freenode(del);
if(*p == NULL)
return;
}
}
}
void list_insertFront2(list_t *list, node *n, void *data)
{
node **p;
node *ins = makenode(data);
ins->next = n;
for(p = &list->head; *p; p = &(*p)->next)
if(*p == n){
*p = ins;
return;
}
*p = ins; // n == NULL
}
// -------------------------------------------------
void disp(int n)
{
printf("%c_",n);
}
int cmpar(const void *data1, const void *data2)
{
return *(int *)data1 - *(int *)data2;
}
void(*show)(void *) = (void(*)(void *))disp;
int main(int argc, char **argv)
{
list_t list;
list_init(&list);
list_insertFront(&list, list.head, (void *)'2');
list_insertFront(&list, list.head, (void *)'5');
list_insertFront(&list, list.head, (void *)'c');
list_insertFront(&list, list.head, (void *)'d');
list_traverse(&list, show);
list_traverse(&list, show);
node *p = list_getnode(&list, 2); // p==NULL
list_insertBack(&list, p, (void *)'X');
list_traverse(&list, show);
list_insertFront2(&list, p, (void *)'x');
list_traverse(&list, show);
p = list_getnode(&list, 2);
list_del(&list, p);
list_traverse(&list, show);
list_add2(&list, (void *)'3');
list_add2(&list, (void *)'1');
list_traverse(&list, show);
list_reverse(&list);
list_traverse(&list, show);
list_t list2;
list_init(&list2);
list_copy(&list2, &list);
list_traverse(&list2, show);
list_destroy(&list2);
list_traverse(&list2, show); // empty
list_sort(&list, cmpar);
list_traverse(&list, show);
return 0;
}