数据结构 双向链表的数据封装

链表

定义数据结构:

typedef void (llist_op_t)(const void *);
typedef int (llist_cmp_t)(const void * , const void *);
typedef void (llist_mod_t)(void *, const void *);

//抽象数据类型
typedef struct node_t{
	void *data;
	struct node_t *next;
	struct node_t *prev;
}NODE;

typedef struct llist_t{
	NODE head;
	int size;
	int count;	
}LLIST;

//==============insert======================
void llist_append(LLIST *handle, void *data);
void llist_appprev(LLIST *handle, void *data);
void llist_index_insert(LLIST *handle, void *data, int index);

//================del=================
void llist_first_del(LLIST *handle, void *key, llist_cmp_t *cmp);
void llist_end_del(LLIST *handle, void *key, llist_cmp_t *cmp);
void llist_all_del(LLIST *handle, void *key, llist_cmp_t *cmp);
void llist_index_del(LLIST *handle, int index);

//=============find=======================
void *llist_first_find(LLIST *handle, void *key, llist_cmp_t *cmp);
void *llist_end_find(LLIST *handle, void *key, llist_cmp_t *cmp);
LLIST *llist_all_find(LLIST *handle, void *key, llist_cmp_t *cmp);
void *llist_index_find(LLIST *handle, int index);

//===============mod=====================
void llist_first_mod(LLIST *handle, void *old_key, llist_cmp_t *cmp, void *new_key, llist_mod_t *mod);
void llist_end_mod(LLIST *handle, void *old_key, llist_cmp_t *cmp, void *new_key, llist_mod_t *mod);
void llist_all_mod(LLIST *handle, void *old_key, llist_cmp_t *cmp, void *new_key, llist_mod_t *mod);
void llist_index_mod(LLIST *handle, int index, void *new_key, llist_mod_t *mod);

//============sort=================
void llist_sort(LLIST *handle, llist_cmp_t *cmp);

//================fileio===============
void llist_store(LLIST *handle, const char *path);
LLIST *llist_load(const char *path);

//=================llist_copy==========
LLIST *llist_copy(LLIST *handle);

//==========llist_inti==============
LLIST *llist_creat(int size);
//===========llist_travel===========
void llist_travel(LLIST *handle, llist_op_t *op);
//==========llist_destroy============
void llist_destroy(LLIST **handle);
//==========llist_count=============
int llist_num(LLIST *handle);

//insert

void llist_append(LLIST *handle, void *data)
{
    ERRP(NULL == data, data NULL, goto ERR1);

    NODE *new = NULL;

    new = (NODE *)malloc(sizeof(NODE));
    ERRP(NULL == new, malloc new, goto ERR1);

    new->data = (void *)malloc(handle->size);
    ERRP(NULL == new->data, new->data NULL, goto ERR2);

    memmove(new->data, data, handle->size);

    new->next = &handle->head;
    new->prev = handle->head.prev;
    handle->head.prev->next = new;
    handle->head.prev = new;

    handle->count++;

    return;
ERR2:
    free(new);
ERR1:
    return;
}

void llist_appprev(LLIST *handle, void *data)
{
    ERRP(NULL == data, data NULL, goto ERR1);

    NODE *new = NULL;

    new = (NODE *)malloc(sizeof(NODE));
    ERRP(NULL == new, malloc new, goto ERR1);

    new->data = (void *)malloc(handle->size);
    ERRP(NULL == new->data, new->data NULL, goto ERR2);

    memmove(new->data, data, handle->size);

    new->next = handle->head.next;
    new->prev = &handle->head;
    handle->head.next->prev = new;
    handle->head.next = new;

    handle->count++;
    return;
ERR2:
    free(new);
ERR1:
    return;
}

void llist_index_insert(LLIST *handle, void *data, int index)
{
    ERRP(index > handle->count || index < 0, index error, goto ERR1);
    ERRP(NULL == data, data NULL, goto ERR1);

    NODE *new = NULL;

    new = (NODE *)malloc(sizeof(NODE));
    ERRP(NULL == new, malloc new, goto ERR1);

    new->data = (void *)malloc(handle->size);
    ERRP(NULL == new->data, new->data NULL, goto ERR2);

    memmove(new->data, data, handle->size);

    NODE *tail = &handle->head;
    int count = 0;
    while (count != index)
    {
        tail = tail->next;
        count++;
    }
    new->next = tail->next;
    new->prev = tail;
    tail->next->prev = new;
    tail->next = new;

    handle->count++;
    return;
ERR2:
    free(new);
ERR1:
    return;
}

