循环双链表封装成类的实现

数据结构 ——循环双链表的封装2-封装成类的实现

一、面向对象的概念
面向对象就是:把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象。对同类对象抽象出其共性,形成类。类中的大多数数据,只能用本类的方法进行处理。类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信。程序流程由用户在使用中决定。对象即为人对各种具体物体抽象后的一个概念,人们每天都要接触各种各样的对象,如手机就是一个对象。
二、示例
下面是采用面向对象的思想,将前面的循环双链表封装成类的实现。以项目工程的形式记录


//llist.h
#ifndef LLIST_H_
#define LLIST_H_

#define LLIST_FORWARD 1  
#define LLIST_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 mode); 
    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 *data);
    void (*travel)(struct llist_head *,llist_op *);
}LLIST;


LLIST *llist_create(int initsize);
void llist_destroy(LLIST *);

#endif

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

//将封装的函数放到.c文件中
int llist_insert(LLIST *,const void *,int mode);
void *llist_find(LLIST *,const void *,llist_cmp *);
int llist_delete(LLIST *,const void *key,llist_cmp *);
int llist_fetch(LLIST *,const void *key,llist_cmp *,void *data);
void llist_travel(LLIST *,llist_op *);

LLIST *llist_create(int initsize)
{
    LLIST *new;
    new=malloc(sizeof(*new));
    if(new==NULL)
     return NULL;
    new->size=initsize;
    new->head.prev=&new->head;
    new->head.next=&new->head;
    //封装函数必须初始化才能调用接口函数
    new->insert=llist_insert;//将插入函数指针赋值给结构体,加括号表示调用函数
    new->delete=llist_delete;
    new->find=llist_find;
    new->fetch=llist_fetch;
    new->travel=llist_travel;
    return new;
    
}

int llist_insert(LLIST *ptr,const void *data,int mode)
{
    struct llist_node_st *newnode;
    newnode=malloc(sizeof(*newnode)+ptr->size);
    if(newnode==NULL)
      return -1;
    memcpy(newnode->data,data,ptr->size);
    if(mode==LLIST_FORWARD)
    {
        newnode->prev=&ptr->head;
        newnode->next=ptr->head.next;
    }                       
    else if(mode==LLIST_BACKWARD)
    {
        newnode->prev=ptr->head.prev;
        newnode->next=&ptr->head;

    }
    else  
    {
        return -3;
    }
    newnode->prev->next=newnode;
    newnode->next->prev=newnode;
    return 0;
}

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)
{
    struct llist_node_st *node;
    node=find_(ptr,key,cmp);
    if(node==&ptr->head)
      return NULL;
    return node->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);
    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);
    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);
}

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);
    }
    free(ptr);
}


//main.c
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include "llist.h"

#define NAMESIZE 32

struct score_st
{
    int id;
    char name[NAMESIZE];
    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 strcmp(k,r->name);
}


int main()
{
    LLIST *handler;
    struct score_st tmp;
    int i,ret;
    handler = llist_create(sizeof(struct score_st));
    if(handler==NULL)
      exit(1);
    for(i=0;i<7;i++)
    {
        tmp.id=i;
        snprintf(tmp.name,NAMESIZE,"std%d",i);
        tmp.math=rand()%100;
        tmp.chinese=rand()%100;
       // ret=llist_insert(handler,&tmp,LLIST_FORWARD);
       //调用insert方法
        ret=handler->insert(handler,&tmp,LLIST_FORWARD);
        if(ret)
          break;
    }
    //llist_travel(handler,print_s);
    handler->travel(handler,print_s);
    printf("\n");
    //查找测试
    #if 0
    int id=6;
    struct score_st *data;
    data=handler->find(handler,&id,id_cmp);
    if(data==NULL)
      printf("Can not find!\n");
    else print_s(data);
    #endif
    //删除测试
    #if 0
    //int id=6;
    char *del_name="std0";
    ret=handler->delete(handler,del_name,name_cmp);
    if(ret)
      printf("llist_delete failed!\n");
    handler->travel(handler,print_s);
    #endif
    //fetch测试
    #if 1
    int id=1;
    struct score_st *data;
    data=malloc(sizeof(struct score_st));
    ret=handler->fetch(handler,&id,id_cmp,data);
    if(ret)
      printf("llist_fetch failed!\n");
    else print_s(data);
    #endif
    llist_destroy(handler);
    exit(0); 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值