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; #endif2、抽象数据类型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 ); #endif3、循环链表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; }