线性表(二):单链表的增删改查及源码
#include
#include
//结点结构体定义
typedef struct link_node {
int n;//数据域
struct link_node *next;//指针域:(此时结构体尚未定义完整,不能用 NODE *next; )用该结构体类型定义一个指针,用来指向下一个结点的地址
}NODE;
//创建结点 函数声明
/*
1、定义一个结构体类型指针需分配空间(大小为结构体大小)
2、下一结点初始化为空,数据域初始化
3、返回结点地址
*/
NODE *creat_node(int n) {
NODE *p = malloc(sizeof(NODE));
p->next = NULL;
p->n = n;
return p;
}
//头插法
/*
1、调用创建结点函数创建一个新结点
2、将头结点的地址赋值给新结点的next指针
3、返回新结点的地址,并将新结点的地址赋值给头结点
*/
void *add(NODE *head,int n) {
NODE *new = creat_node(n);//创建一个新结点
new->next = head;//将头结点的地址赋值给新节点的next指针
return new;//返回新结点的地址
}
//尾插法插入结点
/*
1、先创建一个新的结点(新节点->next指向NULL)
2、寻找最后一个结点
3、将新结点的地址赋值给最后一个结点->next;
*/
void append(NODE *head,int n) {
NODE *new = creat_node(n);//新建一个待插入结点
//找最后一个结点
NODE *end = head;
while (end->next != NULL)//需要保证end不为空
{
end = end->next;
}
//循环结束时end为最后一个结点
end->next = new;
}
//中间插入结点
void insert(NODE *head,int value,int n) {//在链表中的关键值为value的结点后插入一个新结点,新结点的值为n
NODE *p = creat_node(n);
NODE *pos = head;
int flag = 0;
while (pos!=NULL) {
if (pos->n == value)
{
p->next = pos->next;
pos->next = p;
flag = 1;
break;
}
else
{
pos = pos->next;
}
}
if (flag == 1)
{
printf("插入成功!插入值为%d\n",n);
}
else
{
printf("插入失败!关键值不存在\n");
}
}
//删除结点
//分为两种情况
/* 一:要删除的结点是head指针
1、
2、
*/
NODE *delete(NODE *head,int n) {
if (head->n==n) {
NODE *p = head;
head = p->next;
free(p);
return head;
}
else
{
NODE *prev = head;//表示前一结点
NODE *p = prev->next;//表示下一结点
//判断
while (p!= NULL)
{
if (p->n == n)
{
prev->next = p->next;
printf("删除成功!删除值为%d\n", p->n);
free(p);
break;
}
else
{
prev = prev->next;
p = prev->next;
}
}
}
}
//查询结点
NODE *query(NODE *head,int n) {
NODE *p = head;
while (p!=NULL)
{
if (p->n == n)
{
printf("已查询到!该关键值为%d,地址为%x\n",p->n,p);//将该值所在结点的16位地址打印出来
return p;
}
else
{
p = p->next;
}
}
printf("未查询到该关键值!\n");
return NULL;
}
//遍历链表
void show_all(NODE *head) {
NODE *p = head;
while (p != NULL)
{
printf("%d\n",p->n);
p = p->next;
}
}
//修改结点
/*两种方法:
一、查找关键值所在结点,再修改值
二、创建一个新结点,用新创建的结点替换要被替换的结点
*/
void modify(NODE *head,int old,int new) {
NODE *p = head;
while (p!=NULL)
{
if (p->n ==old) {
p->n = new;
printf("修改完成!\n");
return;
}
else
{
p = p->next;
}
}
printf("修改失败!未查找到要修改的值!\n");
}
//链表销毁
void destroy(NODE *head) {
NODE *p1;
NODE *p2;
p1 = head;
while (p1!=NULL)
{
p2 = p1->next;
free(p1);
p1 = p2;
}
}
int main(){
NODE *head = NULL;//head 为一个头指针 初始化赋值为空
head = creat_node(0);//创建一个结点,并将该结点地址赋值给头指针head
//头插法调用:
//head = add(head,1);//调用头插法函数add,将头指针地址和成员变量做实参传递,返回新节点地址并将新节点地址赋值给头结点
//尾插法调用:
append(head, 1);
append(head, 2);
append(head, 3);
append(head, 4);
//调用插入函数
insert(head, 2, 5);
insert(head, 6, 5);
//调用删除函数
head = delete(head, 0);
//调用查询函数
int n;
scanf("%d",&n);
NODE *p = query(head, n);
//调用遍历函数
show_all(head);
//调用修改函数
modify(head,2,6);
show_all(head);
//调用销毁函数
destroy(head);
return 0;
}