经常用到链表,但每次写都不那么顺利,终于有点时间整理一下,把感觉写的不错的代码拿出来分享,希望大家能指出问题,那我算没白写。 该链表以存放整型数据为例。
头文件:
#ifndef __LINK_H__
#define __LINK_H__
#define ERROR ( -1 )
#define OK ( 0 )
#define TRUE ( 1 == 1 )
#define FALSE ( !TRUE )

typedef int BOOL;
typedef int elem_t; //定义元素的数据类型 
typedef struct node
...{
elem_t data;
struct node * next;
}tagNode_t,tagList_t;


/**//* 把已经存在的头节点进行初始化为一个空链表 */
void initList ( tagList_t * list );
/**//* 销毁链表 */
void destroyList( tagList_t * list );

/**//* 将链表重置为空 */
void clearList( tagList_t * list );
BOOL listEmpty( tagList_t * list );
int listLength( tagList_t * list );

/**//* 得到指定位置 pos 的元素,如果顺利得到则返回TRUE,否则返回 FALSE*/
BOOL getElem( tagList_t * list, int iPos, elem_t * e);

/**//* 返回第一个满足 compare 关系的元素的位置,如果不存在则返回 -1 */
int locateElem( tagList_t * list, elem_t e,
BOOL (*compare)(elem_t e1,elem_t e2));

/**//* 将元素e插到链表的指定位置 ,若iPos > listLength() 则插到最后*/
BOOL listInsert( tagList_t * list, int iPos, elem_t e );
BOOL listInsertFront( tagList_t * list, elem_t e );

/**//* 按照费递减序插入元素 e */
BOOL listSortInsert( tagList_t * list, elem_t e );
BOOL listDeleteFront( tagList_t * list, elem_t * e );

/**//* 用visit 函数遍历链表 */
void listTraverse( tagList_t * list, void (*visit)(elem_t e));

#endif
源文件:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "link.h"


/**//* 把已经存在的头节点进行初始化为一个空链表 */
void initList ( tagList_t * list )
...{
list->next = NULL;
}
/**//* 销毁链表,没有释放头结点 */
void destroyList( tagList_t * list )
...{
tagNode_t * pn = NULL;
assert( list != NULL );
pn = list->next;
while( pn != NULL)
...{
list->next = pn->next;
free( pn );
pn = list->next;
}
}

/**//* 将链表重置为空 */
void clearList( tagList_t * list )
...{
destroyList( list ); //同 销毁
}
BOOL listEmpty( tagList_t * list )
...{
return ( NULL == list->next );
}
int listLength( tagList_t * list )
...{
int iLen = 0;
tagNode_t * ptn = NULL;
assert( list != NULL );
ptn = list->next;
while( ptn != NULL )
...{
iLen += 1;
ptn = ptn->next;
}
return iLen;
}

/**//* 得到指定位置 pos 的元素,如果顺利得到则返回TRUE,否则返回 FALSE*/
BOOL getElem( tagList_t * list, int iPos, elem_t * e)
...{
BOOL bRet = FALSE;
tagNode_t * ptn = NULL;
assert( list ); //list != NULL
if( list || ( iPos >= 0 ) )
...{
ptn = list->next;
while( iPos-- && ptn )
...{
ptn = ptn->next;
}
if( ptn != NULL )
...{
*e = ptn->data;
bRet = TRUE;
}
}
return bRet;
}

/**//* 返回第一个满足 compare 关系的元素的位置,如果不存在则返回 0 */
int locateElem( tagList_t * list, elem_t e,
BOOL (*compare)(elem_t e1,elem_t e2))
...{
int iPos = 0;
tagNode_t * ptn = NULL;
assert( list ); //list != NULL
ptn = list->next;
while( ptn )
...{
iPos += 1;
if( compare( e, ptn->data ) )
...{
break;
}
ptn = ptn->next;
}
if( NULL == ptn )
...{
iPos = 0;
}
return iPos;
}

