C++直接用现成的STL标准模板类list就可以了,如果自己实现难度也不大。
C语言的话我这提供一个通用链表xlist,数据类型可自定义,调用者只需在上层分配好自定义结构堆空间,然后设置进去就可以了,xlist在销毁或者清空时自动释放,不需要调用者进行释放空间的操作。各种排序遍历算法使用回调进行,实现上层逻辑与链表结构的分离。
头文件声明如下:
//////////////////////////////////////////////////////////////////////////
//Created date: 2017/03/19
//Filename: xlist.h
//Author: tangm421@outlook.com
//Description: common linklist datatype declare
//////////////////////////////////////////////////////////////////////////
#ifndef __XLIST__HEADER__
#define __XLIST__HEADER__
//////////////////////////////////////////////////////////////////////////
//error description
typedef struct xlist_error_description_type
{
int errornum_;
const char* errordesc_;
}xlist_errdesc_t;
#define XLIST_OK 0
#define XLIST_OUTOFMEM -1
#define XLIST_NOT_CREATE -2
const char* xlist_error_string(int errornum);
//////////////////////////////////////////////////////////////////////////
//link list data struct
typedef struct xlist_type
{
void* data_;
struct xlist_type* next_;
}xlist_t;
int xlist_create(xlist_t** pplisthead);
void xlist_clear(xlist_t* const plisthead);
void xlist_destroy(xlist_t** pplisthead);
int xlist_size(xlist_t* const plisthead);
int xlist_insert_front(xlist_t* const plisthead, void* const data);
int xlist_insert_tail(xlist_t* const plisthead, void* const data);
typedef void (*traverse_action)(void* userdata, void* data);
typedef int (*traverse_condition)(void* userdata, void* data);
int xlist_condition_traverse(xlist_t* const plisthead, traverse_action cb1, void* userdata1, traverse_condition cb2, void* userdata2);
int xlist_condition_delete(xlist_t* const plisthead, traverse_condition cb, void* userdata);
typedef int(*sort_pred)(const void* const data1, const void* const data2);
int xlist_condition_sort(xlist_t* const plisthead, sort_pred cb);
#endif//#ifdef __XLIST__HEADER__
主函数测试代码示例:
//////////////////////////////////////////////////////////////////////////
//Created date: 2017/03/25
//Filename: main.c
//Author: tangm421@outlook.com
//Description:
//////////////////////////////////////////////////////////////////////////
#include "xlist.h"
#include
#include
void traverse_data(void* userdata, void* data)
{
int* index = (int*)userdata;
int* elem = (int*)data;
printf("number %d data: %d\n", (*index)++, *elem);
}
int main(int argc, char* argv[])
{
int ret = 0;
xlist_t* pheader = NULL;
int* data = NULL;
int count = 1;
//创建链表
if((ret = xlist_create(&pheader)) < 0)
{
printf("%s\n", xlist_error_string(ret));
return -1;
}
//添加元素
data = (int*)malloc(sizeof(int));
*data = 12;
xlist_insert_front(pheader, data);
data = (int*)malloc(sizeof(int));
*data = 9;
xlist_insert_front(pheader, data);
data = (int*)malloc(sizeof(int));
*data = 7;
xlist_insert_front(pheader, data);
data = (int*)malloc(sizeof(int));
*data = 3;
xlist_insert_front(pheader, data);
data = (int*)malloc(sizeof(int));
*data = 2;
xlist_insert_front(pheader, data);
//遍历链表
count = 1;
printf("-------------遍历链表元素开始---------------\n");
xlist_condition_traverse(pheader, traverse_data, &count, NULL, NULL);
printf("-------------遍历链表元素结束---------------\n");
//销毁链表
xlist_destroy(&pheader);
return 0;
}
示例运行结果:
L是一个不带头结点的单链表的头指针。 一开始判断该指针以及该指针指向的下一个结点是否为空,如果不为空,代表该链表存在,然后将指针L的指向给q,并且L指向L的下一个结点(L=L->next), 再指向下一个结点之后,再将L的指向给p。
楼上厉害,写这个好浪费时间啊。