链表的基本操作#周报

链表的基本操作

  • 在说链表之前,我们先说说顺序存储。其中我们最熟悉的一种顺序存储的数据结构就是数组,当我们想要给数组中插入一个元素时,为保证顺序以及其他元素不丢失,我们需要在插入元素后,将后面的元素整体后移。所以容易看出这样有着这两个弊端:第一:我们所需要移动的元素有很多时,会浪费算力。第二:我们必须为数组开足够多的空间,否则会存在溢出风险。
    为了避免这两个弊端,我们引入链式存储——链表。
    什么是链表?
    简单来说,链表的利用结构体,额外开辟出一份内存空间去作指针,它总是指向下一个结点,一个个结点通过指针相互串联,这就形成了我们的链表。

在这里插入图片描述
其中DATA数据元素(数据域),可以是int类型或char类型,甚至可以是结构体。NEXT为一个指针通常是用来指向下一个结点,链表的尾部NEXT指向NULL,因为它没有可以指向的空间了。
在这里插入图片描述
对于一个单链表的结点定义:

//定义结点类型 
typedef struct Node
{
	int DATA;//数据域 
	struct Node* NEXT;//指针域 
}Node,* pointnode;//Node表示结点的类型,pointnode表示指向Node结点类型的指针类型

1.对链表进行初始化:

pointnode Initialize()
{
	Node* H=(Node*)malloc(sizeof(Node));  //开辟空间
	if(H==NULL)	//判断是否开辟成功 
	{
		printf("开辟失败!");//开辟失败的提示 
		exit(0); 			//	开辟失败结束程序(根据情况看是否添加) 
	 } 
	 H->NEXT=NULL;			//指针指向NULL 
 } 

2.创建单链表:
<1>头插法
从一个空表开始,生成新结点,并将数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头即头结点之后。

pointnode listofhead()
{
	Node* H = (Node*)malloc(sizeof(Node));//开辟一个头空间
	H -> NEXT= NULL;						//初始化为空

	int x;
	while (scanf("%d", &x) != EOF)		//输入数据,当输入空的时候停止(在Windows下:Ctrl+Z)
	{
		Node* p = (Node*)malloc(sizeof(Node));
		p->DATA = x;				//赋值给数据域
		p->NEXT = H->NEXT;			//将节点插到表头
		H->NEXT = p;
	}
	return H;
}

<2>尾插法
将新结点逐个插入到当前链表的表尾上,增加一个尾指针, 使其始终指向当前链表的尾结点。

pointnode listofend()
{
	Node* H = (Node*)malloc(sizeof(Node));	//开辟头空间
	H->NEXT = NULL;			//初始化

	int x;
	Node* l;		//定义为尾指针
	l = H;          // 尾指针开始指向头,始终指向尾。
	while (scanf("%d", &x) != EOF)
	{
		Node* p = (Node*)malloc(sizeof(Node));
		p->DATA = x;
		l->NEXT = p;	//将结点插到表头
		l = p;

	}
	l->NEXT = NULL;
	return H;
}

注意:头插法的顺序是逆序的:表头->[n]->···->[2]->[1]->NULL
尾插法是正序的:表头->[1]->[2]->····[n]->NULL
3.链表的遍历

void listoftravel(pointnode H)
{
	Node* p = H->NEXT;

	int i = 1;
	while (p)
	{
		printf("第%d个数据是%d\n", i++, p->DATA);
		p = p->NEXT;
	}

}

4.链表的插入
在这里插入图片描述
在这里插入图片描述

//链表的插入
pointnode datainlist(pointnode H,int i,int x)
{
	Node* preve = H;
	int seek;
	for (seek = 1; seek < i; seek++)//寻找元素位置
	{
		preve = preve->NEXT;
	}
	Node* p = (Node*)malloc(sizeof(Node));
	p->DATA = x;
	p->NEXT = preve->NEXT;
	preve->NEXT = p;
	return H;
}

4.链表的修改

//链表的修改
pointnode moddata(pointnode H,int x,int t)
{
	Node* p = H->NEXT;

	while (p)
	{
		if (p->DATA == x)
		{
			p->DATA = t;
		}
		p = p->NEXT;
	}
	return H;
}

