今天我们来实现带头结点的一个单链表的创建。
#include <stdio.h> #include <stdlib.h> #include <time.h> #define ElemType int typedef struct Node { ElemType data; struct Node * next; //指向下一个结点的指针 }Node; typedef struct Node* Linklist; //定义Linklist为指向每个结构体的指针 /*建立含有n个结点的带有头结点的链表*/ int creatListHead(Linklist *L,int n) { Linklist p = NULL; //定义一个结点 int i; srand(time(0)); //初始化随机数种子 *L = (Linklist)malloc(sizeof(Node)); //创建头结点 if(*L==NULL) { printf("node head malloc fail!\n"); return -1; } (*L)->next = NULL; //创建了一个只有头结点的单链表 /*创建新的结点并依次插入*/ for(i=0;i<n;i++) { p = (Linklist)malloc(sizeof(Node)); //为每个结点分配内存空间 if(p==NULL) //检查内存是否分配成功 { printf("node p malloc fail!\n"); return -1; } p->data = rand()%100 + 1; //随机产生一个100之内的数 p->next = (*L)->next; (*L)->next = p; } printf("finish creat linklist!\n"); return 0; } int main() { Linklist link = NULL; if(creatListHead(&link,10)==0) //创建链表 printf("creat back to main sucess!\n"); else printf("creat fail to main!\n"); return 0; }
如上标注颜色的地方为我们应该特别注意的地方:
1.创建一个指针的时候,一定要同时对其进行初始化为NULL,以免后面出现不必要的错误(如检查内存是否分配成功)
2.使用malloc()分配内存空间之后,一定马上检查指针是否为NULL,用来检测是否分配成功。
3.本次创建中,我们使用了“指向指针的指针”来作为创建单链表的参数。为以后链表中的插入操作删除等很多操作提供了方便:
1)每个链表结点,可能会发生删除插入操作,所以注定了结点结构体中的指针肯定会不断的发生变化———链表结点的定义一定要用指针来对结点进行间接访问
2)在传入头结点指针给调用函数时,在函数的操作过程中,会给头结点分配内存空间,对其进行修改。所以我们要用指向头结点指针的指针来作为函数的参数。
昨天就是因为问题2)浪费了一个下午的时间,最后终于在各位网友和校友的关注下弄明白了,在此谢谢大家~