/**//* 将元素e插到链表的指定位置 ,若iPos > listLength() 则插到最后*/
BOOL listInsert( tagList_t * list, int iPos, elem_t e )
...{
BOOL bRet = FALSE;
tagNode_t * ptn = NULL, * pstNew = NULL;
assert( list ); //list != NULL
if( list || (iPos >= 0) )
...{
ptn = list->next;
while( iPos-- && ptn->next )
...{
ptn = ptn->next;
} 
pstNew = ( tagNode_t * )malloc( sizeof( tagNode_t ) );
if( pstNew != NULL )
...{
pstNew->data = e;
pstNew->next = ptn->next;
ptn->next = pstNew;
bRet = TRUE;
}
}
return bRet;
}
BOOL listInsertFront( tagList_t * list, elem_t e )
...{
BOOL bRet = FALSE;
tagNode_t * pstNew =
( tagNode_t * )malloc( sizeof( tagNode_t ) );
assert( list );
if( pstNew != NULL )
...{
pstNew->data = e;
pstNew->next = list->next;
list->next = pstNew;
bRet = TRUE;
}
return bRet;
}

/**//* 按照非递减序插入元素 e */
BOOL listSortInsert( tagList_t * list, elem_t e )
...{
BOOL bRet = FALSE;
tagNode_t * ptn = NULL, * pstNew = NULL;
assert( list );
ptn = list;
while( ptn->next )
...{
if( ptn->next->data > e )
...{
bRet = TRUE;
break;
}
ptn = ptn->next;
}
pstNew = ( tagNode_t * )malloc( sizeof( tagNode_t ) );
if( pstNew != NULL)
...{
pstNew->data = e;
pstNew->next = ptn->next;
ptn->next = pstNew;
bRet = TRUE;
}
return bRet;
}
BOOL listDeleteFront( tagList_t * list, elem_t * e )
...{
BOOL bRet = FALSE;
tagNode_t * ptn = NULL;
if( list != NULL )
...{
ptn = list->next;
*e = ptn->data;
list->next = ptn->next;
free( ptn );
bRet = TRUE;
}
return bRet;
}

/**//* 用visit 函数遍历链表 */
void listTraverse( tagList_t * list, void (*visit)(elem_t e))
...{
tagNode_t * ptn = NULL, * pstNew = NULL;
assert( list );
ptn = list->next;
while( ptn )
...{
visit( ptn->data );
ptn = ptn->next;
}
}

测试文件:
include <stdio.h>
#include "link.h"
void tst_link()
...{
elem_t e;
tagList_t list;
printf("********Test Stack******** ");
initList( &list );
printf("IsEmpty: %s ",(listEmpty( &list ) ? "true":"false"));
listSortInsert( &list, 4 );
listSortInsert( &list, 3 );
printf("5 in pos: %d ",locateElem( &list,5,elemEqual ));
listSortInsert( &list, 5 );
printf("5 in pos: %d ",locateElem( &list,5,elemEqual ));
listSortInsert( &list, 7 );
listSortInsert( &list, 2 );
printf("getElem (3) %s : %d ",(getElem( &list, 3, &e )?"right":"error"),e);
printf("getElem (6) %s : %d ",(getElem( &list, 6, &e )?"right":"error"),e);
listPrint( &list );
printf(" ");
printf("len: %d ",listLength( &list ));
listDeleteFront( &list, &e );
printf("After delete front len: %d ",listLength( &list ));
printf("IsEmpty: %s ",(listEmpty( &list ) ? "true":"false"));
printf("5 in pos: %d ",locateElem( &list,5,elemEqual ));
destroyList( &list );
printf("IsEmpty: %s ",(listEmpty( &list ) ? "true":"false"));
}

本文分享了一段C语言实现的带头结点的链表代码,适用于存放整型数据。作者希望通过分享代码,得到大家的反馈和建议。
5816

被折叠的 条评论
为什么被折叠?



