/**********************************************************************************
* *
* 作者:杨志永 *
* 日期:2012-05-13 *
* QQ:929168233 *
* Email:ljy520zhiyong@163.com *
* *
* 文件名: linkList.c *
* *
* 功能:创建链表,添加节点,求链表的长度 *
* *
***********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
#define DEBUG FALSE //标识是否处理调试介段
#define N 80 //最大的名字的字符个数
static int count = 0; //标识链表中的成员是第count次插入的
struct Student
{
char name[N+1]; //学生的名字
int age; //学生的年龄
};
struct list
{
struct Student * student; //链表节点中有一个学生成员
int length; //标识该成员是第length次插入的
struct list * next; //指向下一个链表的成员
};
struct list * initList(void); //初始化链表并返回头指针
_Bool add_member(struct list * linkList, int position, struct Student node); //在链表linkList中的第position位置中插入一个学生成员node,并返回结果.1为成功插入;0为插入失败
void showLinkList(struct list * linkList, int length); //打印链表中的所有成员
int linkListLength(struct list * linkList); //求出链表的长度,并返回该长度
int main(void)
{
struct list * linkList = NULL; //用于接收初始化链表的头指针
struct Student student1 = {"yangzhiyong1", 11}; //结构体学生变量并初始化
struct Student student2 = {"yangzhiyong2", 12};
struct Student student3 = {"yangzhiyong3", 13};
struct Student student4 = {"yangzhiyong4", 14};
linkList = initList(); //初始化链表并接收其链表的头指针
if ( add_member(linkList, 1, student1) ) //添加一个学生成员,并放在原有链表中的第一个位置
{
if(DEBUG)
{
printf("添加成功!\n");
}
}
else
{
if (DEBUG)
{
printf("添加失败!\n");
}
}
if ( add_member(linkList, 1, student2) ) //添加一个学生成员,并放在原有链表中的第一个位置
{
if(DEBUG)
{
printf("添加成功!\n");
}
}
else
{
if (DEBUG)
{
printf("添加失败!\n");
}
}
if ( add_member(linkList, 1, student3) ) //添加一个学生成员,并放在原有链表的第一个位置
{
if(DEBUG)
{
printf("添加成功!\n");
}
}
else
{
if (DEBUG)
{
printf("添加失败!\n");
}
}
if ( add_member(linkList, 1, student4) ) //添加一个学生成员,并放在原有链表的第一个位置
{
if(DEBUG)
{
printf("添加成功!\n");
}
}
else
{
if (DEBUG)
{
printf("添加失败!\n");
}
}
//以上四个插入操作,使得链表中成员的顺序为:student4->student3->student2->student1,即反序插入
int length = linkListLength(linkList); //获取链表的长度(不包括其头指针)
printf("linkList's lenght is %d\n", length);
showLinkList(linkList, length); //打印链表,第一个参数为链表的头指针,第二个为链表的长度
free(linkList); //程序结束后释放其链表的内存空间
linkList = NULL; //并使链表的头指针置空
if (DEBUG)
{
printf("释放linkList内存成功!\n");
}
exit(EXIT_SUCCESS); //成功退出程序
}
struct list * initList(void)
{
if (DEBUG)
{
printf("开始初始化链表空间\n");
}
struct list * linkList = (struct list *)malloc( sizeof(struct list) );
struct Student * student = (struct Student *)malloc( sizeof(struct Student) );
if ( linkList==NULL || student==NULL)
{
printf("在文件%s第%d行中分配内存失败!\n", __FILE__, __LINE__);
exit(EXIT_FAILURE);
}
else
{
if (DEBUG)
{
printf("初始化分配内存空间成功!\n");
}
}
linkList->student = student;
strcpy(linkList->student->name, "默认值");
linkList->student->age = 0;
linkList->length = count++;
linkList->next = NULL;
if (DEBUG)
{
printf("初始化完毕\n");
}
return linkList;
}
_Bool add_member(struct list * linkList, int position, struct Student node)
{
_Bool flag = 0; //判断是否成功插入到链表
int i = 0;
struct list * head = linkList; //声明一个链表的指针,并将头指针赋值给它,用于操作链表而又不影响原有链表的头指针
struct list * new_node = (struct list *) malloc( sizeof(struct list) ); //分配一个新节点的内存空间
struct Student * new_student = (struct Student *) malloc( sizeof(struct Student) ); //分配个学生结构体的内存空间
int length = linkListLength(head); //获取链表的长度
if ( new_node==NULL || new_student==NULL || linkList==NULL ) //如果分配内存空间出错则退出
{
printf("在文件%s第%d行中分配新节点内存失败!\n", __FILE__, __LINE__);
exit(EXIT_FAILURE);
}
else
{
if (DEBUG)
{
printf("添加元素中分配内存成功呀!\n");
}
}
if ( position < 1 || position > length + 1 ) //判断插入的位置是否合法不能插在头结点的前面
{ //也不能插入在原有链表长度+1之后的位置
if (DEBUG)
{
printf("插入的位置出错啦\n");
}
return flag;
}
else
{
if (DEBUG)
{
printf("插入的位置合法!\n");
}
}
if ( length < 1 ) //判断是否是第一次插入节点
{
while( linkList->next )
{
linkList = linkList->next;
}
if (DEBUG)
{
printf("开始初始化新添加的元素的值\n");
}
new_node->student = new_student; //初始化链表节点的student成员
strcpy( new_node->student->name ,node.name ); //初始化链表节点中的student成员中的name成员
new_node->student->age = node.age; //初始化锭表节点中的student成员中的age成员
new_node->length = count++; //标识是第count次插入的数据
linkList->next = new_node; //将头指针指向该节点的首地址
new_node->next = NULL; //并将该节点的下一个成员置空,因为是第一次插入嘛,所以后面必定为NULL
}
else
{
while( linkList->next && i < position-1) //移动头指针到position的结点位置中
{
i++;
linkList = linkList->next;
}
if (DEBUG)
{
printf("开始初始化新添加的元素的值\n");
}
new_node->student = new_student; //初始化链表节点的student成员
strcpy( new_node->student->name ,node.name ); //初始化链表节点中的student成员中的name成员
new_node->student->age = node.age; //初始化锭表节点中的student成员中的age成员
new_node->length = count++; //标识是第count次插入的数据
new_node->next = linkList->next; //将新添加的节点的下个成员指向前一个节点的next成员
linkList->next = new_node; //然后将前一个节点的next成员指向新添加的节点
}
linkList = head; //重置链表的指针为头指针
flag = 1; //标识为成功插入
return flag; //返回结果标识
}
int linkListLength(struct list * linkList)
{
int length = 0; //统计链表的长度
struct list * head = linkList; //声明一个链表指针使其指向链表的头指针
while( linkList->next ) //统计长度(不包括头指针)
{
length++;
linkList = linkList->next;
}
linkList = head; //重置链表的头指针
return length; //返回求得的链表的长度
}
void showLinkList(struct list * linkList, int length)
{
struct list * head = linkList; //声明一个指向当前链表头结点的指针
if ( length <= 0 ) //判断链表中是否有数据
{
printf("链表中没有数据!\n");
return;
}
else
{
printf("链表中的成员个数为%d\n", length);
}
if (DEBUG)
{
printf("开始打印\n");
}
while( head->next ) //开始打印链表结点的值
{
printf("length is %d\n", head->next->length);
printf("student's name is %s, student's age is %d\n", head->next->student->name, head->next->student->age);
head = head->next;
}
}
这个是自己写的单向链表,不知道有没有什么问题,如有发现问题请告诉一下,呵呵.第一次写.