双向链表常用操作

typedef struct _list {
  struct _list* plPrev;
  struct _list* plNext;
  void* p;
} list;
int ListCreate( list *pl ) {
   
    pl->plPrev = pl->plNext = pl;
    pl->p = NULL;

    return 0;
}

list *ListInsert( list *pl, void *p ) {

    list *plNew;

    if ( (plNew = (list*)malloc( sizeof( *plNew ))) == NULL )
return NULL;

    plNew->p = p;

    plNew->plNext = pl;
    plNew->plPrev = pl->plPrev;

    pl->plPrev = plNew;
    plNew->plPrev->plNext = plNew;

    return plNew;
}

void ListDelete( list *pl ) {

    pl->plPrev->plNext = pl->plNext;
    pl->plNext->plPrev = pl->plPrev;

    free( pl );
}

void ListDeleteAll( const list *pl ) {

while( pl->plNext->p )
{
free(pl->plNext->p);
ListDelete( pl->plNext );
}
}

------------------------------------------------------------------------

typedef struct psListNode
{
  struct psListNode
    *next,              /**< \internal */
    *prev;              /**< \internal */

  void
    *value;             /**< \internal */
} PSListNode;
/** \typedef PSListNode
*  \brief Typedef for psListNode structure. * \ingroup pslist
*/


/** \struct psList list.h ps/ps.h
*  \brief psList structure.
*  \ingroup pslist
*/

typedef struct psList
{
  PSListNode
    *first,             /**< \internal */
    *last;              /**< \internal */

  long
    numNodes;

  PSListDestroyFunc
    destroyFunc;        /**< \internal */
} PSList;

#include <stdio.h>
#include <stdlib.h>

#include "ps/list.h"

/**
*  \brief Allocates and initializes a new PSList.
*
*  \param destroyFunc pointer to a function to destroy/free the data
*  to be stored in the list.  May be set to NULL to indicate that the
*  data should not be destroyed (i.e. the list doesn't own the data or
*  items are statically allocated, etc.).
*
*  \returns a pointer to a new PSList on success or NULL on failure.
*  \sa psListFree().
*  \ingroup pslist
*/

PSList *
psListAlloc(PSListDestroyFunc destroyFunc)
{
  PSList
    *tempList;

  if((tempList = calloc(1, sizeof(PSList))) != NULL)
    tempList->destroyFunc = destroyFunc;

  return(tempList);
}

/**
*  \brief Frees up a PSList.
*
*  Calls the destroyFunc() on each piece of data if not NULL.
*
*  \param list pointer to PSList to be freed.
*  \returns nothing.
*  \sa psListAlloc().
*  \ingroup pslist
*/

void
psListFree(PSList *list)
{
  PSListNode
    *nextNode,
    *node;

  if(!list)
    return;

  for(node = list->first; node; node = nextNode)
  {
    nextNode = node->next;
    if(list->destroyFunc)
      list->destroyFunc(node->value);
    free(node);
  }

  free(list);
}

/**
*  \brief Creates and inserts a new PSListNode into \c list in front of
*  \c node.
*
*  \param list pointer to PSList in which to insert node.
*  \param node pointer to node to insert in front of.
*  \param value pointer to data to be stored.
*
*  \returns a pointer to the new node on success or NULL on failure.
*  \ingroup pslist
*/

PSListNode *
psListInsert(PSList *list, PSListNode *node, void *value)
{
  PSListNode
    *newNode;

  if(!list)
    return(NULL);

  if((newNode = calloc(1, sizeof(PSListNode))) != NULL)
  {
    newNode->value = value;

    if(node)
    {
      if(node->prev)
      {
        newNode->next = node;
        newNode->prev = node->prev;
        node->prev = newNode;
        newNode->prev->next = newNode;
      }
      else
      {
        newNode->next = list->first;
        if(list->first)
          list->first->prev = newNode;
        list->first = newNode;
        if(!list->last)
          list->last = newNode;
      }
    }
    else
    {
      if(list->last)
      {
        newNode->prev = list->last;
        list->last->next = newNode;
      }
      list->last = newNode;
      if(!list->first)
        list->first = newNode;
    }

    list->numNodes++;
  }

  return(newNode);
}

