单链表的创建、添加、删除

:在实验时,受编译器种类限制,某些代码须稍加修正

一、创建

头插法

①什么是头插法?
在这里插入图片
②代码实现:

#include<stdio.h>
#include<stdlib.h>

typedef struct node
{
	int data;
	struct node * next;
}Node;

//create函数如下:
Node*create(int n)
{
    int i;
    Node*head= (Node*)malloc(sizeof(Node));   //创建头节点
    head->next=NULL;
    for(i=0;i<n;i++)
    {
        Node*p=(Node*)malloc(sizeof(Node));
        scanf("%d",&(p->data));
        p->next=head->next;
        head->next=p;
    }
    return head;
}
//visit函数如下
void visit(Node*head)
{
    head=head->next;
    while(head!=NULL)
    {
        printf("%d\n",head->data);
        head=head->next;
    }
}
int main(void)
{
	int num;
	scanf("%d",&num);	//输入想要创建节点的个数
	Node*head=create(num);
    visit(head);
	return 0;
}

输出结果:
在这里插入图片描述
很明显头插法是逆序输出的

尾插法

①什么是尾插法?
在这里插入图片描述
②代码实现:

//create函数如下:
Node * create(int n)
{
    int i;
    Node * head= (Node*)malloc(sizeof(Node));   //创建头节点
    head->next=NULL;
    Node*fakehead=head;	//创建虚拟头节点代替真实的头节点
    for(i=0;i<n;i++)
    {
        Node*p=(Node*)malloc(sizeof(Node));
        scanf("%d",&(p->data));
        p->next=NULL;
        fakehead->next=p;
        fakehead=p;
    }
    return head;
}

输出结果:
在这里插入图片描述
很明显尾插法是正序输出的

两者的差别在哪呢?
除了输出逆序正序外,两者执行过程中用来表示头节点的head变量的变化也是不同的。
头插法中,head变量存储的值(头节点的地址)是固定的。p变量存储的值一直变动。

head
data1
head
data2
data1
head
data3
data2
data1

尾插法中,head变量和p变量是一直变化的,(由于函数返回值是头节点的指针,head变化后则无法返回正确值,所以用fakehead代替head)这种情况就好像移动。

head/fakehead
data1
head
fakehead
data2
head
data1
fakehead
data3
head
data1
data2
fakehead
data4

二、添加

①如何添加?
在这里插入图片描述
找到值为x节点的地址,在其前面或后面插入新的节点。

②前插代码实现

Node * add(Node*head)
{
	int n;
    printf("你想在哪个数字前面添加:");
    scanf("%d",&n);
    Node*newnode=(Node*)malloc(sizeof(Node));	//创建要插入的节点
    printf("输入你想添加的数字:");
    scanf("%d",&newnode->data);
    Node*fakehead=head;
    Node*pre;
    while(fakehead!=NULL&&fakehead->data!=n)
    {
        pre=fakehead;
        fakehead=fakehead->next;
    }
    pre->next=newnode;
    newnode->next=fakehead;
    return head;
}

输出结果:
在这里插入图片描述

③代码解释,以前插为例:

head/fakehead/pre
data1
data2
datax
data4
head/pre
fakehead
data2
datax
data4
head
pre
fakehead
datax
data4
head
data1
pre
fakehead
adta4

fakehead->data已经等于所要寻找的x,此时将要插入的节点在pre和fakedata之间插入。

如果想要后插入只需稍稍变动:

//add函数如下
Node * add(Node*head)
{
    int n;
    printf("你想在哪个数字后面添加:");
    scanf("%d",&n);
    Node*newnode=(Node*)malloc(sizeof(Node));
    printf("输入你想添加的数字:");
    scanf("%d",&newnode->data);
    Node*fakehead=head;
    Node*pre;
    while(fakehead!=NULL&&fakehead->data!=n)
    {
        pre=fakehead;
        fakehead=fakehead->next;
    }
    newnode->next=fakehead->next;					//改动部分
    fakehead->next=newnode;							//改动部分
    return head;
}

同样还是fakehead的位置是x的位置,在fakehead的后面插入一个新的节点。newnode>next=fakehead->next;
fakehead->next=newnode;
这两行代码和创建链表中的头插法是一样的。

输出结果
在这里插入图片描述

三、删除

①怎样删除链表里的节点?

del
head
data1
data2
data3
data4

我们找到所要删除的节点x,然后将x前一个节点的next赋值为x后一个节点的地址。

②代码实现:

Node * del(Node*head)
{
    int n;
    printf("你想删除的数字是:");
    scanf("%d",&n);
    Node*fakehead=head;
    Node*pre;
    while(fakehead!=NULL&&fakehead->data!=n)
    {
        pre=fakehead;
        fakehead=fakehead->next;
    }
    pre->next=fakehead->next;
    return head;
}

输出结果:
在这里插入图片描述

③代码解释
这里和前面add函数(链表的添加)差不多,依然是采用了fakehead和pre。一前一后,当fakehead是寻找的x时,pre的next直接赋值为fakehead下一个节点的地址。

del
head
data1
pre
fakehead/x
data4

一个小细节是x的next还保存的还是data4的地址。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值