一个不错的链表类(mark)

来源:互联网 发布:知乎网站的盈利模式 编辑:程序博客网 时间:2024/05/22 12:56

头文件:

/* GLIB - Library of useful routines for C programming * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * Modified by the GLib Team and others 1997-2000.  See the AUTHORS * file for a list of people on the GLib Team.  See the ChangeLog * files for a list of changes.  These files are distributed with * GLib at ftp://ftp.gtk.org/pub/gtk/.  */#ifndef __G_LIST_H__#define __G_LIST_H__#include <memory>#undefMAX#define MAX(a, b)  (((a) > (b)) ? (a) : (b))#undefMIN#define MIN(a, b)  (((a) < (b)) ? (a) : (b)/* memory allocation functions */#define g_malloc(sz)  malloc(sz)static inline void * g_malloc0(int sz){void *p=malloc(sz);memset(p,0,sz);return p;}#define g_alloca(s)    alloca(s)#define g_new(type,count)   (type *)g_malloc(sizeof(type)*(count))#define g_new0(type, count)(type *)g_malloc0(sizeof(type)*(count))#define g_realloc(p,sz) realloc((p),(sz))#define g_free(p) free(p)/*misc*/#define g_return_if_fail(expr) if (!(expr)) {printf("%s:%i- assertion" #expr "failed\n",__FILE__,__LINE__); return;}#define g_return_val_if_fail(expr,ret) if (!(expr)) {printf("%s:%i- assertion #expr failed\n",__FILE__,__LINE__); return (ret);}#define g_assert(expr) if (!(expr)) printf("%s:%i- assertion #expr failed\n",__FILE__,__LINE__)#define g_assert_not_reached() printf("%s:%i- assert not reached failed\n",__FILE__,__LINE__)typedef struct _GListGList;struct _GList{  void * data;  GList *next;  GList *prev;};typedef  int gint;typedef  unsigned int guint;typedef  void* gpointer;typedef int gboolean;typedef const void *gconstpointer;typedef gint            (*GCompareFunc)         (gconstpointer  a,                                                 gconstpointer  b);typedef gint            (*GCompareDataFunc)     (gconstpointer  a,                                                 gconstpointer  b, gpointer       user_data);typedef void            (*GFunc)                (gpointer       data,                                                 gpointer       user_data);#ifdef __cplusplusextern "C" {#endif                                                 /* Doubly linked lists *//*  void     g_list_push_allocator (GAllocator       *allocator);  void     g_list_pop_allocator  (void);*/GList*   g_list_alloc          (void);void     g_list_free           (GList            *list);void     g_list_free_1         (GList            *list);GList*   g_list_append         (GList            *list,void *          data);GList*   g_list_prepend        (GList            *list,void *          data);GList*   g_list_insert         (GList            *list,void *          data,gint              position);GList*   g_list_insert_sorted  (GList            *list,void *          data,GCompareFunc      func);GList*   g_list_insert_before  (GList            *list,GList            *sibling,void *          data);GList*   g_list_concat         (GList            *list1,GList            *list2);GList*   g_list_remove         (GList            *list,gconstpointer     data);GList*   g_list_remove_all     (GList            *list,gconstpointer     data);GList*   g_list_remove_link    (GList            *list,GList            *llink);GList*   g_list_delete_link    (GList            *list,GList            *link_);GList*   g_list_reverse        (GList            *list);GList*   g_list_copy           (GList            *list);GList*   g_list_nth            (GList            *list,guint             n);GList*   g_list_nth_prev       (GList            *list,guint             n);GList*   g_list_find           (GList            *list,gconstpointer     data);GList*   g_list_find_custom    (GList            *list,gconstpointer     data,GCompareFunc      func);gint     g_list_position       (GList            *list,GList            *llink);gint     g_list_index          (GList            *list,gconstpointer     data);GList*   g_list_last           (GList            *list);GList*   g_list_first          (GList            *list);guint    g_list_length         (GList            *list);void     g_list_foreach        (GList            *list,GFunc             func,void *          user_data);GList*   g_list_sort           (GList            *list,GCompareFunc      compare_func);GList*   g_list_sort_with_data (GList            *list,GCompareDataFunc  compare_func,void *          user_data);void    *g_list_nth_data       (GList            *list,guint             n);#ifdef __cplusplus}#endif#define g_list_previous(list)((list) ? (((GList *)(list))->prev) : NULL)#define g_list_next(list)((list) ? (((GList *)(list))->next) : NULL)typedef GList GSList;#define g_slist_prepend g_list_prepend#define g_slist_free g_list_free#define g_slist_free_1  g_list_free_1#define g_slist_reverse g_list_reverse#define g_slist_next g_list_next#define g_slist_foreach g_list_foreach#define g_slist_length g_list_length/* to be continued...*/#endif /* __G_LIST_H__ */

