分享:通用链表(有任何问题或建议,请提出)(5.2新增两个函数)
思路借鉴了库函数qsort,由具体的程序提供比较和打印函数,GenericityList.h中的函数完成对链表的所有操作。 链表中的值字段可以是任意的数据类型。
Insert函数要求提供数据类型的大小,以及一个比较函数。
Print函数要求提供一个打印函数。
DeleteNode函数要求提供一个比较函数。
5.2
新增两个函数,QuickOperateR() 和 OperateR()
这两个函数执行相同的任务,逆向操作链表中的节点,如果只是单纯的逆序打印链表中的节点,那么这两个函数等同于Reverse()+ Print() + Reverse()函数相同。
这两个函数的不同在于,QuickOperateR为递归实现。
而OperateR为迭代实现。
创建链表,我没明白有什么用,所以就没写。
在Insert中,比较函数如果永远返回-1,那么就是头部插入;如果永远返回1,就是尾部插入;根据不同的比较函数的返回值,也可以按照升序或降序插入。
应用:
https://bbs.bccn.net/viewthread.php?tid=476513&page=1&extra=page%3D1#pid2626355
程序代码:
//测试: #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include "GenericityList.h" int COM( void *a, void *b ); int com( void *, void * ); void PRINT( void * ); int main( void ) { List Root; List T; int s; int ix; srand( ( unsigned )time( NULL ) ); Root = NULL; for( ix = 0; 20 > ix; ++ix ) { s = rand() % 10000; Insert( &Root, &s, sizeof( int ), COM); } Print( Root, PRINT ); Reverse( &Root ); printf("\n逆序后:\n"); Print( Root, PRINT ); DeleteNode( &Root, &s, com ); printf( "\n删除第一个节点:\n" ); Print( Root, PRINT ); T = First( Root ); printf( "\n首节点的值:" ); PRINT( T->Element ); printf( "\n" ); while( !DelFirst( &Root ) ) { printf( "\n删除首节点:" ); Print( Root, PRINT ); } if( NULL == ( T = First( Root ) ) ) printf( "\n空链表\n" ); printf( "\n\n\n" ); Delete( &Root ); Print( Root, PRINT ); return 0; } int COM( void *a, void *b ) { return ( *( int * )a - *( int * )b ) > 0? 1: -1; } int com( void *a, void *b ) { return 0; } void PRINT( void *a ) { printf("%d ",*( int* )a ); }
程序代码:
//接口: #ifndef _GENERICITY_LIST_ #define _GENERICITY_LIST_ struct List{ void *Element; struct List *Link; }; typedef struct List List_T; typedef List_T *List; typedef List List_T_P; int Insert( List *RootPP, void *Value, unsigned int DataSize , int ( *Compare )( void *, void * ) );//插入节点,成功返回1,否则返回1 void Print( List RootP, void ( *Print )( void * ) ); void Delete( List *RootPP ); int DeleteNode( List *RootPP, void *Value, int ( *Compare )( void *, void * ) );//删除节点,成功返回0,否则返回1 List Find( List RootP, void *Value, int ( *Compare )( void *, void * ) );//查找节点,成功返回该节点,否则返回NULL void Reverse( List *RootP ); List First( List RootP );//返回首节点,如果链表为空,则返回NULL int DelFirst( List *RootPP );//删除首节点,成功返回0,否则返回1 void OperateR( List Root, void ( *Operate )( List ) );//链表逆操作 void QuickOperateR( List Root, void ( *Operate )( List ) );//链表逆操作 #endif
程序代码:
//实现: #include "GenericityList.h" #include <stdlib.h> #include <stdio.h> #include <string.h> enum { OK = 0, NOT }; int Insert( List *RootPP, void *value, unsigned int DataSize , int ( *compare )( void *, void * ) ) { List Next; List NewCell; while( NULL != ( Next = *RootPP ) && 0 < compare( Next->Element, value ) ) RootPP = &Next->Link; if( NULL == ( NewCell = ( List )malloc( sizeof( struct List ) ) ) ) return NOT; if( NULL == ( NewCell->Element = malloc( DataSize ) ) ) return NOT; memmove( NewCell->Element, value, DataSize ); NewCell->Link = Next; *RootPP = NewCell; return OK; } void Print( List RootP, void ( *print )( void * ) ) { while( NULL != RootP ) { print( RootP->Element ); RootP = RootP->Link; } } void Delete( List *RootPP ) { List Temp; List This; for( This = *RootPP, *RootPP = NULL; NULL != This; This = Temp ) { Temp = This->Link; free( This->Element ); free( This ); } } int DeleteNode( List *RootPP, void *value, int ( *compare )( void *, void * ) ) { List This; for( ;NULL != ( This = *RootPP ); RootPP = &This->Link ) if( 0 == compare( This->Element, value ) ) break; if( NULL != This ) { *RootPP = This->Link; free( This->Element ); free( This ); return OK; } return NOT; } List Find( List RootP, void *value, int ( *compare )( void *, void * ) ) { List This; for( This = RootP; NULL != This; This = This->Link ) if( 0 == compare( This->Element, value ) ) break; return This; } List Reverse( List RootP ) { List Next, Current; for( Current = NULL; NULL != RootP; RootP = Next ) { Next = RootP->Link; RootP->Link = Current; Current = RootP; } return Current; } /*下面这个不要返回的Reverse函数好么,怎么都感觉不如有返回值的,还是说我写的太烂了。*/ /* void Reverse( List *RootP ) { List Next, Current; for( Current = NULL; NULL != *RootP; *RootP = Next ) { Next = (*RootP)->Link; (*RootP)->Link = Current; Current = *RootP; if( NULL == Next ) break; } } */ static int __C__O__M__( void *, void * ); List First( List RootP ) { return Find( RootP, ( void * )0, __C__O__M__ ); } int DelFirst( List *RootPP ) { return DeleteNode( RootPP, ( void * )0, __C__O__M__ ); } int __C__O__M__( void *a, void *b ) { return 0; } void QuickOperateR( List Root, void ( *Operate )( List ) ) { if( NULL == Root ) return; QuickOperateR( Root->Link, Operate ); Operate( Root ); } static void Push( List ); static List Pop( void ); static void Destroy( void ); static int IsEmpty( void ); static int IsFull( void ); void OperateR( List Root, void ( *Operate )( List ) ) { while( NULL != Root ) { Push( Root ); Root = Root->Link; } while( !IsEmpty() ) Operate( Pop() ); Destroy(); } #define INITSIZE 128 static List *Stack; static int Top = -1; static int CurrentSize = INITSIZE; int IsEmpty( void ) { return -1 == Top; } int IsFull( void ) { List *Temp; if( Top == CurrentSize ) { CurrentSize += INITSIZE; Temp = ( List * )realloc( Stack, CurrentSize * sizeof( List_T ) ); if( NULL == Temp ) { CurrentSize -= INITSIZE; return NOT; } Stack = Temp; return OK; } else return OK; } void Push( List a ) { if( NULL == Stack ) { Stack = ( List * )malloc( CurrentSize * sizeof( List_T ) ); if( NULL == Stack ) exit( EXIT_FAILURE ); } if( !IsFull() ) Stack[ ++Top ] = a; else return; } List Pop( void ) { return Stack[ Top--]; } void Destroy( void ) { free( Stack ); Stack = NULL; Top = -1; CurrentSize = INITSIZE; }
[此贴子已经被作者于2017-5-3 17:06编辑过]