分类: C/C++
2010-10-05 12:07:27
#include#include #define TRUE 1 /*操作成功返回1*/ #define FALSE 0 /*操作失败返回0*/ #define LEN sizeof(struct student) /*定义一个常量LEN,它代表每个节点的大小*/ struct student{ /*这个部分是定义链表每个节点的数据内容*/ char name[20]; /*学生姓名*/ int num; /*学生学号*/ int score; /*学生成绩*/ struct student *next; /*指向下一个节点地址的指针*/ }; int n; /*声明一个变量,该变量表示节点的数量,换句话说就是学生数据的数量,因为一个节点储存一个学生的数据*/ struct student *creat() /*创建节点的函数*/ { struct student *head; /*创建一个头指针,该指针指向链表头,起到根指针(root)的作用*/ struct student *p1 = NULL; /*创建一个工具指针,目的为了指向新节点,由于目前是空链表,没有节点,所以初始化为NULL*/ struct student *p2 = NULL; /*创建另一个工具指针,目的是为了指向链表最后一个节点,我们暂时也初始化为NULL*/ n = 0; /*n在之前声明为节点数量,由于是空表,所以初始化为0*/ p1 = (struct student *)malloc(LEN); /*创建节点前,我们必须先申请节点的内存空间,LEN在预处理时已经定义为节点的大小*/ p2 = p1; /*新节点空间出来了,我们将空间首地址的备份在p2中,这时p1和p2这两个工具指针都指向新节点的地址*/ /*下面开始验证新节点空间是否申请成功*/ if(p1 == NULL){ printf("Creation Failed!\n"); /*如果p1为NULL,则表示空间申请失败,文字告知程序员*/ return FALSE; /*并返回FALSE代码,与处理时定义为0*/ }else{ head = NULL; /*申请节点空间成功后,我们就可以使用该空间了,这时我们首先要把指向链表头的头指针初始化为NULL*/ pritnf("Enter %d of students.", n+1); /*输入第n个学生资料,由于n初始为0,而每次输入都是基于前一次数量+1*/ scanf("%s, %d, %d", &(p1->name), &(p1->num), &(p1->score)); /*分别输入name/num/score并保存在节点中*/ } /*第一个学生资料输完了,我们要考虑循环输入的问题*/ while(p1->num != 0){ /*只要学生学号不为0,那么就一直录入数据*/ n += 1; if(n == 1){ /*如果仅仅输入一个学生资料*/ head = p1; /*那么第一个节点的首地址,就是链表的首地址,而这个唯一节点还必须要承担链表尾节点的作用*/ p2->next = NULL; /*第一个节点同时也是最后一个节点,因为p2备份了p1的地址,那么节点的next指针就指向NULL*/ }else{ /*如果不止一个学生资料*/ p2->next = p1; /*那么这个节点指向下一个新节点的地址,因为p1始终保存的是新节点的地址*/ } p2 = p1; p1 = (struct student *)malloc(LEN); pritnf("Enter %d of students.", n+1); scanf("%s, %d, %d", &(p1->name), &(p1->num), &(p1->score)); } p2->next = NULL; /*当输入0时,录入结束,p2所在的位置是最后一个节点,那么next指向NULL*/ free(p1); /*工具使用完了,要还给系统*/ p1 = NULL; /*由于空间释放掉了,p1成了无家可归的人,我们把它收回来*/ return TRUE; /*最后返回TRUE,即表示成功的1*/ }
总结一下创建一个链表的几个步骤:
1 – 创建链表前,首先要知道链表里的节点中,保存的数据都有哪些,因此我们要先声明节点的结构体数据类型;
2 – 为了链表的操作,我们肯定要创建工具指针,因为它们会帮助我们始终指向我们想要指向的地方;
3 – 申请空间后一定要验证空间的可用性;
4 – 录入数据后,要判断数据的录入是否具有延续性,还是一次性;
5 – 录入数据完毕后,切记要让最后一个节点指向NULL;
6 – 用完链表后,记得有malloc,就要有free;
7 – 回收工具指针;
8 – 返回成功代码。