链表中第一个结点的存储位置叫做头指针,那么整个链表的存取就必须是从头指针开始进行了。之后的每一个结点,其实就是上一个的后继指针指向的位置。
这里有个地方要注意,就是对头指针概念的理解,这个很重要。“链表中第一个结点的存储位置叫做头指针”,如果链表有头结点,那么头指针就是指向头结点数据域的指针。画一个图吧。
头指针就是链表的名字。头指针仅仅是个指针而已。
//这里插入关于链表中有无头节点进行初始化链表知识 //首先明白头指针与头结点的关系:http://www.nowamagic.net/librarys/veda/detail/1805 //定义结点的结构体 //typedef struct LNode{ // int data; // struct LNode *next; //}LNode,*LinkList;//则定义LinkList L;时,L为链表的头指针。 // //L=(LinkList) malloc (sizeof(LNode)); //创建一个结点,此处返回给L的是一个指针,并且赋给了头指针。 //L->next=null; //这里说明我创建了一个头结点,即同时运用了头指针和头结点。 //这么方便只要加上->next就说明创建了头节点。不过你想想头指针是没有next的,只有头结点才有,所以就不难理解了 //带头结点初始化 //Node *head; //声明头结点 //首先第一眼看到(*head)->next=NULL;和我们刚才所说是不是一样,只要头指针一旦运用了next操作就自动创建了头结点 //但是我们今天的重点不在于这个,更多在于Node **head,对于两个指针的操作理解 //第一个指针*head,表明了head这个指针变量存储的是另外一个指向结构体NODE的指针,第二个指针,即*head作为一个整体 //其结果是一个指针,其指向的内容就是结构体NODE。经过这么一理解,对于头指针,头结点,首元节点的关系就非常明朗了 // void InitList(Node **head){ // *head=(Node *)malloc( sizeof(Node));//这里需要明确的第一点,申请内存返回的都是地址 // //第二点就是(Node *)表明了其返回的指针指向最后的结果是NODE的结构体,如果是指向int,那么我们就写(int *) // (*head)->next=NULL; //} //带头结点尾方便了首元节点和其他节点一样,统一了操作 //方式一: // void CreatList(Node **head){ // Node *r=*head,*s;//因为前面已经对头结点,头指针初始化过了,因此可以直接使用*head // int a; // while(scanf("%d",&a)){ // if(a!=0){ // s=(Node *)malloc(sizeof(Node)); // s->value=a; // r->next=s;//这里没有着急设置s->next,原因在于后续还要插入数据。因此将s赋值给r // r=s; // } // else{ // r->next=NULL;//如果后续输入的数据为空,则就将其设置为null // break; // } // } //} //调用CreatList(&head);//这句话表明了形参Node **head,只有第一个*才是起作用了,第个*号是和head联系在一起,作为整体使用的 //方式二: // void CreatList(Node *head){ // Node *r=head,*s; // ... //下面的都一样 //} //调用CreatList(head); // //不带头结点初始化 //方式一: //void InitList(Node **head){ // *head=NULL;//这里直接就是指向的首元节点,还有之前自己一个误解,看到head就觉得它就是头指针了,其实它就是随便一个指针变量 //并不是像自己之前想的那样的 //从这里才发现,真正有无头节点的区别。 //*head=(Node *)malloc( sizeof(Node));//这里需要明确的第一点,申请内存返回的都是地址 //第二点就是(Node *)表明了其返回的指针指向最后的结果是NODE的结构体,如果是指向int,那么我们就写(int *) //(*head)->next=NULL; //} //调用InitList(&head); // //方式二: //void InitList(Node *head){ // head=NULL; //} //调用InitList(head); //不带头结点尾插入,第一个节点与其他节点分开操作 //void CreatList(Node **head){ // Node *p,*t; /*p工作指针,t临时指针*/ // int a,i=1; // while(scanf("%d",&a)){ // if(a!=0){ // t=(Node *)malloc(sizeof(Node)); // t->value=a; // if(i==1){ // *head=t; // } // else{ // p->next=t; // } // p=t; // } // else{ // p->next=NULL; // break; // } // i++; // } //} //调用CreatList(&head); //其实从上面就可以知道,其实有头结点对于我们来说是一种更加明智更加方便的操作
原文:https://www.cnblogs.com/shujuxiong/p/10926844.html