首页 > 其他分享 >动态链表学习笔记:查找,插入与删除

动态链表学习笔记:查找,插入与删除

时间:2024-03-12 20:30:50浏览次数:18  
标签:node cout 笔记 next 链表 查找 NULL name

目录

情境引入:

一、数据的查找

1.要求:

2.思路:

3.程序:

4.运行 :

二、数据的插入 

1.要求:

2.思路:

 3.程序:

 4.运行:

三、数据的删除

1.要求:

2.思路:

3.程序:

4.运行

四、调整与小结:

优化:

运行


情境引入:

        学习了动态链表的输入输出后,若还需要对其进行进一步的操作,要怎么实现呢?为了更好的学习链表的操作,我们不妨根据一个实际情境进一步完善上次的程序:

题目:写一个链表的程序,使其能完成数据的插入,删除与查找

数据包括工人的编号,姓名和年龄

 我对上期的代码主要做了如下的修改:结构体的数据数量调整,变为工人的编号,姓名,年龄三个变量;输入输出部分也进行了相应的改动。

#include<iostream>
using namespace std;
struct node
{
	char num[30];
	char name[30];
	int age;
	struct node* next;
};

node* head;
void create()
{
	node* p = NULL, * s;
	s = new node;
	cin >> s->num;
	cin >> s->name;
	cin >> s->age;
	head = NULL;
	while (s->num != NULL && s->age != NULL && s->name != NULL) {
		if (head == NULL)head = s;
		else p->next = s;
		p = s;
		s = new node;
		cin >> s->num;
		cin >> s->name;
		cin >> s->age;
	}
	p->next = NULL;
	delete s;
	return;
}

int main()
{
	node* p;
	create();
	p = head;
	while (p != NULL)
	{
		cout << p->num << " " << p->name << " " << p->age << endl;
		p = p->next;
	}
	return 0;
}

输出部分如图 :

一、数据的查找

1.要求:

        输入数据在链表中的位置,检索链表输出对应元素

2.思路:

        因为插入与删除需要用到数据的查找,调用查找函数找到相应的位置直接进行相应的修改即可,所以我们从查找做起。

        我们查找的逻辑是:输入了元素的位置后,先判断输入是否合理(这个变量起码要大于0)我们只需要在函数中添加一个循环控制变量,当变量和我们输入的元素位置的变量相等时返回对应的指针。如果没有遍历到,那么就返回空指针。

        所以循环的条件就很容易想到,就是链表指向的元素不能是空指针,如果遍历到空指针还没有返回值,那么就说明这个链表没有这么长,所以返回空指针。

注意!!其实这个函数是可以写成void型直接输出的,但是我们后续的插入和删除需要调用查找函数,所以我们选择指针作为返回类型。

3.程序:
node *search (int search)
{//search变量是要查找的数据,在主函数中输入传入被调函数
	if (search <= 0) //非法输入
		return NULL;
	if (search == 1)//第一个数据返回头指针
		return head;
	int j = 2;//从第二个数据开始
	node* p;
	p = head->next;//将头指针向后移
	while (j !=search && p != NULL)
	{
		p = p->next;
		j++;
	}
	return p;
}
4.运行 :

二、数据的插入 

1.要求:

        输入要插入数据的位置,输入要插入的数据,将数据插入到输入的位置数据的后面。

2.思路:

        我们输入插入数据的位置后,我们应当先对输入的数据的合法性进行检测,如果数据小于一,那么应当有报错提示。之后可以通过调用查找函数找到其在链表中的位置(p),在当前位置开辟新空间(q),将数据写入q,让p的地址部分储存刚开辟的q的地址(p->next = q;),让q的地址部分指向原来p指向的地址即可(q->next = p->next;)。流程图如下:

 3.程序:
void insert()
{
	int insert;
	cout << "请选择你要插入的位置:" << endl;
	cin >> insert;
	if (insert < 1)//输入合法性判断
	{
		cout << "您所插入的位置不存在" << endl;
		return;
	}
	node* p = search(insert);
	node* q = new node;
	cout << "请输入要插入的节点数据编号:";
	cin >> q->num;
	cout << "请输入要插入的节点数据姓名:";
	cin >> q->name;
	cout << "请输入要插入的节点数据年龄:";
	cin >> q->age;
	q->next = p->next;//将q的地址部分指向p原来指向的结构体
	p->next = q;//让p的地址部分指向q
	return;
}
 4.运行:

