#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef int dataType;
// 节点
struct node
{
dataType data;// 指针域
struct node *next; // 指向下一个节点
};
// 创建新节点
struct node *create_newNode(dataType data)
{
struct node *pnew = malloc(sizeof(struct node));
if(pnew == NULL)
return NULL;
pnew->data = data;
pnew->next = NULL;
return pnew;
}
// 创建链表
struct node *create_list(void)
{
// 设置空链表
struct node *head = NULL;
struct node *tail = NULL;
while(1)
{
dataType data;
scanf("%d",&data);
if(data== 0)
break;
// 创建新节点
struct node *pnew = create_newNode(data);
if(pnew == NULL)
{
printf("create new node failed:\n");
//exit(0); // 不管再哪里调用,整个程序结束
return NULL; // 只退出本函数
}
// 从无到有
if(head == NULL)
{
head = pnew;
tail = pnew;
}
else// 从少到多
{
//尾插法
// tail->next = pnew;
// tail = pnew;
//头插法
pnew->next=head;
head=pnew;
}
}
return head;
}
//修改
bool amendnode(struct node *head,dataType a,dataType b)
{
for (struct node *p = head;p !=NULL;p = p->next)
{
int count =0;
if (p->data == a)
{
p->data = b;
count++;
}
if (count ==0)
{
printf("没有要修改的");
break;
}
}
return true;
}
//删除
void delete(struct node **head,dataType b)
{
if (*head == NULL)
return;
struct node *cur = *head;
struct node *prev = NULL;
// 判断头节点是否为待删除节点
while (cur != NULL && cur->data == b)
{
*head = cur->next;
free(cur);
cur = *head;
}
// 遍历链表删除其他节点
while (cur != NULL)
{
// 如果当前节点是待删除节点
while (cur != NULL && cur->data != b)
{
prev = cur;
cur = cur->next;
}
// 删除节点
if (cur != NULL)
{
prev->next = cur->next;
free(cur);
cur = prev->next;
}
}
}
//添加
struct node *create_newNodeAtPosition(struct node **head,dataType data, int position)
{
struct node *pnew = malloc(sizeof(struct node));
if (pnew == NULL)
return NULL;
pnew->data = data;
pnew->next = NULL;
if (position == 0)
{
pnew->next = *head;
*head = pnew;
}
else
{
struct node *cur = *head;
for (int i = 0; i < position - 1 && cur != NULL; i++)
{
cur = cur->next;
}
if (cur != NULL)
{
pnew->next = cur->next;
cur->next = pnew;
}
else
{
free(pnew);
pnew = NULL;
}
}
}
// 显示链表
void show_list(struct node *head)
{
if(head == NULL)
return;
for(struct node *p = head; p != NULL; p = p->next)
{
printf("%d\t",p->data);
}
printf("\n");
}
int main(int argc, char const *argv[])
{
int a,b,position;
// 创建链表
struct node *head = create_list();
if(head == NULL)
return -1;
// 显示链表
show_list(head);
printf("输入要修改的数据:");
scanf("%d",&a);
printf("修改为:");
scanf("%d",&b);
amendnode(head,a,b);
show_list(head);
printf("输入要删除的数据:");
scanf("%d",&b);
delete(&head,b);
show_list(head);
printf("输入要添加的数据:");
scanf("%d",&b);
printf("输入要添加的位置:");
scanf("%d",& position);
create_newNodeAtPosition(&head,b, position);
show_list(head);
return 0;
}
总结:代码初期的添加模块,在添加数8到第0个的时候,运行显示的结果并没有添加的数8,只有3 2 1,调整链表的头指针 head
的值并不会对传递进函数的参数产生影响。这意味着,在 create_newNodeAtPosition
函数中修改了 head
的值,但并不会在调用该函数后反映到实际的链表中。
为了解决这个问题,我在函数内部使用二级指针传递头节点 head
的地址,这样就能正确修改链表的头节点了。
添加模块,在添加数8到第0个的时候,运行显示的结果并没有添加的数8,只有3 2 1,调整链表的头指针 head
的值并不会对传递进函数的参数产生影响。这意味着,在 create_newNodeAtPosition
函数中修改了 head
的值,但并不会在调用该函数后反映到实际的链表中。
为了解决这个问题,我在函数内部使用二级指针传递头节点 head
的地址,这样就能正确修改链表的头节点了。