源文件:

/* GLIB - Library of useful routines for C programming * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * Modified by the GLib Team and others 1997-2000.  See the AUTHORS * file for a list of people on the GLib Team.  See the ChangeLog * files for a list of changes.  These files are distributed with * GLib at ftp://ftp.gtk.org/pub/gtk/.  *//*  * MT safe */#include "StdAfx.h"#include "glist.h"#define _g_list_alloc g_list_allocGList* g_list_alloc (void){  GList *list;    list = g_new0 (GList, 1);    return list;}voidg_list_free (GList *list){  GList *last;    while (list)    {      last = list;      list = list->next;      g_free (last);    }}#define _g_list_free_1 g_list_free_1voidg_list_free_1 (GList *list){  g_free (list);}GList*g_list_append (GList*list,       void * data){  GList *new_list;  GList *last;    new_list = _g_list_alloc ();  new_list->data = data;    if (list)    {      last = g_list_last (list);      /* g_assert (last != NULL); */      last->next = new_list;      new_list->prev = last;      return list;    }  else    return new_list;}GList*g_list_prepend (GList *list,void *  data){  GList *new_list;    new_list = _g_list_alloc ();  new_list->data = data;    if (list)    {      if (list->prev){  list->prev->next = new_list;  new_list->prev = list->prev;}      list->prev = new_list;      new_list->next = list;    }    return new_list;}GList*g_list_insert (GList*list,       void * data,       gint position){  GList *new_list;  GList *tmp_list;    if (position < 0)    return g_list_append (list, data);  else if (position == 0)    return g_list_prepend (list, data);    tmp_list = g_list_nth (list, position);  if (!tmp_list)    return g_list_append (list, data);    new_list = _g_list_alloc ();  new_list->data = data;    if (tmp_list->prev)    {      tmp_list->prev->next = new_list;      new_list->prev = tmp_list->prev;    }  new_list->next = tmp_list;  tmp_list->prev = new_list;    if (tmp_list == list)    return new_list;  else    return list;}GList*g_list_insert_before (GList   *list,      GList   *sibling,      void * data){  if (!list)    {      list = g_list_alloc ();      list->data = data;      g_return_val_if_fail (sibling == NULL, list);      return list;    }  else if (sibling)    {      GList *node;      node = g_list_alloc ();      node->data = data;      if (sibling->prev){  node->prev = sibling->prev;  node->prev->next = node;  node->next = sibling;  sibling->prev = node;  return list;}      else{  node->next = sibling;  sibling->prev = node;  g_return_val_if_fail (sibling == list, node);  return node;}    }  else    {      GList *last;      last = list;      while (last->next)last = last->next;      last->next = g_list_alloc ();      last->next->data = data;      last->next->prev = last;      return list;    }}GList *g_list_concat (GList *list1, GList *list2){  GList *tmp_list;    if (list2)    {      tmp_list = g_list_last (list1);      if (tmp_list)tmp_list->next = list2;      elselist1 = list2;      list2->prev = tmp_list;    }    return list1;}GList*g_list_remove (GList     *list,       gconstpointer  data){  GList *tmp;    tmp = list;  while (tmp)    {      if (tmp->data != data)tmp = tmp->next;      else{  if (tmp->prev)    tmp->prev->next = tmp->next;  if (tmp->next)    tmp->next->prev = tmp->prev;    if (list == tmp)    list = list->next;    _g_list_free_1 (tmp);    break;}    }  return list;}GList*g_list_remove_all (GList*list,   gconstpointer data){  GList *tmp = list;  while (tmp)    {      if (tmp->data != data)tmp = tmp->next;      else{  GList *next = tmp->next;  if (tmp->prev)    tmp->prev->next = next;  else    list = next;  if (next)    next->prev = tmp->prev;  _g_list_free_1 (tmp);  tmp = next;}    }  return list;}static inline GList*_g_list_remove_link (GList *list,     GList *link){  if (link)    {      if (link->prev)link->prev->next = link->next;      if (link->next)link->next->prev = link->prev;            if (link == list)list = list->next;            link->next = NULL;      link->prev = NULL;    }    return list;}GList*g_list_remove_link (GList *list,    GList *link){  return _g_list_remove_link (list, link);}GList*g_list_delete_link (GList *list,    GList *link){  list = _g_list_remove_link (list, link);  _g_list_free_1 (link);  return list;}GList*g_list_copy (GList *list){  GList *new_list = NULL;  if (list)    {      GList *last;      new_list = _g_list_alloc ();      new_list->data = list->data;      last = new_list;      list = list->next;      while (list){  last->next = _g_list_alloc ();  last->next->prev = last;  last = last->next;  last->data = list->data;  list = list->next;}    }  return new_list;}GList*g_list_reverse (GList *list){  GList *last;    last = NULL;  while (list)    {      last = list;      list = last->next;      last->next = last->prev;      last->prev = list;    }    return last;}GList*g_list_nth (GList *list,    guint  n){  while ((n-- > 0) && list)    list = list->next;    return list;}GList*g_list_nth_prev (GList *list, guint  n){  while ((n-- > 0) && list)    list = list->prev;    return list;}void *g_list_nth_data (GList     *list, guint      n){  while ((n-- > 0) && list)    list = list->next;    return list ? list->data : NULL;}GList*g_list_find (GList         *list,     gconstpointer  data){  while (list)    {      if (list->data == data)break;      list = list->next;    }    return list;}GList*g_list_find_custom (GList         *list,    gconstpointer  data,    GCompareFunc   func){  g_return_val_if_fail (func != NULL, list);  while (list)    {      if (! func (list->data, data))return list;      list = list->next;    }  return NULL;}gintg_list_position (GList *list, GList *link){  gint i;  i = 0;  while (list)    {      if (list == link)return i;      i++;      list = list->next;    }  return -1;}gintg_list_index (GList         *list,      gconstpointer  data){  gint i;  i = 0;  while (list)    {      if (list->data == data)return i;      i++;      list = list->next;    }  return -1;}GList*g_list_last (GList *list){  if (list)    {      while (list->next)list = list->next;    }    return list;}GList*g_list_first (GList *list){  if (list)    {      while (list->prev)list = list->prev;    }    return list;}guintg_list_length (GList *list){  guint length;    length = 0;  while (list)    {      length++;      list = list->next;    }    return length;}voidg_list_foreach (GList *list,GFunc  func,void *  user_data){  while (list)    {      GList *next = list->next;      (*func) (list->data, user_data);      list = next;    }}GList*g_list_insert_sorted (GList        *list,                      void *      data,                      GCompareFunc  func){  GList *tmp_list = list;  GList *new_list;  gint cmp;  g_return_val_if_fail (func != NULL, list);    if (!list)     {      new_list = _g_list_alloc ();      new_list->data = data;      return new_list;    }    cmp = (*func) (data, tmp_list->data);    while ((tmp_list->next) && (cmp > 0))    {      tmp_list = tmp_list->next;      cmp = (*func) (data, tmp_list->data);    }  new_list = _g_list_alloc ();  new_list->data = data;  if ((!tmp_list->next) && (cmp > 0))    {      tmp_list->next = new_list;      new_list->prev = tmp_list;      return list;    }     if (tmp_list->prev)    {      tmp_list->prev->next = new_list;      new_list->prev = tmp_list->prev;    }  new_list->next = tmp_list;  tmp_list->prev = new_list;   if (tmp_list == list)    return new_list;  else    return list;}static GList *g_list_sort_merge (GList     *l1,    GList     *l2,   GFunc     compare_func,   gboolean  use_data,   void *  user_data){  GList list, *l, *lprev;  gint cmp;  l = &list;   lprev = NULL;  while (l1 && l2)    {      if (use_data)cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data);      elsecmp = ((GCompareFunc) compare_func) (l1->data, l2->data);      if (cmp <= 0)        {  l->next = l1;  l = l->next;  l->prev = lprev;   lprev = l;  l1 = l1->next;        }       else {  l->next = l2;  l = l->next;  l->prev = lprev;   lprev = l;  l2 = l2->next;        }    }  l->next = l1 ? l1 : l2;  l->next->prev = l;  return list.next;}static GList* g_list_sort_real (GList    *list,  GFunc     compare_func,  gboolean  use_data,  void *  user_data){  GList *l1, *l2;    if (!list)     return NULL;  if (!list->next)     return list;    l1 = list;   l2 = list->next;  while ((l2 = l2->next) != NULL)    {      if ((l2 = l2->next) == NULL) break;      l1 = l1->next;    }  l2 = l1->next;   l1->next = NULL;   return g_list_sort_merge (g_list_sort_real (list, compare_func, use_data, user_data),    g_list_sort_real (l2, compare_func, use_data, user_data),    compare_func,    use_data,    user_data);}GList *g_list_sort (GList        *list,     GCompareFunc  compare_func){  return g_list_sort_real (list, (GFunc) compare_func, FALSE, NULL);    }GList *g_list_sort_with_data (GList            *list,       GCompareDataFunc  compare_func,       void *          user_data){  return g_list_sort_real (list, (GFunc) compare_func, TRUE, user_data);}


原创粉丝点击