三、数据的删除

1.要求:

输入要删除的元素的位置,将该处的数据从链表中删除。

2.思路:

有了插入的铺垫,删除的原理与之相似,也是输入要删除的数据(p2)的位置,那么我们只需要用查找函数找到该位置结构体的前一位(p1)和后一位(p3),让前一个结构体的地址部分指向它后一个结构体。(也就是p1->next = p3;)这样,这个结构体就不被指向了,或者说,就被“跳过了”。这时我们再用delete关键字释放空间,这个结构体就被彻底删除了。说起来些许抽象,上程序框图:

3.程序:
void remove()
{
	int i;
	cout << "请选择你要删除的位置:" << endl;
	cin >> i;
	node* p1 = search(i - 1);
	node* p2 = p1->next;
	node* p3 = p2->next;
	p1->next = p3;//让p1的地址部分直接指向p3
	delete p2;//释放内存空间
	cout << "删除成功!" << endl;
	return;
}
4.运行:

四、调整与小结:

至此,我们整个的链表操作系统系列就结束啦! 

优化:

为了方便,我在程序中添加了打印链表的print函数,之后又把几个函数整合到一起。同时为了提高程序的实用性,我在程序中添加了switch函数,通过输入不同的数字对链表进行不同的操作,更加便捷,同时也优化了输出,完整程序如下:

#include<iostream>
using namespace std;

struct node
{
	char num[20];
	char name[20];
	int age;
	struct node* next;
};

node* head;

void print()
{
	node* p;
	p = head;
	while (p != NULL)
	{
		cout << p->num << " " << p->name << " " << p->age << endl;
		p = p->next;
	}
	return;
}

void create()//创建链表
{
	int stage = 2;
	node* p = NULL, * s;
	s = new node;
	cout << "请输入编号:";
	cin >> s->num;
	cout << "请输入姓名:";
	cin >> s->name;
	cout << "请输入年龄:";
	cin >> s->age;
	head = NULL;
	while (s->age != NULL && s->name != NULL && s->num != NULL) {
		cout << "正在输入第" << stage << "个元素" << endl;
		if (head == NULL)head = s;
		else p->next = s;
		p = s;
		s = new node;
		cout << "请输入编号:";
		cin >> s->num;
		cout << "请输入姓名:";
		cin >> s->name;
		cout << "请输入年龄:";
		cin >> s->age;
		stage++;
	}
	p->next = NULL;
	delete s;
	return;
}

node *search (int search)//搜索链表
{
	if (search <= 0) 
		return NULL;
	if (search == 1)
		return head;
	int j = 2;
	node* p;
	p = head->next;
	while (j !=search && p != NULL)
	{
		p = p->next;
		j++;
	}
	return p;
}
void insert()
{
	int insert;
	cout << "请选择你要插入的位置:" << endl;
	cin >> insert;
	if (insert < 1)//输入合法性判断
	{
		cout << "您所插入的位置不存在" << endl;
		return;
	}
	node* p = search(insert);
	node* q = new node;
	cout << "请输入要插入的节点数据编号:";
	cin >> q->num;
	cout << "请输入要插入的节点数据姓名:";
	cin >> q->name;
	cout << "请输入要插入的节点数据年龄:";
	cin >> q->age;
	q->next = p->next;//将q的地址部分指向p原来指向的结构体
	p->next = q;//让p的地址部分指向q
	return;
}


void remove()
{
	int i;
	cout << "请选择你要删除的位置:" << endl;
	cin >> i;
	node* p1 = search(i - 1);
	node* p2 = p1->next;
	node* p3 = p2->next;
	p1->next = p3;
	delete p2;
	cout << "删除成功!" << endl;
	return;

}
int main()
{
	node* p;
	int location, operate;
	cout << "创建链表:" << endl;
	create();
	print();
	cout << "请输入要进行的操作:1查找,2插入,3删除:";
	while (cin >> operate) {
		if (operate == 0)
			break;
		else {
			switch (operate) {
			case 1:
				cout << "请输入要查找的元素位置:";
				cin >> location;
				cout << search(location)->num << " " << search(location)->name << " " << search(location)->age << endl;
				break;
			case 2:
				insert();
				print();
				break;
			case 3:
				remove();
				print();
				break;
			}
		}
		cout << "请输入要进行的操作:1查找,2插入,3删除:";
	}
	return 0;
}
运行:

