持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
含头结点的单链表
单链表是由表头指针唯一确定的,因此单链表可以用头指针的名字来命名。若头指针名为L,则简称该链表为表L,所以单链表只能从头开始遍历。含有头节点的链表,首元节点的地址保存在头节点(即其“前驱节点”)的指针域中,则对链表的第一个数据元素的操作与其他数据元素相同,无需进行特殊处理。在无头结点的单链表中,因为其首元节点我没有前驱节点,所以在对其进行操作时要进行特殊处理。
1、定义单链表的结构体
typedef int DataType;//相当于为int起了个别名Datatype
//单链表节点的数据域可以是复杂的结构类型,这里举例简单的整形数据。
typedef struct node
{
DataType num;//每个元素的数据信息,这里只是简单的int类型
struct node *next;//存放下一个结点的地址
}node,*list;
2、使用无参函数创建一个单链表并初始化
list Creat_H()
{
list l;
list p;
l = (struct node *)malloc(sizeof(struct node));//为指针动态分配内存空间
l->next = NULL;
list r;
r = l;
int s = 0;
scanf_s("%d", &s);
while (s != 0) { //为单链表赋值,以0结束
p = (struct node *)malloc(sizeof(struct node));
p->num = s;
p->next = NULL; r->next = p; r = p;
scanf_s("%d", &s);
}
return l;
}
3、删除第k个元素
void Delete_node(list h, int k)
{
list p = h, q;
int j = 0;
while (j < k-1&&p->next)
{
p = p->next;
++j;
}
if(!(p->next)||(j>k-1)){
printf("删除位置不合理!\n");
}
else
{
q = p->next;
p->next = q->next;
free(q);
printf("删除成功!\n");
}
}
4、打印单链表(只能从头节点开始打印)
void Print(list l)
{
list head = l->next;
while (head != NULL)
{
printf("%d ", head->num);
head = head->next;
}printf("\n");
}
5、按数据删除元素
思路:遍历链表找到该数据所在位置->调用按位置删除函数进行删除
void Delete_node2(list h,Node k)
{
list p = h, q,s;
int j = 0;
while (p->num!= k.num && p->next)
{
p = p->next;
++j;
}
//得到要删除数据的位置
if (!(p->next)) {
printf("该元素不存在!删除失败!\n");
}
else
{
Delete_node(h, j);//按位置进行删除
}
}
6、元素插入
注意:链表有n个元素,则会有n+1个插入位置!!!
//插入节点
int insert(list L,int i,DataType e)
{
list p=L,s;
int j = 0;
while (p&&(j<i-1))
{
p = p->next; ++j;
}
if (!p || j > i - 1)
{
return 0;
}
s = (Node*)malloc(sizeof(list));
s->num = e;
s->next = p->next;
p->next = s;
printf("插入成功!\n");
return 1;
}
7、主函数及测试结果
int main()
{
list l;
printf("单链表初始化赋值,输入0结束:\n");
l=Creat_H();
Print(l);
//节点删除
printf("请输入要删除节点的位置:\n");
int t;
scanf_s("%d", &t);
Delete_node(l, t);
Print(l);
//插入节点
printf("请输入要插入节点的位置 :\n");
int s;
scanf_s("%d", &s);
DataType e = 111;//要插入的节点
insert(l, s, e);
Print(l);
//按值删除
Node k;
k.num = 100;
Delete_node2(l,k);
Print(l);
}
单链表初始化赋值,输入0结束:
1 2 3 4 5 6 7 8 9 0
1 2 3 4 5 6 7 8 9
请输入要删除节点的位置:
1
按位置删除成功!
2 3 4 5 6 7 8 9
请输入要插入节点的位置 :
1
插入成功!
111 2 3 4 5 6 7 8 9
该元素不存在!删除失败!
111 2 3 4 5 6 7 8 9
8、完整代码
#include "stdio.h"
#include "stdlib.h"
typedef int DataType;
typedef struct node
{
DataType num;
struct node *next;
}Node,*list;
list Creat_H()
{
list l;
list p;
l = (struct node *)malloc(sizeof(struct node));
l->next = NULL;
list r;
r = l;
int s = 0;
scanf_s("%d", &s);
while (s != 0) {
p = (struct node *)malloc(sizeof(struct node));
p->num = s;
p->next = NULL; r->next = p; r = p;
scanf_s("%d", &s);
}
return l;
}
//插入节点
int insert(list L,int i,DataType e)
{
list p=L,s;
int j = 0;
while (p&&(j<i-1))
{
p = p->next; ++j;
}
if (!p || j > i - 1)
{
return 0;
}
s = (Node*)malloc(sizeof(list));
s->num = e;
s->next = p->next;
p->next = s;
printf("插入成功!\n");
return 1;
}
//删除节点(按位置删除)
void Delete_node(list h, int k)
{
list p = h, q;
int j = 0;
while (j < k-1&&p->next)
{
p = p->next;
++j;
}
if(!(p->next)||(j>k-1)){
printf("删除位置不合理!\n");
}
else
{
q = p->next;
p->next = q->next;
free(q);
printf("按位置删除成功!\n");
}
}
//按数据删除
void Delete_node2(list h,Node k)
{
list p = h, q,s;
int j = 0;
while (p->num!= k.num && p->next)
{
p = p->next;
++j;
}
if (!(p->next)) {
printf("该元素不存在!删除失败!\n");
}
else
{
Delete_node(h, j);
}
}
void Print(list l)
{
list head = l->next;
while (head != NULL)
{
printf("%d ", head->num);
head = head->next;
}printf("\n");
}
int main()
{
list l;
printf("单链表初始化赋值,输入0结束:\n");
l=Creat_H();
Print(l);
//节点删除
printf("请输入要删除节点的位置:\n");
int t;
scanf_s("%d", &t);
Delete_node(l, t);
Print(l);
//插入节点
printf("请输入要插入节点的位置 :\n");
int s;
scanf_s("%d", &s);
DataType e = 111;//要插入的节点
insert(l, s, e);
Print(l);
//按值删除
Node k;
k.num = 100;
Delete_node2(l,k);
Print(l);
}