在研究链表节点插入的时候发现的问题。先看节点插入函数:
//插入节点,参数:插入那个链表,插入节点的数据是多少
struct Node* insertNodeByHead(struct Node* headNode, int data){
struct Node* newNode = createNode(data);
if(headNode==NULL){
headNode = (struct Node*)malloc(sizeof(struct Node));
headNode->data = 9;
headNode->next = NULL;
}
newNode->next = headNode->next; //此时两个节点共同指向下一个节点
headNode->next = newNode; //现在headNode节点指向newNode节点
return headNode;
}
我学习的教程是没有判断改链表是否为空的情况,我考虑到如果链表是空的话,那我先给链表分配内存。但是问题出现:
struct Node* createList(){
struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
//headNode成为了结构体变量
//变量使用前必须初始化
//headNode->data = 1;
headNode->next = NULL;
return headNode;
}
int main(){
struct Node* List; //创建一个链表变量 未初始化
struct Node* list = createList(); //创建一个链表,已分配内存 但后面并没有使用到这个链表
insertNodeByHead(List, 3); //使用这个语句插入失败
//List = insertNodeByHead(List, 3); //使用这个语句插入成功
printList(List); //打印链表
return 0;
}
下面是运行结果:
经过这两个实验的结果,我开始认为是函数结果返回的问题,链表在传入函数之前并没有给链表分配内存,所以在函数里面headNode分配的内存地址可能和在函数外面的List地址不一样,他们指向的位置不一样,所以没有List = insertNodeByHead(List, 3);这个语句给List重新赋值的时候,List的地址没有得到更新,后续的操作都是无效的。所以我做了下面的实验进行验证:
可以看出,地址更新后无需再次更新,后面的操作都是有效的。
但是后面问题又来了,正当我觉得问题就是出现在这个这个点上的时候。我将struct Node* list = createList(); 这个语句删除后:
int main(){
struct Node* List; //创建一个链表变量 未初始化
//struct Node* list = createList();
//insertNodeByHead(List, 3);
List = insertNodeByHead(List, 4);
insertNodeByHead(List, 3);
insertNodeByHead(List, 5);
insertNodeByHead(List, 6);
printList(List);
return 0;
}
运行结果又出现问题了:
除了上面的一些实验数据,我还做了其他的实验,查看链表各运行阶段的地址变化,但都没有发现什么问题,应该指针的问题吧,我对指针也不熟悉,有没有懂的帮忙分析分析。
下面是全部的实验代码:
#include <stdio.h>
#include <stdlib.h>
struct Node{
int data;
struct Node* next;
};
struct Node* createList(){
struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
//headNode成为了结构体变量
//变量使用前必须初始化
//headNode->data = 1;
headNode->next = NULL;
return headNode;
}
//创建节点
struct Node* createNode(int data){
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
void printList(struct Node* headNode){
struct Node* pMove = headNode;
while(pMove){
printf("%d\t", pMove->data);
pMove = pMove->next;
printf("`");
}
printf("\n");
}
//插入节点,参数:插入那个链表,插入节点的数据是多少
struct Node* insertNodeByHead(struct Node* headNode, int data){
struct Node* newNode = createNode(data);
if(headNode==NULL){
headNode = (struct Node*)malloc(sizeof(struct Node));
headNode->data = 9;
headNode->next = NULL;
}
newNode->next = headNode->next; //此时两个节点共同指向下一个节点
headNode->next = newNode; //现在headNode节点指向newNode节点
return headNode;
}
//删除指点节点
int deleteNodeByAppoint(struct Node* headNode, int posData){
struct Node* posNode = headNode->next;
struct Node* posNodeFront = headNode;
if(posNode==NULL){
printf("删除失败,无法删除空链表!\n");
return 0;
}
else{
while(posNode!=NULL){
if(posNode->data == posData){
posNodeFront->next = posNode->next;
free(posNode);
return 1;
}
posNodeFront = posNode;
posNode = posNodeFront->next;
}
printf("没有找到相关数据,无法删除!\n");
}
}
int main(){
struct Node* List; //创建一个链表变量 未初始化
//struct Node* list = createList();
//insertNodeByHead(List, 3);
List = insertNodeByHead(List, 4);
insertNodeByHead(List, 3);
insertNodeByHead(List, 5);
insertNodeByHead(List, 6);
printList(List);
return 0;
}