5.链表的删除

//链表的删除
pointnode  freedata(pointnode H,int x)
{
	Node* p;
	Node* preve;//前驱结点
	p = H->NEXT;

	while (p->DATA != x)//查找元素
	{
		preve = p;
		p = p ->NEXT;
	}
	preve->NEXT = p->NEXT;
	free(p);	//删除操作
	return H;

}

完整代码:

#include<stdio.h>
#include<stdlib.h>
//定义结点类型 
typedef struct Node
{
	int DATA;//数据域 
	struct Node* NEXT;//指针域 
}Node, * pointnode;
//Node表示结点的类型,pointnode表示指向Node结点类型的指针类型

//链表的初始化 
pointnode Initialize()
{
	Node* H = (Node*)malloc(sizeof(Node));  //开辟空间
	if (H == NULL)	//判断是否开辟成功 
	{
		printf("开辟失败!");//开辟失败的提示 
		exit(0); 			//	开辟失败结束程序(根据情况看是否添加) 
	}
	H->NEXT = NULL;			//指针指向NULL 
}
//头插法建立链表
pointnode listofhead()
{
	Node* H = (Node*)malloc(sizeof(Node));//开辟一个头空间
	H = NULL;						//初始化为空

	int x;
	while (scanf("%d", &x) != EOF)		//输入数据,当输入空的时候停止(在Windows下:Ctrl+Z)
	{
		Node* p = (Node*)malloc(sizeof(Node));
		p->DATA = x;				//赋值给数据域
		p->NEXT = H->NEXT;			//将节点插到表头
		H->NEXT = p;
	}
	return H;
}

//尾插法
pointnode listofend()
{
	Node* H = (Node*)malloc(sizeof(Node));	//开辟头空间
	H->NEXT = NULL;			//初始化

	int x;
	Node* l;		//定义为尾指针
	l = H;          // 尾指针开始指向头,始终指向尾。
	while (scanf("%d", &x) != EOF)
	{
		Node* p = (Node*)malloc(sizeof(Node));
		p->DATA = x;
		l->NEXT = p;	//将结点插到表头
		l = p;

	}
	l->NEXT = NULL;
	return H;
}
//遍历链表
void listoftravel(pointnode H)
{
	Node* p = H->NEXT;

	int i = 1;
	while (p)
	{
		printf("第%d个数据是%d\n", i++, p->DATA);
		p = p->NEXT;
	}

}
//链表的插入
pointnode datainlist(pointnode H,int i,int x)
{
	Node* preve = H;
	int seek;
	for (seek = 1; seek < i; seek++)//寻找元素位置
	{
		preve = preve->NEXT;
	}
	Node* p = (Node*)malloc(sizeof(Node));
	p->DATA = x;
	p->NEXT = preve->NEXT;
	preve->NEXT = p;
	return H;
}
//链表的修改
pointnode moddata(pointnode H,int x,int t)
{
	Node* p = H->NEXT;

	while (p)
	{
		if (p->DATA == x)
		{
			p->DATA = t;
		}
		p = p->NEXT;
	}
	return H;
}

//链表的删除
pointnode  freedata(pointnode H,int x)
{
	Node* p;
	Node* preve;//前驱结点
	p = H->NEXT;

	while (p->DATA != x)//查找元素
	{
		preve = p;
		p = p ->NEXT;
	}
	preve->NEXT = p->NEXT;
	free(p);	//删除操作
	return H;

}
int main()
{
	pointnode list;
	Initialize();
	list = listofend();
	//list = listofhead();
	listoftravel(list);

	//链表的修改
	int x;
	int t;
	printf("你想修改的数据是:");
	scanf("%d", &x);
	printf("你想把他改为:");
	scanf("%d", &t);
	moddata(list, x, t);
	listoftravel(list);

	//链表的插入
	int i;
	printf("你想在哪个位置插入数据:");
	scanf("%d", &i);
	printf("你想插入的数据是:");
	scanf("%d", &x);
	datainlist(list, i, x);
	listoftravel(list);

	//链表的删除
	printf("你想删除的数据是:");
	scanf("%d", &x);
	freedata(list, x);
	listoftravel(list);
	return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值