void main()
{
Node *head = NULL;
//第一种通过返回值来接收创建好的链表
//Node * createLinkList();
head = createLinkList();
//第二种,传入指向结点的指针
//void createLinkList(Node *head);
createLinkList(head);
//第三种,传入指向结点指针的指针
//void createLinkList(Node **Phead);
createLinkList(&head);
}
第一种:返回头指针去接收创建好的链遍,但是这种方式在使用的时候必须要有指针变量来接受创建的链表。这个不是强制要求的,别人在用我们写的程序时候,即使链表没有被接收也可以,也不会报错,不能强制别人去接收。所以这种方式不是很好。
/**
* 根据用户输入的数据创建一个链表
* */
Node * createLinkList()
{
int length;
printf("请输入结点个数");
scanf("%d",&length);
//生成一个结点
Node *head = NULL;
for(int i=0;i<length ;i++)
{
Node *p = (Node *)malloc(sizeof(Node));
printf("请输入第一个结点存放的数据");
scanf("%d",&p->data);
p->next = NULL;
Node *last = head;
if(last)
{
//如果第一个结点不为空
while(last->next)
{
last = last->next;
}
last->next = p;
}
else
{
//只有头指针,整个链表中没结点,则把头指针指向新生成的p结点
head = p;
}
}
return head;
}
第二种:如果我们只是传入指向结点的指针是无法改变函数外面的head的,所以我们要传入指向结点指针的指针
第二种不可行!
第三种传入指向结点指针的指针
/**
* 传入指向结点指针的指针来创建链表
* */
void createLinkList2(Node **Phead)
{
int length;
printf("请输入结点个数");
scanf("%d",&length);
for(int i=0;i<length;i++)
{
Node *p = (Node *)malloc(sizeof(Node));
printf("请输入结点存放的数据");
scanf("%d",&p->data);
p->next = NULL;
//找到最后一个结点
Node *last = *Phead;
if(last)
{
while(last->next)
{
last = last->next;
}
last->next = p;
}
else
{
*Phead = p;
}
}
}
第四种在工程中的拓展 自己在定义一种结构用来存放head, 这种方式的好处是我们可以在自己定义的结构中进行拓展。例如加上Node *tail;
/**
* 第四种:自定一种结构来存放head
* */
typedef struct _list{
Node *head;
}List;
void createLinkList3(List *Plist)
{
int length;
printf("请输入结点个数");
scanf("%d",&length);
for(int i=0;i<length;i++)
{
Node *p = (Node *)malloc(sizeof(Node));
printf("请输入结点存放的数据");
scanf("%d",&p->data);
p->next = NULL;
//找到最后一个结点
Node *last = Plist->head;//(修改为Plist->head)
if(last)
{
while(last->next)
{
last = last->next;
}
last->next = p;
}
else
{
//修改为Plist->head
Plist->head = p;
}
}
}
由于参数改变使用时要做一些改变
List myList;
myList.head = NULL;
createLinkList3(&myList);
//遍历链表
printf("链表中的数据\n");
for(Node *p = (&myList)->head;p;p= p->next)
{
printf("%d\n",p->data);
}