一个复杂一点的单向链表

来源:互联网 发布:linux 磁盘使用情况 编辑:程序博客网 时间:2024/05/06 12:19
/***********************************************************************************  ** 作者:杨志永                                                                    **  日期: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;}}

这个是自己写的单向链表,不知道有没有什么问题,如有发现问题请告诉一下,呵呵.第一次写.

原创粉丝点击