//del

void llist_first_del(LLIST *handle, void *key, llist_cmp_t *cmp)
{
    NODE *tail = NULL;
    for (tail = handle->head.next; tail != &handle->head; tail = tail->next)
    {
        if (cmp(tail->data, key) == 0)
        {
            tail->prev->next = tail->next;
            tail->next->prev = tail->prev;
            free(tail->data);
            free(tail);
            handle->count--;
            return;
        }
    }
    return;
}

void llist_end_del(LLIST *handle, void *key, llist_cmp_t *cmp)
{
    NODE *tail = NULL;
    for (tail = handle->head.prev; tail != &handle->head; tail = tail->prev)
    {
        if (cmp(tail->data, key) == 0)
        {
            tail->prev->next = tail->next;
            tail->next->prev = tail->prev;
            free(tail->data);
            free(tail);
            handle->count--;
            return;
        }
    }
    return;
}

void llist_all_del(LLIST *handle, void *key, llist_cmp_t *cmp)
{
    NODE *tail = NULL, *new = NULL;
    for (tail = handle->head.next; tail != &handle->head; tail = new)
    {
        if (cmp(tail->data, key) == 0)
        {
            new = tail->next;
            tail->prev->next = tail->next;
            tail->next->prev = tail->prev;
            free(tail->data);
            free(tail);
            handle->count--;
            tail = tail->prev;
        }
        else
        {
            new = tail->next;
        }
    }
    return;
}

void llist_index_del(LLIST *handle, int index)
{
    ERRP(index >= handle->count || index < 0, index error, goto ERR1);

    int count = 0;
    NODE *tail = handle->head.next;
    while (count != index)
    {
        tail = tail->next;
        count++;
    }
    tail->prev->next = tail->next;
    tail->next->prev = tail->prev;
    free(tail->data);
    free(tail);
    handle->count--;
    return;

ERR1:
    return;
}

//find

void *llist_first_find(LLIST *handle, void *key, llist_cmp_t *cmp)
{
    NODE *tail = NULL;

    for (tail = handle->head.next; tail != &handle->head; tail = tail->next)
    {
        if (cmp(tail->data, key) == 0)
        {
            return tail->data;
        }
    }

    return NULL;
}

void *llist_end_find(LLIST *handle, void *key, llist_cmp_t *cmp)
{
    NODE *tail = NULL;

    for (tail = handle->head.prev; tail != &handle->head; tail = tail->prev)
    {
        if (cmp(tail->data, key) == 0)
        {
            return tail->data;
        }
    }

    return NULL;
}

LLIST *llist_all_find(LLIST *handle, void *key, llist_cmp_t *cmp)
{
    LLIST *temp = NULL;
    temp = llist_creat(handle->size);
    ERRP(NULL == temp, malloc temp, goto ERR1);

    NODE *tail = NULL;
    for (tail = handle->head.next; tail != &handle->head; tail = tail->next)
    {
        if (cmp(tail->data, key) == 0)
        {
            llist_append(temp, tail->data);
        }
    }
    return temp;
ERR1:
    return NULL;
}

void *llist_index_find(LLIST *handle, int index)
{
    NODE *tail = NULL;
    int count = 0;
    for (tail = handle->head.next; tail != &handle->head; tail = tail->next)
    {
        if (index == count)
        {
            return tail->data;
        }
        else
        {
            count++;
        }
    }

    return NULL;
}

//mod

void llist_first_mod(LLIST *handle, void *old_key, llist_cmp_t *cmp, void *new_key, llist_mod_t *mod)
{
    NODE *tail = NULL;

    for (tail = handle->head.next; tail != &handle->head; tail = tail->next)
    {
        if (cmp(tail->data, old_key) == 0)
        {
            mod(tail->data, new_key);
            return;
        }
    }

    return;
}

void llist_end_mod(LLIST *handle, void *old_key, llist_cmp_t *cmp, void *new_key, llist_mod_t *mod)
{
    NODE *tail = NULL;

    for (tail = handle->head.prev; tail != &handle->head; tail = tail->prev)
    {
        if (cmp(tail->data, old_key) == 0)
        {
            mod(tail->data, new_key);
            return;
        }
    }

    return;
}

void llist_all_mod(LLIST *handle, void *old_key, llist_cmp_t *cmp, void *new_key, llist_mod_t *mod)
{
    NODE *tail = NULL;

    for (tail = handle->head.next; tail != &handle->head; tail = tail->next)
    {
        if (cmp(tail->data, old_key) == 0)
        {
            mod(tail->data, new_key);
        }
    }

    return;
}