/**
*  \brief Deletes the specifed \c node (and data) from \c list.
*
*  Calls the destroyFunc on the data if not NULL.
*
*  \param list pointer to PSList.
*  \param node pointer to node to delete.
*
*  \returns nothing.
*  \ingroup pslist
*/

void
psListDelete(PSList *list, PSListNode *node)
{
  if(!list || !node)
    return;

  if(node->prev)
    node->prev->next = node->next;
  else
    if((list->first = node->next) != NULL)
      list->first->prev = NULL;

  if(node->next)
    node->next->prev = node->prev;
  else
    if((list->last = node->prev) != NULL)
      list->last->next = NULL;

  if(list->destroyFunc)
    list->destroyFunc(node->value);
  list->numNodes--;
  free(node);
}

/**
*  \brief Gets the first node in \c list.
*
*  \param list pointer to PSList.
*
*  \returns a pointer to the first node in \c list if the list has a first
*  node or NULL if not (the list is empty).
*  \ingroup pslist
*/

PSListNode *
psListFirst(PSList *list)
{
  if(list)
    return(list->first);
   
  return(NULL);
}

/**
*  \brief Gets the last node in \c list.
*
*  \param list pointer to PSList.
*
*  \returns a pointer to the last node in \c list if the list has a last
*  node or NULL if not (the list is empty).
*  \ingroup pslist
*/

PSListNode *
psListLast(PSList *list)
{
  if(list)
    return(list->last);
   
  return(NULL);
}

/**
*  \brief Gets the next node (following \c node) in \c list.
*
*  \param list pointer to PSList.
*  \param node pointer to node.
*
*  \returns A pointer to the node following \c node if one exists or NULL
*  if not (end of list).
*  \ingroup pslist
*/

PSListNode *
psListNext(PSList *list, PSListNode *node)
{
  if(list && node)
    return(node->next);
   
  return(NULL);
}

/**
*  \brief Gets the previous node (before \c node) in \c list.
*
*  \param list pointer to PSList.
*  \param node pointer to node.
*
*  \returns A pointer to the node previous to \c node if one exists or NULL
*  if not (beginning of list).
*  \ingroup pslist
*/

PSListNode *
psListPrev(PSList *list, PSListNode *node)
{
  if(list && node)
    return(node->prev);
   
  return(NULL);
}

/**
*  \brief Gets the number of nodes (items) in \c list.
*
*  \param list pointer to PSList.
*
*  \returns the number of items in \c list.
*  \ingroup pslist
*/

long
psListNumNodes(PSList *list)
{
  if(list)
    return(list->numNodes);
   
  return(0);
}

/**
*  \brief Gets the value stored in \c list at \c node.
*
*  \param list pointer to PSList.
*  \param node pointer to node from which to retieve data.
*
*  \returns the data stored in the specified node.
*  \ingroup pslist
*/

void *
psListGetValue(PSList *list, PSListNode *node)
{
  if(list && node)
    return(node->value);
   
  return(NULL);
}

/**
*  \brief Get the nodeNum'th node in \c list.
*
*  \returns a pointer to the nodeNum'th node in \c list or NULL if the
*  node doesn't exist.
*  \ingroup pslist
*/

PSListNode *
psListGetNode(PSList *list, long nodeNum)
{
  PSListNode
    *node;

  if(!list || nodeNum < 0 || nodeNum > list->numNodes)
    return(NULL);

  node = psListFirst(list);
  while(node && --nodeNum)
    node = psListNext(list, node);
   
  return(node);
}

原文地址:https://www.cnblogs.com/fx2008/p/2192840.html