1、首先定义公共头文件common.h,其中包含了枚举类型status_code的定义,目的是将其作为循环链表结构操作的返回类型。
#ifndef _common_h
#define _common_h
enum status_code { Success, Fail, MemoryOut, NotPresent, RangeError };
typedef enum status_code status_code;
#endif
2、抽象数据类型circ_link_list的定义circ_link_list.h,
#ifndef _circ_link_list_h
#define _circ_link_list_h
#include "common.h"
typedef int elem_type;
struct node;
typedef struct node node;
typedef node * node_ptr;
typedef node_ptr circ_link_list;
struct node
{
elem_type data;
node_ptr next;
};
status_code init_circ_list( circ_link_list * lst );
status_code clear_circ_list( circ_link_list lst );
status_code free_circ_list( circ_link_list * lst );
int is_clist_empty( circ_link_list lst );
int clist_size( circ_link_list lst );
void traverse_clst( circ_link_list lst );
status_code insert_elem_clst( circ_link_list * lst, int i, elem_type e );
status_code remove_elem_clst( circ_link_list * lst, int i, elem_type * e );
status_code get_elem_clst( circ_link_list lst, int i, elem_type * e );
int locate_elem_clst( circ_link_list lst, elem_type e );
#endif
3、循环链表ADT的实现,关键点在于链表结尾的判断,注意插入和删除操作时有些情况下需要对尾指针进行更新。
#include "circ_link_list.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
status_code init_circ_list( circ_link_list * lst )
{
status_code res = Success;
*lst = ( node_ptr )malloc( sizeof( node ) );
assert( *lst != NULL );
( *lst )->data = 0;
( *lst )->next = *lst;
return res;
}
status_code clear_circ_list( circ_link_list lst )
{
status_code res = Success;
node_ptr h = lst->next, p = h->next;
while( p != h )
{
h->next = p->next;
free( p );
p = h->next;
}
return res;
}
status_code free_circ_list( circ_link_list * lst )
{
status_code res = Success;
node_ptr h = (*lst)->next;
clear_circ_list( *lst );
free( h );
*lst = NULL;
return res;
}
int is_clist_empty( circ_link_list lst )
{
return lst->next == lst;
}
int clist_size( circ_link_list lst )
{
int len = 0;
node_ptr h = lst->next, p = h;
while( p != h )
{
++len; p = p->next;
}
return len;
}
void traverse_clst( circ_link_list lst )
{
node_ptr h = lst->next, p = h->next;
while( p != h )
{
printf( "%d ", p->data );
p = p->next;
}
putchar( '\n' );
}
status_code insert_elem_clst( circ_link_list * lst, int i, elem_type e )
{
status_code res = Success;
node_ptr h = (*lst)->next, p = h, s = NULL;
int j = 0;
int flag = 1;
while( j < i - 1 && ( flag || p != h ) )
{
flag = 0;
++j;
p = p->next;
}
if( j > i - 1 || ( !flag && p == h ) )
return RangeError;
s = ( node_ptr )malloc( sizeof( node ) );
assert( s != NULL );
s->data = e;
s->next = p->next;
p->next = s;
*lst = ( p == *lst ) ? s : *lst;
++h->data;
return res;
}
status_code remove_elem_clst( circ_link_list * lst, int i, elem_type * e )
{
status_code res = Success;
int j = 0;
node_ptr h = (*lst)->next, p = h, q = NULL;
int flag = 1;
while( j < i - 1 && ( flag || p->next != h ) )
{
++j;
p = p->next;
flag = 0;
}
if( j > i - 1 || ( ! flag && p->next == h ) )
return RangeError;
*e = p->next->data;
q = p->next;
if( q == *lst )
*lst = p;
p->next = q->next;
free( q );
return res;
}
status_code get_elem_clst( circ_link_list lst, int i, elem_type * e )
{
status_code res = Success;
node_ptr h = lst->next, p = h->next;
int j = 1;
while( j < i && p != h )
{
++j;
p = p->next;
}
if( j > i || p == h )
return RangeError;
*e = p->data;
return res;
}
int locate_elem_clst( circ_link_list lst, elem_type e )
{
int pos = 1;
node_ptr h = lst->next, p = h->next;
while( p != h && p->data != e )
{
p = p->next; ++pos;
}
return p == h ? -1 : pos;
}