void llist_index_mod(LLIST *handle, int index, void *new_key, llist_mod_t *mod)
{
    ERRP(index > handle->count || index < 0, index error, goto ERR1);
    void *tail = llist_index_find(handle, index);
    mod(tail, new_key);

ERR1:
    return;
}

//sort

void llist_sort(LLIST *handle, llist_cmp_t *cmp)
{
    NODE *i = NULL;
    NODE *j = NULL;
    void *new = NULL;

    new = (void *)malloc(handle->size);
    ERRP(NULL == new, new NULL, goto ERR1);

    for (i = handle->head.next; i != &handle->head; i = i->next)
    {
        for (j = handle->head.next; j->next != &handle->head; j = j->next)
        {
            if (cmp(j->data, j->next->data))
            {
                memmove(new, j->data, handle->size);
                memmove(j->data, j->next->data, handle->size);
                memmove(j->next->data, new, handle->size);
            }
        }
    }
    free(new);

    return;
ERR1:
    return;
}

//fileio

void llist_store(LLIST *handle, const char *path)
{
    FILE *fp = NULL;
    NODE *tail = NULL;

    fp = fopen(path, "w");
    ERRP(NULL == fp, fp open, goto ERR1);

    if (fwrite(handle, sizeof(*handle), 1, fp) != 1)
    {
        perror("fwrite");
        goto ERR2;
    }

    for (tail = handle->head.next; tail != &handle->head; tail = tail->next)
    {
        if(fwrite(tail->data , handle->size , 1 ,fp) != 1)
        {
            perror("fwrite");
            goto ERR2;
        }
    }

    fclose(fp);
    return ;
ERR2:
    fclose(fp);
ERR1:
    return;
}

LLIST *llist_load(const char *path)
{
    FILE *fp = NULL;
    LLIST *handle = NULL;
    void *tail = NULL;
    int i;
    
    handle = (LLIST*)malloc(sizeof(LLIST));
    ERRP(NULL == handle , malloc handle , goto ERR1);

    fp = fopen(path, "r");
    ERRP(NULL == fp, fp open, goto ERR2);

    if(fread(handle , sizeof(*handle) , 1 , fp) != 1)
    {
        perror("fread");
		goto ERR3;
    }

    handle->head.data = NULL;
    handle->head.next = &handle->head;
    handle->head.prev = &handle->head;
    
    for(i=0 ;i < handle->count ;i++)
    {
        tail = (void*)malloc(handle->size);
        ERRP(NULL == tail , tail malloc , goto ERR3);

        if(fread(tail , handle->size , 1 ,fp)!=1)
        {
            perror("fread");
		    goto ERR3;
        }
        
        llist_append(handle,tail);
        handle->count--;
    }

    fclose(fp);
    return handle;

ERR3:	
	fclose(fp);
    llist_destroy(&handle);
ERR2:
	free(handle);
ERR1:
	return NULL;
}

//copy

LLIST *llist_copy(LLIST *handle)
{
    LLIST * newhandle = NULL;
    NODE *tail = handle->head.next;

    newhandle = llist_creat(handle->size);
    ERRP(NULL == newhandle , newhandle init , goto ERR1);

    while(tail != &handle->head)
    {
        llist_append(newhandle,tail->data);
        tail = tail->next;
    }

    return newhandle;
ERR1: 
    return NULL;
}

//count nmu

int llist_num(LLIST *handle)
{
    return handle->count;
}

//init

LLIST *llist_creat(int size)
{
    LLIST *handle = NULL;

    handle = (LLIST *)malloc(sizeof(LLIST));
    ERRP(NULL == handle, malloc handle, goto ERR1);

    handle->head.data = NULL;
    handle->head.next = &handle->head;
    handle->head.prev = &handle->head;
    handle->size = size;
    handle->count = 0;

    return handle;
ERR1:
    return NULL;
}

//traval

void llist_travel(LLIST *handle, llist_op_t *op)
{
    NODE *tail = NULL;

    for (tail = handle->head.next; tail != &handle->head; tail = tail->next)
    {
        op(tail->data);
    }
}

//destroy

void llist_destroy(LLIST **handle)
{
    NODE *tail = NULL;
    NODE *sava = NULL;

    for (tail = (*handle)->head.next; tail != &(*handle)->head; tail = sava)
    {
        sava = tail->next;
        free(tail->data);
        free(tail);
    }
    free(*handle);
    *handle = NULL;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值