Linux下学C语言——第二十节 数据结构|双向循环链表

双向循环链表的实现:

llist.h:

#ifndef LLIST_H__
#define LLIST_H__

#define FORWARD 1
#define BACKWARD 2

typedef void llist_op(const void *);

typedef int llist_cmp(const void *,const void *);


struct llist_node_st
{
    void *data;
    struct llist_node_st *prev;
    struct llist_node_st *next;

};


typedef struct 
{
    int size;
    struct llist_node_st head;
}llist;

llist *llist_creat(int initsize);

int llist_insert(llist *,const void *data , int mode);

void llist_travel(llist *, llist_op *);

void *llist_find(llist * , const void *key , llist_cmp *);

int llist_delete(llist *,const void *key,llist_cmp *);


int llist_fetch(llist *,const void *key,llist_cmp *,void *data);

void llist_destroy(llist *);

#endif

llist.c 

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "llist.h"


llist *llist_creat(int initsize)
{
   llist *new;
   
   new = malloc (sizeof(*new));
   if(new == NULL)
       return NULL;
       
    new ->size = initsize;
    new ->head.data = NULL;
    new ->head.prev = &new ->head;
    new ->head.next = &new ->head;
    
    return new; 
}


int llist_insert(llist *ptr,const void *data , int mode)
{
    struct llist_node_st *new;

    new = malloc(sizeof(*new));
    if(new == NULL)
        return -1;

    new -> data = malloc (ptr->size);
    if(new -> data == NULL)
        return -2;
    memcpy(new->data,data,ptr->size);//*

    if(mode == FORWARD)
    {
        new -> prev = &ptr->head;
        new -> next = ptr ->head.next;

    }
    else if(mode == BACKWARD)
    {
        new ->prev = ptr->head.prev;
        new ->next = &ptr -> head;
    }
    else
    {
        return -3;
    }
    new ->prev->next = new;
    new ->next ->prev = new;
    return 0;
}


void llist_travel(llist *ptr,llist_op *op)
{
    struct llist_node_st *cur;

    for(cur = ptr ->head.next; cur != &ptr ->head;cur = cur ->next)
        op(cur ->data);
}



static struct llist_node_st * find_(llist *ptr , const void *key ,llist_cmp *cmp)
{
    struct llist_node_st *cur;

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


void *llist_find(llist * ptr, const void *key , llist_cmp *cmp)
{
    return find_(ptr,key,cmp)->data;
}


int llist_delete(llist *ptr,const void *key,llist_cmp *cmp)
{
    struct llist_node_st *node;

    node = find_(ptr, key,cmp);

    if(node == &ptr->head)
        return -1;
    
    node->prev ->next = node ->next;
    node->next ->prev = node ->prev;
    free(node->data);
    free(node);

    return 0;
}



int llist_fetch(llist *ptr,const void *key,llist_cmp *cmp,void *data)
{
    struct llist_node_st *node;

    node = find_(ptr, key , cmp);
    if(node == &ptr->head)
        return -1;

    node->prev ->next = node ->next;
    node ->next ->prev = node ->prev;

    if(data != NULL)
        memcpy(data,node->data,ptr->size);

    free(node -> data);
    free(node);

    return 0;
}



void llist_destroy(llist *ptr)
{
    struct llist_node_st *cur,*next;

    for(cur = ptr->head.next;cur != &ptr->head; cur = next)
    {
        next = cur ->next;
        free(cur ->data);
        free(cur);
    }
    free(ptr);
}

main.c

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "llist.h"

#define NAME 32
struct score_st 
{
    int id;
    char name[NAME];
    int math;
    int chinese;
};


static void print_s(const void *record)
{
    const struct score_st *r = record;
    printf("%d %s %d %d\n",r->id,r->name,r->math,r->chinese);
}


static int id_cmp(const void *key,const void *record)
{
    const int *k = key;
    const struct score_st *r = record;

    return (*k - r->id);
}


static int name_cmp(const void *key,const void *record)
{
    const char *k = key;
    const struct score_st *r = record;

    return stecmp(*k , r->name);
}


int main()
{
    llist *handler;
    struct score_st tmp;
    int i, ret;
    handler = llist_creat(sizeof(struct score_st));
    if(handler ==NULL)
        exit(1);

    for (i = 0;i < 7;i++)
    {
        tmp.id = i;
        snprintf(tmp.name ,NAME ,"std%d",i);
        tmp.math = rand()%100;
        tmp.chinese = rand()%100;

        ret = llist_insert(handler , &tmp, FORWARD);
        if(ret)
            exit(1);
    }

    llist_travel(handler,print_s);
    
    printf("\n\n");
   
    int id =3;
    ret = llist_delete(handler , &id, id_cmp);
    if(ret)
        printf("failed\n");
    llist_travel(handler,print_s);

#if 0
    int id = 3;
    struct score *data;
    data = llist_find (handler, &id,id_cmp);
    if(data == NULL)
        printf("Can not find\n");
    else
        print_s(data);
#endif
   
    llist_destroy(handler);
   
    exit(0);
}

makefile:

all:llist

llist:llist.o main.o
    $(CC) $^ -o $@

clean:
    rm llist *.o -rf

 执行:

[tom@CentOS7 lib1]$ ./llist 
6 std6 90 59
5 std5 62 27
4 std4 49 21
3 std3 86 92
2 std2 93 35
1 std1 77 15
0 std0 83 86


6 std6 90 59
5 std5 62 27
4 std4 49 21
2 std2 93 35
1 std1 77 15
0 std0 83 86

结构体更改:

通用性较强的循环链表的结构体

结构体1:

struct list_node_st

{

    void *data; //指向用户自定义的结构体的空间

    struct llist_node_st *prev;

    struct llist_node_st *next;

};

结构体2:

struct list_node_st

{

    struct llist_node_st *prev;

    struct llist_node_st *next;

    char data[0];//剩余空间的起始位置

};

面向对象的实现:

#ifndef LLIST_H__
#define LLIST_H__

#define FORWARD 1
#define BACKWARD 2

typedef void llist_op(const void *);

typedef int llist_cmp(const void *,const void *);


struct llist_node_st
{
    
    struct llist_node_st *prev;
    struct llist_node_st *next;
    char data[0];
};


typedef struct llist_head 
{
    int size;
    struct llist_node_st head;

    int(*insert)(struct llist_head *,const void *,int);
    void *(*find)(struct llist_head *,const void *,llist_cmp *);
    int (*delete)(struct llist_head *,const void *, llist_cmp *);
    int (*fetch)(struct llist_head *,const void *,llist_cmp *,void *);
    void (*travel)(struct llist_head *,llist_op *);
}llist;

llist *llist_creat(int initsize);

void llist_destroy(llist *);

#endif

封装:将结构体写在.c文件中

#include <string.h>

#include <stdio.h>

#include <stdlib.h>

#include "llist.h"

struct llist_node_st

{

   

    struct llist_node_st *prev;

    struct llist_node_st *next;

    char data[0];

};

 struct head_st

{

    int size;

    struct llist_node_st head;

};

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值