【c语言】【每周一练】Hash表之链表hash

//散列表之链表散列
#include <stdio.h>
#include <string.h>
#include "linux_list.h"
#define m 7

struct record{
struct list_head list;
int id;
char name[10];
};
int  Record_value(char *str,struct record *rec);
int main(void){
int i,j,n;
struct list_head *hash;
char str[100];
FILE *fp;
struct record *a;
hash=(struct list_head *)malloc(m*sizeof(struct list_head));
for(j=0;j<m;j++)
INIT_LIST_HEAD(&(hash[j]));

fp=fopen("records.txt","r");
while(fgets(str,100,fp)!=NULL){

   a=(struct record *)malloc(sizeof(struct record));
   Record_value(str,a);
   Hash_insert(hash,a);

}
fclose(fp);
Hash_search(hash,7);
Hash_delete(hash,7);
Hash_search(hash,7);
return 0;
}
 int Hash_insert(struct list_head *hash,struct record *rec){
    int idhash;
   idhash=Address_hash(rec->id);
   list_add(&(rec->list),&(hash[idhash]));

 }
int Hash_search(struct list_head *hash,int id){
    struct record *rec;
    int idhash;
  struct list_head *lp;
  idhash=Address_hash(id);
  list_for_each(lp,&(hash[idhash])){
  rec=list_entry(lp,struct record,list);
  if(rec->id==id){
  printf("has found! ");
  Record_print(rec);
  return 0;

  }

  }
  printf("not found!\n");
  return 1;

}
int Hash_delete(struct list_head *hash,int id){
   struct record *rec;
    int idhash;
  struct list_head *lp;
  idhash=Address_hash(id);
  list_for_each(lp,&(hash[idhash])){
  rec=list_entry(lp,struct record,list);
  if(rec->id==id){
   list_del(lp);
   printf("delete success!\n");
   return 0;
  }


  }
  printf("not found!\n");
  return 1;
}
int  Record_value(char *str,struct record *rec){
int i,j;
char id[10];
i=0;
for(j=0;str[j]!=' ';j++)
id[j]=str[j];
while(str[j]==' ' && ++j);
for(;str[j]!=' '&&str[j]!='\n';j++)
rec->name[i++]=str[j];
rec->name[i]='\0';
rec->id=atoi(id);
return 0;
}
void Record_print(struct record* rec){
printf("id is %d,name is %s\n",rec->id,rec->name);


}
int Address_hash(int id){
return id%m;
}

没有重新建链表,用的是linux中的链表。

View Code
#ifndef __C_LIST_H
#define __C_LIST_H

typedef unsigned char     u8;
typedef unsigned short    u16;
typedef unsigned int      u32;
typedef unsigned long     size_t;

#define offsetof(TYPE, MEMBER)   ((size_t) &((TYPE *)0)->MEMBER)

/**
 * container_of - cast a member of a structure out to the containing structure
 * @ptr:    the pointer to the member.
 * @type:    the type of the container struct this is embedded in.
 * @member:    the name of the member within the struct.
 *
 */
#define container_of(ptr, type, member) (type *)((char *)ptr -offsetof(type,member))

/*
 * These are non-NULL pointers that will result in page faults
 * under normal circumstances, used to verify that nobody uses
 * non-initialized list entries.
 */
#define LIST_POISON1  ((void *) 0x00100100)
#define LIST_POISON2  ((void *) 0x00200200)

struct list_head {
    struct list_head *next, *prev;
};

/**
 * list_entry - get the struct for this entry
 * @ptr:    the &struct list_head pointer.
 * @type:    the type of the struct this is embedded in.
 * @member:    the name of the list_struct within the struct.
 */
#define list_entry(ptr, type, member) \
    container_of(ptr, type, member)


#define LIST_HEAD_INIT(name) { &(name), &(name) }

#define LIST_HEAD(name) \
    struct list_head name = LIST_HEAD_INIT(name)

static inline void INIT_LIST_HEAD(struct list_head *list)
{
    list->next = list;
    list->prev = list;
}

/**
 * list_for_each    -    iterate over a list
 * @pos:    the &struct list_head to use as a loop counter.
 * @head:    the head for your list.
 */
#define list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)

/**
 * list_for_each_r    -    iterate over a list reversely
 * @pos:    the &struct list_head to use as a loop counter.
 * @head:    the head for your list.
 */
#define list_for_each_r(pos, head) \
    for (pos = (head)->prev; pos != (head); pos = pos->prev)

/*
 * Insert a new entry between two known consecutive entries.
 *
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
static inline void __list_add(struct list_head *new,
                  struct list_head *prev,
                  struct list_head *next)
{
    next->prev = new;
    new->next = next;
    new->prev = prev;
    prev->next = new;
}

/**
 * list_add - add a new entry
 * @new: new entry to be added
 * @head: list head to add it after
 *
 * Insert a new entry after the specified head.
 * This is good for implementing stacks.
 */
static inline void list_add(struct list_head *new, struct list_head *head)
{
    __list_add(new, head, head->next);
}

/**
 * list_add_tail - add a new entry
 * @new: new entry to be added
 * @head: list head to add it before
 *
 * Insert a new entry before the specified head.
 * This is useful for implementing queues.
 */
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
    __list_add(new, head->prev, head);
}

/*
 * Delete a list entry by making the prev/next entries
 * point to each other.
 *
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
    next->prev = prev;
    prev->next = next;
}

/**
 * list_del - deletes entry from list.
 * @entry: the element to delete from the list.
 * Note: list_empty on entry does not return true after this, the entry is
 * in an undefined state.
 */
static inline void list_del(struct list_head *entry)
{
    __list_del(entry->prev, entry->next);
    entry->next = LIST_POISON1;
    entry->prev = LIST_POISON2;
}


/**
 * list_empty - tests whether a list is empty
 * @head: the list to test.
 */
static inline int list_empty(const struct list_head *head)
{
    return head->next == head;
}


static inline void __list_splice(struct list_head *list,
                 struct list_head *head)
{
    struct list_head *first = list->next;
    struct list_head *last = list->prev;
    struct list_head *at = head->next;

    first->prev = head;
    head->next = first;

    last->next = at;
    at->prev = last;
}

/**
 * list_splice - join two lists
 * @list: the new list to add.
 * @head: the place to add it in the first list.
 */
static inline void list_splice(struct list_head *list, struct list_head *head)
{
    if (!list_empty(list))
        __list_splice(list, head);
}


#endif // __C_LIST_H

每周一练,day day up!

posted @ 2012-06-30 23:17  huals  阅读(396)  评论(0编辑  收藏  举报