标签:node,cout,笔记,next,链表,查找,NULL,name
From: https://blog.csdn.net/weixin_45080800/article/details/136659874

相关文章

  • 【算法】【线性表】【数组】在排序数组中查找元素的第一个和最后一个位置
    1 题目给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1,-1]。你必须设计并实现时间复杂度为 O(logn) 的算法解决此问题。示例1:输入:nums=[5,7,7,8,8,......
  • Vue2.x笔记:组件通信
    一、插槽slot插槽(slot)是一种Vue中组件通信的方式,主要用于父组件向子组件传递自定义内容。有三种插槽:默认插槽:最基本的插槽,没有任何标识,每个子组件只能定义一个具名插槽:具有name属性的默认插槽,每个子组件可以定义多个作用域插槽:子组件提供数据,由父组件决定其渲染方式1.默......
  • leetcode160.链表相交
    160.相交链表 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。图示两个链表在节点 c1 开始相交:题目数据 保证 整个链式结构中不存在环。注意,函数返回结果后,链表必须 保持其原始结......
  • go语言笔记
    学golang,我需要阅读一本go语言的书籍,也需要浏览和go相关的社区网站。有一个问题是,为什么需要阅读一本编程书籍?直接从网上搜索是可以找到很多快餐资料的,似乎比书籍更有效?答案是全面。通常,书的质量比博客高多了,我现在写的就是博客,算不上书籍。书籍的质量也体现在它的内容比较系统......
  • 查找笔记本设备编号
    有一笔记本充不了电了,想着也过保了,交差也得查一下保修状况,上了官网,要求输入设备编号,是的,这个编号肯定是要的,结果输了一圈,什么serialnumber,typenumber,factoryid,complianceid,cmiidid,还是没有得到自己简单想要的,标签是哑光黑,看着费眼神,想来厂家为保密原因也可以理解,怎么编......
  • java学习笔记(不定时更新!)
    (1)三元运算符: 运算式?输出结果1:输出结果2;(2)键盘录入: scannersc=newScanner(System.in){ inti=Scanner.nextInt(); doubled=Scanner.nextDouble(); Stringstr=sc.next(); }(3) 数组(长度固定,可存基本数据类型):数据类型【】数组名=new数据类型【】{元素1......
  • Java学习笔记——第十三天
    常用API(二)MathMath代表数学,是一个工具类,里面提供的都是对数据进行操作的一些静态方法。Math类提供的常用方法方法名说明publicstaticintabs(inta)获取参数绝对值publicstaticdoubleceil(doublea)向上取整publicstaticdoublefloor(doublea)向下......
  • scikit-opt学习笔记
    1.差分约束算法'''minf(x1,x2,x3)=x1^2+x2^2+x3^2s.t.x1*x2>=1x1*x2<=5x2+x3=10<=x1,x2,x3<=5'''defobj_func(p):x1,x2,x3=preturnx1**2+x2**2+x3**2c......
  • Leetcode.19. 删除链表的倒数第 N 个结点
    给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。示例1:输入:head=[1,2,3,4,5],n=2输出:[1,2,3,5]示例2:输入:head=[1],n=1输出:[]示例3:输入:head=[1,2],n=1输出:[1] 提示:链表中结点的数目为 sz1<=sz<=300<=Node.val<=100......
  • leetcode: 1261: 在受污染的二叉树中查找元素
    给出一个满足下述规则的二叉树:root.val==0如果 treeNode.val==x 且 treeNode.left!=null,那么 treeNode.left.val==2*x+1如果 treeNode.val==x 且 treeNode.right!=null,那么 treeNode.right.val==2*x+2现在这个二叉树受到「污染」,所有的 tree......