现在的位置: 首页 > 综合 > 正文

数据机构 循环双链表 代码整理 清晰明了 思维整密的算法设计 值得品尝

2017年03月26日 ⁄ 综合 ⁄ 共 3384字 ⁄ 字号 评论关闭

llist.h

#ifndef __LLIST_H
#define __LLIST_H

#define LLIST_ADD_FORWARD  0
#define LLIST_ADD_BACKWARD 1

typedef void llist_op(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 size);

int llist_add(LLIST *, const void *data, int dir);

void llist_travel(LLIST *, llist_op *op);

void llist_delet(LLIST *, const void *key, llist_cmp *cmp);

void *llist_find(LLIST *, const void *key, llist_cmp *cmp);

void llist_destroy(LLIST *);
#endif

==========================================================

llist.c

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

LLIST *llist_creat(int size)
{
 LLIST *new;

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

 return new;
}

int llist_add(LLIST *ptr, const void *data, int dir)
{
 struct llist_node_st *newnode;

 newnode = malloc(sizeof(*newnode));
 if(newnode == NULL) {
  goto malloc_node_err;
 }
 newnode->data = malloc(ptr->size);
 if(newnode->data == NULL) {
  goto malloc_data_err;
 }

 memcpy(newnode->data, data, ptr->size);

 //if(dir == LLIST_ADD_FORWARD)
 if(dir == LLIST_ADD_BACKWARD) {
  newnode->next = ptr->head.next;
  newnode->prev = &ptr->head;
 } else {
  newnode->next = &ptr->head;
  newnode->prev = ptr->head.prev;  
 } 
 
 newnode->next->prev = newnode;
 newnode->prev->next = newnode;

 return 0;
 
 free(newnode->data);
malloc_data_err:
 free(newnode);
malloc_node_err:
 return -1;
}

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_delet(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) {
   cur->next->prev = cur->prev;
   cur->prev->next = cur->next;
   free(cur->data);
   free(cur);
   return ;
  }
 }
}

void *llist_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) {
   return cur->data;
  }
 }
 return NULL;
}

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 "llist.h"
#define NAMESIZE 32

struct score {
 int id;
 char name[NAMESIZE];
 int china;
 int math;
 int english;
};

static void print_score(void *data)
{
 struct score *d = data;
 printf("%d %s %d %d %d\n", d->id, d->name, d->china, d->math, d->english);
}

static int name_cmp(const void *key, const void *data)
{
 const char *k = key;
 const struct score *d = data;

 return strcmp(k, d->name);
}

int main(void)
{
 struct score tmp, *p;
 LLIST *list;
 int i;
 
 list = llist_creat(sizeof(struct score));
 /* if error */

 for(i = 0; i < 9; i++) {
  tmp.id = i;
  tmp.china = 100 - i;
  tmp.math = 100 - i * 2;
  tmp.english = 100 - i * 3;
  snprintf(tmp.name, NAMESIZE, "student%d", i);

  llist_add(list, &tmp, LLIST_ADD_FORWARD);
 }
 
 llist_travel(list, print_score);
 //The above of code can done llist_creat,llist_add_forward,llist_travel and final print_score
 
 llist_delet(list, "student6", name_cmp);
 llist_travel(list, print_score);
 //the above of code can done llist_delet,llist_add_backward
 
 p = llist_find(list, "student2", name_cmp);
 if(p == NULL) {
  printf("Can not find.\n");
 } else {
  print_score(p);
 }
 //the above of code can find  score.name  flags about "stdxxx".
 
 llist_destroy(list);
 //destroy  linklist.
 return 0;
}



抱歉!评论已关闭.