链表:
链表是一种基础数据结构,采用动态分配储存单元的方式进行储存分配。结构体指针在这上面得到了充分的运用。换句话说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。
创建链表:
首先,要先构造一个结构体,构造结构体一般都用typedef函数,这样方便结构体变量的命名。
typedef struct _node{
int value;
struct _node *next;
}Node;
然后再构造节点,再构造节点之前我们先来了解下:
p = head->next与head->next=p的区别:
p= head->next的意思是原本head指针指向next,将这个赋值给p,也就相当于显示这个指针,即p也指向next。
head->next=p的意思是改变next的指向,next指向p这个新的节点。
构造节点如下:
Node *p = (Node*)malloc(sizeof(Node));
p->value = number;
p->next = NULL;//注意最后p指针是指向next,方便后面的连接
下一步就是构建这个链表的最后一个指针:
Node *last = head;//先让last指向head,因为链表可能就一个节点
while(last->head){
last = last->next;
}
最后就是将他们串联起来就行了。
整个内容如下:
typedef struct _node{
int value;
struct _node *next;
}Node;
int main(int argc, char const *argv[])
{
Node *head = NULL;
int number;
do{
scanf("%d",&number);
if(number !=-1){
Node *p = (Node*)malloc(sizeof(Node));
p->next = number;
p->next = NULL;
Node *last = head;
if(last){
while(last ->next){
last = last->next;
}
last->next = p;
}esle{
head = p;
}
}
}while(number !=-1);
}
让我们对上述进行一下优化,我们先用一个函数块,来将加入节点这个操作放入函数块中:
Node* add(Node* head,int number)
{
Node *p = (Node*)malloc(sizeof(Node));
p->next = number;
p->next = NULL;
Node *last = head;
if(last){
while(last ->next){
last = last->next;
}
last->next = p;
}else{
head = p;
}
return head;
}
注意这时候用的是一个二级指针,因为函数中改变指针的指向,主函数中的指针是不会发生任何变化的,但是如果是改变指针所指的内容,这个时候主函数中的指针的内容是会变的,我们可以理解为函数重新复制了一个和主函数一样的指针。
整个也就是这样的:
#include <stdio.h>
#include <stdlib.h>
typedef struct _node{
int value;
struct _node *next;
}Node;
Node* add(Node *head,int number);
int main(int argc, char *argv[])
{
Node *head=NULL;
int number;
do{
scanf("%d",&number);
if(number!=-1){
head=add(head,number);
}
}while(number!=-1);
printf("%d",head->value);
return 0;
}
Node* add(Node *head,int number)
{
Node *p=(Node*)malloc(sizeof(Node));
p->value=number;
p->next=NULL;
Node *last=head;
if(last){
while(last->next){
last=last->next;
}
last->next=p;
}else{
head=p;
}
}
然后我们可以再次改进,新建一个结构体_list来表示整个链表,还可以方便以后调整。
#include <stdio.h>
#include <stdlib.h>
typedef struct _node{
int value;
struct _node *next;
}Node;
typedef struct _list{
Node* head;
}List;
void * add(List *list,int number);
int main(int argc, char *argv[])
{
List list;
list.head=NULL;
int number;
do{
scanf("%d",&number);
if(number!=-1){
add(&list,number);
}
}while(number!=-1);
printf("%d",list.head->value);
return 0;
}
void * add(List *list,int number)
{
Node *p=(Node*)malloc(sizeof(Node));
p->value=number;
p->next=NULL;
Node *last=list->head;
if(last){
while(last->next){
last=last->next;
}
last->next=p;
}else{
list->head=p;
}
}
对于上述还是有需要改善的地方,last这个指针总是从head循环到最后指向最后一个,每新加一个节点,就要重新循环一次,很麻烦。所以需要增加一个tail指针
#include <stdio.h>
#include <stdlib.h>
#include "node.h"
typedef struct _list{
Node* head;
Node* tail;
}List;
void * add(List *list,int number);
int main(int argc, char *argv[])
{
List list;
list.head=NULL;
list.tail=NULL;
int number;
do{
scanf("%d",&number);
if(number!=-1){
add(&list,number);
// head=add(head,number);
}
}while(number!=-1);
printf("%d",list.tail->value);
return 0;
}
void * add(List *plist,int number)
{
Node *p=(Node*)malloc(sizeof(Node));
p->value=number;
p->next=NULL;
Node *last=list->head;
if(last){
last = plist ->tail;
last->next=p;
plist->tail=p;
}else{
plist->head=p;
plist->tail=p;
}
}
(以上内容是上翁恺老师的mooc课程上总结借鉴的)