头插法:
新建一个值为inputData的结点,插入链表的头部。
#include<stdio.h>
#include <stdlib.h>
typedef int ElemType;
//设计一个链表结构体数据类型 ,结点
struct node {
ElemType data;//数据域
struct node* next;//指针域
};
/*
new_node:新建一个结点,并且初始化
参数:
inputData 新建结点的数据
返回值:
成功返回新建结点的地址
失败返回NULL
*/
struct node* new_node(ElemType inputData)
{
//1、新建一个结点
struct node* newNode = malloc(sizeof(struct node));
if (newNode == NULL)
{
printf("新结点内存申请失败\n");
return NULL;
}
//2、初始化新建的结点
newNode->data = inputData;
newNode->next = NULL;
return newNode;
}
/*
create_list:创建一条只有首结点的单链表
返回值:返回链表首结点的地址
*/
struct node* create_list(ElemType inputData)
{
//1、先申请首结点的内存空间
struct node* head = new_node(inputData);//0x1234578
if (head == NULL)
{
printf("首结点申请失败\n");
return NULL;
}
//2、初始化首结点
head->data = inputData;
head->next = NULL;
//3、把首结点的地址返回(存储起来)
return head;
}
/*
print_allToList:将链表中所有结点的数据打印出来
参数:
head 链表的首结点
*/
void print_allToList(struct node* head)
{
//遍历链表的每一个结点,每个结点的数据都打印出来
struct node* p = head;
while (p)
{
printf("%d ", p->data);
p = p->next;//指向下一个结点
}
printf("\n");
}
/*
insert_nodeToList_head:新建一个值为inputData的结点,插入链表的头部
参数:
head 链表的首结点
inputData 新建结点的数据
返回值:
成功 返回 链表的首结点
失败 返回 NULL
*/
struct node* insert_nodeToList_head(struct node* head, ElemType inputData)
{
//1、新建一个结点并且初始化
struct node* newNode = new_node(inputData);
if (newNode == NULL)
{
printf("新结点创建失败\n");
return NULL;
}
//新结点的next指向原来链表的首结点
newNode->next = head;
//head存储新结点的地址,也就是说,此时新结点的链表的首结点
head = newNode;
return head;
}
int main()
{
struct node* head;//存储首结点的地址 链表a的首结点
//创建一条只有首结点的单链表
head = create_list(100);//首结点
head = insert_nodeToList_head(head,110);//head=更新头结点
head = insert_nodeToList_head(head,120);
head = insert_nodeToList_head(head,130);
head = insert_nodeToList_head(head,140);
head = insert_nodeToList_head(head,150);
print_allToList(head);
return 0;
}
运行结果:
尾插法:
insert_nodeToList_tail:
新建一个值为inputData的结点,插入链表的尾部
参数:
head 链表的首结点inputData 新建结点的数据
#include<stdio.h>
#include <stdlib.h>
typedef int ElemType;
//设计一个链表结构体数据类型 ,结点
struct node {
ElemType data;//数据域
struct node* next;//指针域
};
/*
new_node:新建一个结点,并且初始化
参数:
inputData 新建结点的数据
返回值:
成功返回新建结点的地址
失败返回NULL
*/
struct node* new_node(ElemType inputData)
{
//1、新建一个结点
struct node* newNode = malloc(sizeof(struct node));
if (newNode == NULL)
{
printf("新结点内存申请失败\n");
return NULL;
}
//2、初始化新建的结点
newNode->data = inputData;
newNode->next = NULL;
return newNode;
}
/*
create_list:创建一条只有首结点的单链表
返回值:返回链表首结点的地址
*/
struct node* create_list(ElemType inputData)
{
//1、先申请首结点的内存空间
struct node* head = new_node(inputData);//0x1234578
if (head == NULL)
{
printf("首结点申请失败\n");
return NULL;
}
//2、初始化首结点
head->data = inputData;
head->next = NULL;
//3、把首结点的地址返回(存储起来)
return head;
}
/*
print_allToList:将链表中所有结点的数据打印出来
参数:
head 链表的首结点
*/
void print_allToList(struct node* head)
{
//遍历链表的每一个结点,每个结点的数据都打印出来
struct node* p = head;
while (p)
{
printf("%d ", p->data);
p = p->next;//指向下一个结点
}
printf("\n");
}
/*
insert_nodeToList_tail:新建一个值为inputData的结点,插入链表的尾部
参数:
head 链表的首结点
inputData 新建结点的数据
*/
void insert_nodeToList_tail(struct node* head, ElemType inputData)
{
//1、新建一个结点
struct node* newNode = new_node(inputData);
if (newNode == NULL)
{
printf("insert_nodeToList_tail error\n");
return;
}
//2、初始化新建的结点 --不需要初始化,因为在new_node函数中已经初始化了
//newNode->data = inputData;
//newNode->next = NULL;
//3、遍历链表,找到链表的尾结点(尾部)
struct node* p = head;//p指向首结点
struct node* pre = NULL;//存储p的前一个结点
while (p) //p == NULL 才退出
{
pre = p;
p = p->next;
}
//此时pre就是尾结点的地址
//4、将新建好结点插到链表的尾结点的后面
pre->next = newNode;
}
int main()
{
struct node* head;//存储首结点的地址 链表a的首结点
//创建一条只有首结点的单链表
head = create_list(100);//首结点
insert_nodeToList_tail(head, 110);
insert_nodeToList_tail(head, 115);
insert_nodeToList_tail(head, 120);
insert_nodeToList_tail(head, 125);
print_allToList(head);
return 0;
}
运行结果:
中间插入法:
insert_nodeToList:
新建一个值为inputData的结点,插到链表中值为frontData的结点的前面
如果值为frontData的结点不存在,则插在链表的尾部
如果值为frontData的结点有多个,则插在第一个的前面
如果值为frontData的结点是首结点,则使用头插
#include<stdio.h>
#include <stdlib.h>
#include<stdio.h>
#include <stdlib.h>
typedef int ElemType;
//设计一个链表结构体数据类型 ,结点
struct node {
ElemType data;//数据域
struct node* next;//指针域
};
/*
new_node:新建一个结点,并且初始化
参数:
inputData 新建结点的数据
返回值:
成功返回新建结点的地址
失败返回NULL
*/
struct node* new_node(ElemType inputData)
{
//1、新建一个结点
struct node* newNode = malloc(sizeof(struct node));
if (newNode == NULL)
{
printf("新结点内存申请失败\n");
return NULL;
}
//2、初始化新建的结点
newNode->data = inputData;
newNode->next = NULL;
return newNode;
}
/*
create_list:创建一条只有首结点的单链表
返回值:返回链表首结点的地址
*/
struct node* create_list(ElemType inputData)
{
//1、先申请首结点的内存空间
struct node* head = new_node(inputData);//0x1234578
if (head == NULL)
{
printf("首结点申请失败\n");
return NULL;
}
//2、初始化首结点
head->data = inputData;
head->next = NULL;
//3、把首结点的地址返回(存储起来)
return head;
}
/*
print_allToList:将链表中所有结点的数据打印出来
参数:
head 链表的首结点
*/
void print_allToList(struct node* head)
{
//遍历链表的每一个结点,每个结点的数据都打印出来
struct node* p = head;
while (p)
{
printf("%d ", p->data);
p = p->next;//指向下一个结点
}
printf("\n");
}
/*
insert_nodeToList_head:新建一个值为inputData的结点,插入链表的头部
参数:
head 链表的首结点
inputData 新建结点的数据
返回值:
成功 返回 链表的首结点
失败 返回 NULL
*/
struct node* insert_nodeToList_head(struct node* head, ElemType inputData)
{
//1、新建一个结点并且初始化
struct node* newNode = new_node(inputData);
if (newNode == NULL)
{
printf("头插入失败\n");
return NULL;
}
//新结点的next指向原来链表的首结点
newNode->next = head;
//head存储新结点的地址,也就是说,此时新结点的链表的首结点
head = newNode;
return head;
}
/*
insert_nodeToList:新建一个值为inputData的结点,插到链表中值为frontData的结点的前面
如果值为frontData的结点不存在,则插在链表的尾部
如果值为frontData的结点有多个,则插在第一个的前面
如果值为frontData的结点是首结点,则使用头插
参数:
head 链表的首结点
inputData 新建结点的数据
frontData 新结点插在该结点的前面的数据
返回值:
成功 返回 链表的首结点
失败 返回 NULL
*/
struct node* insert_nodeToList(struct node* head, ElemType inputData, ElemType frontData)
{
//1、新建一个结点,并且初始化
struct node* newNode = new_node(inputData);
if (newNode == NULL)
{
printf("insert_nodeToList error\n");
return NULL;
}
//遍历链表,找到值为frontData的结点frontNode和它的前面一个结点pre
struct node* p = head;
struct node* pre = NULL;
while (p)
{
//找到了,此时 p 就是 值为frontData的结点frontNode
if (p->data == frontData)
break;
else {//如果没有找到,则p往链表的下一个结点进行遍历
pre = p;//记录p结点的上一个结点
p = p->next;
}
}
if (p != NULL)//找到的情况
{
if (p == head)//1、如果值为frontData的结点 是首节点 ,使用头插法,更新首结点
{
//新结点的next存储原链表的首结点地址,也就是新结点指向原来的首结点
newNode->next = head;//newNode->next = p;
head = newNode;//此时新结点就是链表的首结点
}
else {//2、值为frontData的结点在中间
newNode->next = p;
pre->next = newNode;
}
}
else {//没找到的情况(如果链表遍历完之后,没找到) p == NULL ,也就是说值为frontData的结点没有找到,新结点使用尾插
pre->next = newNode;
}
return head;
}
int main()
{
struct node* head;//存储首结点的地址 链表a的首结点
//创建一条只有首结点的单链表
head = create_list(100);//首结点
head = insert_nodeToList_head(head, 110);//head=更新头结点
head = insert_nodeToList_head(head, 120);
head = insert_nodeToList_head(head, 130);
head = insert_nodeToList_head(head, 140);
head = insert_nodeToList_head(head, 150);
head = insert_nodeToList(head,125,120);//在值为120的结点后面插入125
print_allToList(head);
return 0;
}
运行结果:
插入之前:
插入之后: