目录
一、顺序插入
1、步骤:
(1)比较大小找到插入的位置;
(2)将插入点上一节点的指针指向新节点;
(3)将新节点的指针指向插入点的后一节点。
2、图示:
new为新节点地址;
last为上一节点地址;
temp为后一节点地址;
3、具体实现
指针temp依次指向链表中的每个节点,并将节点的值与输入的值比较,如果不满足,temp则指向下一个。last保存上一次temp的值(即上一节点地址)。如图,当temp指向4这个节点时满足,则新节点位置为last和temp之间。然后将last节点的指针指向new,将new节点的指针指向temp。即:
last->next = new; //插入位置的前一节点的指针指向新节点
new->next = temp; //新节点的指针指向后一节点
4、示例
#include <stdio.h>
#include <stdlib.h>
/*顺序插入法*/
/*声明结构体*/
struct NUM
{
int num;
struct NUM *next;
};
/*添加节点*/
void AddStruct(struct NUM **head,int ipnum)
{
struct NUM *new; //保存新节点地址
struct NUM *temp; //当前地址
struct NUM *last; //上一节点地址
last = NULL;
new = (struct NUM *)malloc(sizeof(struct NUM));//创建节点
if(new == NULL)
{
printf("内存分配失败\n");
exit(1);
}
//printf("内存分配成功\n");
new->num = ipnum; //保存数据到新节点
if(*head != NULL)//不是空链表
{
temp = *head; //传入的是指针的地址即指针的指针,取值即可得到指针
//printf("不是空链表\n");
while(temp != NULL && ipnum > temp->num) //指针没有指到链表结尾且插入值大于当前节点值
{
last = temp; //保存插入位置前一节点地址,该节点的指针指向新节点
temp = temp->next; //指针往后走
}
if(ipnum <= (*head)->num) //如果输入的数值小于或等于第一个节点的值
{
new->next = *head; //新节点的指针指向插入前的第一个节点
*head = new; //头指针指向新节点 (相当于头插法)
}
else
{
last->next = new; //插入位置的前一节点的指针指向新节点
new->next = temp; //新节点的指针指向后一节点
}
}
else //是空链表
{
printf("是空链表\n");
*head = new;
new->next = NULL;
}
}
/*打印链表数据*/
void PrintfStruct(struct NUM *head)
{
struct NUM *numh;
numh = head;
printf("输入的数据为:\n");
while(numh != NULL)
{
printf("%d ",numh->num);
numh = numh->next; //指向下一个节点
}
printf("\n");
}
int main()
{
struct NUM *head = NULL;
int inpnum;
while(1)
{
printf("请输入数值(-1结束):");
scanf("%d",&inpnum);
if(inpnum == (-1)) break;
AddStruct(&head,inpnum);
}
PrintfStruct(head);
return 0;
}
二、节点删除
1、步骤:
(1)比较值找到要删除的节点;
(2)将删除点上一节点的指针指向后一节点;
(3)释放该节点空间。
2、图示:
last为上一节点地址;
temp为要删除节点的地址;
3、具体实现
指针temp依次指向链表中的每个节点,并将节点的值与输入的值比较,如果不满足,则指向下一个。last保存上一次temp的值(即上一节点地址)。找到删除点后,将last节点的指针指向删除点temp的后一节点(temp->next);再释放temp节点。即
lats->next = temp->next;
free(temp);
4、示例
#include <stdio.h>
#include <stdlib.h>
/*单链表删除*/
/*声明结构体*/
struct NUM
{
int num;
struct NUM *next;
};
/*添加节点*/
void AddStruct(struct NUM **head,int ipnum)
{
struct NUM *new; //保存新节点地址
struct NUM *temp; //当前地址
struct NUM *last; //上一节点地址
last = NULL;
new = (struct NUM *)malloc(sizeof(struct NUM));//创建节点
if(new == NULL)
{
printf("内存分配失败\n");
exit(1);
}
//printf("内存分配成功\n");
new->num = ipnum; //保存数据到新节点
if(*head != NULL)//不是空链表
{
temp = *head; //传入的是指针的地址即指针的指针,取值即可得到指针
//printf("不是空链表\n");
while(temp != NULL && ipnum > temp->num) //指针没有指到链表结尾且插入值大于当前节点值
{
last = temp; //保存插入位置前一节点地址,该节点的指针指向新节点
temp = temp->next; //指针往后走
}
if(ipnum <= (*head)->num) //如果输入的数值小于或等于第一个节点的值
{
new->next = *head; //新节点的指针指向插入前的第一个节点
*head = new; //头指针指向新节点 (相当于头插法)
}
else
{
last->next = new; //插入位置的前一节点的指针指向新节点
new->next = temp; //新节点的指针指向后一节点
}
}
else //是空链表
{
printf("是空链表\n");
*head = new;
new->next = NULL;
}
}
/*删除节点*/
void DeleteStruct(struct NUM **head,int ipnum)
{
struct NUM *temp;
struct NUM *last;
temp = *head;
last = NULL;
while(temp != NULL && ipnum != temp->num) //指针没有指到链表结尾且插入值不等于当前节点值
{
last = temp; //保存插入位置前一节点地址,该节点的指针指向新节点
temp = temp->next; //指针往后走
}
if(temp == NULL)
{
printf("找不到该节点!\n");
}
else
{
if(last == NULL) //该值在第一个节点(上面的while不执行)
{
*head = temp->next; //头指针指向后一节点
}
else
{
last->next = temp->next; //上一节点的指针指向后一节点
}
free(temp); //释放空间
printf("已删除该节点!\n");
}
}
/*打印链表数据*/
void PrintfStruct(struct NUM *head)
{
struct NUM *numh;
numh = head;
printf("链表中数据为:\n");
while(numh != NULL)
{
printf("%d ",numh->num);
numh = numh->next; //指向下一个节点
}
printf("\n");
}
int main()
{
struct NUM *head = NULL;
int inpnum;
while(1)
{
printf("请输入数值(-1结束):");
scanf("%d",&inpnum);
if(inpnum == (-1)) break;
AddStruct(&head,inpnum);
PrintfStruct(head);
}
printf("开始删除节点:\n");
while(1)
{
printf("请输入数值(-1结束):");
scanf("%d",&inpnum);
if(inpnum == (-1)) break;
DeleteStruct(&head,inpnum);
PrintfStruct(head);
}
return 0;
}