【数据结构之链表的实现与应用】

111 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

含头结点的单链表

单链表是由表头指针唯一确定的,因此单链表可以用头指针的名字来命名。若头指针名为L,则简称该链表为表L,所以单链表只能从头开始遍历。含有头节点的链表,首元节点的地址保存在头节点(即其“前驱节点”)的指针域中,则对链表的第一个数据元素的操作与其他数据元素相同,无需进行特殊处理。在无头结点的单链表中,因为其首元节点我没有前驱节点,所以在对其进行操作时要进行特殊处理。 image.png

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);
}