数组与链表算法-单向链表算法

news2024/11/28 16:35:56

目录

数组与链表算法-单向链表算法

C++代码

单向链表插入节点的算法

C++代码

单向链表删除节点的算法

C++代码

对单向链表进行反转的算法

C++代码

单向链表串接的算法

C++代码


数组与链表算法-单向链表算法

在C++中,若以动态分配产生链表节点的方式,则可以先行定义一个类数据类型,接着在类中定义一个指针变量,其数据类型与此类相同,作用是指向下一个链表节点,另外类中至少要有一个数据字段。例如,声明一个学生成绩链表节点的结构,并且包含两个数据字段:姓名(name)和成绩(score),以及一个指针(next)。接着就可以动态创建链表中的每个节点。假设现在要新增一个节点至链表的末尾,且ptr指向链表的第一个节点,程序必须设计以下4个步骤:

  1. 动态分配内存空间给新节点使用。
  2. 将原链表尾部的指针(next)指向新元素所在的内存位置(内存地址)。
  3. 将ptr指针指向新节点的内存位置,表示这是新的链表尾部。
  4. 由于新节点当前为链表的最后一个元素,因此将它的指针(next)指向NULL。

遍历(Traverse)单向链表的过程,就是使用指针运算来访问链表中的每个节点。如果要遍历已建立的单向链表,就可以使用结构指针ptr来作为链表的读取游标,一开始指向链表的头。每次读完链表的一个节点,就将ptr往下一个节点移动(指向下一个节点),直到ptr指向NULL为止。

C++代码

#include<iostream>
using namespace std;

class list {
public:
	int num;
	char name[10];
	int score;
	class list* next;
};

void SetList(list* tempList) {
	cout << "请输入学号:";
	cin >> tempList->num;
	cout << "请输入姓名:";
	cin >> tempList->name;
	cout << "请输入成绩:";
	cin >> tempList->score;
}

int main() {
	list* newnode;
	list* ptr;
	list* delptr;
	
	cout << "请输入5位学员的数据:" << endl;
	delptr = new list;
	SetList(delptr);
	ptr = delptr;
	for (int i = 1; i < 5; i++) {
		newnode = new list;
		SetList(newnode);
		newnode->next = nullptr;
		ptr->next = newnode;
		ptr = ptr->next;
	}
	cout << "学生成绩" << endl;
	cout << "学号\t姓名\t成绩\n========================" << endl;
	ptr = delptr;
	while (ptr != nullptr) {
		cout << ptr->num << "\t" << ptr->name << "\t" << ptr->score << endl;
		ptr = ptr->next;
	}
	return 0;
}

输出结果

单向链表插入节点的算法

  1. 将新节点加到第一个节点之前,即成为此链表的首节点。
  2. 将新节点加到最后一个节点之后。
  3. 将新节点加到链表中间的位置。

C++代码

#include<iostream>
using namespace std;

class list {
public:
	int num;
	char name[10];
	int score;
	class list* next;
};

void SetList(list* tempList) {
	cout << "请输入学号:";
	cin >> tempList->num;
	cout << "请输入姓名:";
	cin >> tempList->name;
	cout << "请输入成绩:";
	cin >> tempList->score;
}

void PrintList(list* head) {
	list* ptr = head;
	while (ptr != nullptr) {
		cout << ptr->num << "\t" << ptr->name << "\t" << ptr->score << endl;
		ptr = ptr->next;
	}
}

list* FindNode(list* head, int num) {
	list* ptr;
	ptr = head;
	while (ptr != nullptr) {
		if (ptr->num == num)
			return ptr;
		ptr = ptr->next;
	}
	return ptr;
}

list* InsertNode(list* head, list* ptr, list* tempList) {
	if (ptr == nullptr) {
		tempList->next = head;
		return tempList;
	}
	else {
		if (ptr->next == nullptr) {
			ptr->next = tempList;
		}
		else {
			tempList->next = ptr->next;
			ptr->next = tempList;
		}
	}
	return head;
}

int main() {
	list* newnode;
	list* ptr;
	list* head;

	cout << "请输入3位学员的数据:" << endl;
	head = new list;
	SetList(head);
	ptr = head;
	for (int i = 1; i < 3; i++) {
		newnode = new list;
		SetList(newnode);
		newnode->next = nullptr;
		ptr->next = newnode;
		ptr = ptr->next;
	}
	cout << "========================" << endl;
	cout << "学生成绩" << endl;
	cout << "学号\t姓名\t成绩\n========================" << endl;
	PrintList(head);

	int position;
	while (true){
		cout << "请输入要插入其后的学生学号,要结束请输入-1:";
		cin >> position;
		if (position == -1)
			break;
		else {
			ptr = FindNode(head, position);
			newnode = new list;
			SetList(newnode);
			head = InsertNode(head, ptr, newnode);
		}
	}
	cout << "========================" << endl;
	cout << "学生成绩" << endl;
	cout << "学号\t姓名\t成绩\n========================" << endl;
	PrintList(head);

	return 0;
}

输出结果

单向链表删除节点的算法

  1. 删除链表的第一个节点
  2. 删除链表的最后一个节点
  3. 删除链表的中间节点

C++代码

#include<iostream>
using namespace std;

class list {
public:
	int num;
	char name[10];
	int score;
	class list* next;
};

void SetList(list* tempList) {
	cout << "请输入学号:";
	cin >> tempList->num;
	cout << "请输入姓名:";
	cin >> tempList->name;
	cout << "请输入成绩:";
	cin >> tempList->score;
}

void PrintList(list* head) {
	list* ptr = head;
	while (ptr != nullptr) {
		cout << ptr->num << "\t" << ptr->name << "\t" << ptr->score << endl;
		ptr = ptr->next;
	}
}

list* FindNode(list* head, int num) {
	list* ptr;
	ptr = head;
	while (ptr != nullptr) {
		if (ptr->num == num)
			return ptr;
		ptr = ptr->next;
	}
	return ptr;
}

list* DeleteNode(list* head, list* ptr) {
	list* top;
	top = head;
	if (ptr == head) {
		head = head->next;
	}
	else {
		while (top->next != ptr)
			top = top->next;
		if (ptr->next == nullptr)
			top->next = nullptr;
		else
			top->next = ptr->next;
	}
	cout << "已删除第 " << ptr->num << " 号学生的信息" << endl;
	delete ptr;
	return head;
}

int main() {
	list* newnode;
	list* ptr;
	list* head;

	cout << "请输入3位学员的数据:" << endl;
	head = new list;
	SetList(head);
	ptr = head;
	for (int i = 1; i < 3; i++) {
		newnode = new list;
		SetList(newnode);
		newnode->next = nullptr;
		ptr->next = newnode;
		ptr = ptr->next;
	}
	cout << "========================" << endl;
	cout << "学生成绩" << endl;
	cout << "学号\t姓名\t成绩\n========================" << endl;
	PrintList(head);

	int position;
	while (true) {
		cout << "请输入要插入其后的学生学号,要结束请输入-1:";
		cin >> position;
		if (position == -1)
			break;
		else {
			ptr = FindNode(head, position);
			head = DeleteNode(head, ptr);
		}
	}
	cout << "========================" << endl;
	cout << "学生成绩" << endl;
	cout << "学号\t姓名\t成绩\n========================" << endl;
	PrintList(head);

	return 0;
}

输出结果

对单向链表进行反转的算法

了解单向链表节点的插入和删除之后,大家会发现在这种具有方向性的链表结构中增删节点是相当容易的一件事。而要从头到尾输出整个单向链表也不难,但若要反转过来输出单向链表,则需要某些技巧。我们知道单向链表中的节点特性是知道下一个节点的位置,是无从得知它的上一个节点的位置。如果要将单向链表反转,就必须使用3个指针变量,如下面程序代码中的before、ptr、last。

C++代码

#include<iostream>
using namespace std;

class list {
public:
	int num;
	char name[10];
	int score;
	class list* next;
};

void SetList(list* tempList) {
	cout << "请输入学号:";
	cin >> tempList->num;
	cout << "请输入姓名:";
	cin >> tempList->name;
	cout << "请输入成绩:";
	cin >> tempList->score;
}

void PrintList(list* head) {
	list* ptr = head;
	while (ptr != nullptr) {
		cout << ptr->num << "\t" << ptr->name << "\t" << ptr->score << endl;
		ptr = ptr->next;
	}
}

list* TransposeNode(list* head) {
	list* ptr = head;
	list* before = nullptr;
	list* last = nullptr;
	while (ptr != nullptr) {
		last = before; 
		before = ptr;
		ptr = ptr->next;
		before->next = last;
	}
	head = before;
	return head;
}

int main() {
	list* newnode;
	list* ptr;
	list* head;

	cout << "请输入3位学员的数据:" << endl;
	head = new list;
	SetList(head);
	ptr = head;
	for (int i = 1; i < 3; i++) {
		newnode = new list;
		SetList(newnode);
		newnode->next = nullptr;
		ptr->next = newnode;
		ptr = ptr->next;
	}
	cout << "========================" << endl;
	cout << "学生成绩" << endl;
	cout << "学号\t姓名\t成绩\n========================" << endl;
	PrintList(head);

	head = TransposeNode(head);
	
	cout << "========================" << endl;
	cout << "反转算法" << endl;
	cout << "学号\t姓名\t成绩\n========================" << endl;
	PrintList(head);

	return 0;
}

输出结果

单向链表串接的算法

对于两个或两个以上的链表的串接(Concatenation,也称为级联),实现起来很容易;只要将链表的首尾相连即可。

C++代码

#include<iostream>
using namespace std;

class list {
public:
	int num;
	char name[10];
	int score;
	class list* next;
};

void SetList(list* tempList) {
	cout << "请输入学号:";
	cin >> tempList->num;
	cout << "请输入姓名:";
	cin >> tempList->name;
	cout << "请输入成绩:";
	cin >> tempList->score;
}

void PrintList(list* head) {
	list* ptr = head;
	while (ptr != nullptr) {
		cout << ptr->num << "\t" << ptr->name << "\t" << ptr->score << endl;
		ptr = ptr->next;
	}
}

list* ConcatNode(list* head1, list* head2) {
	list* ptr;
	ptr = head1;
	while (ptr->next != nullptr)
		ptr = ptr->next;
	ptr->next = head2;
	return head1;
}

int main() {
	list* newnode;
	list* ptr;
	list* head1;
	list* head2;

	cout << "请输入第一组3位学员的数据:" << endl;
	head1 = new list;
	SetList(head1);
	ptr = head1;
	for (int i = 1; i < 3; i++) {
		newnode = new list;
		SetList(newnode);
		newnode->next = nullptr;
		ptr->next = newnode;
		ptr = ptr->next;
	}
	cout << "========================" << endl;
	cout << "第一组学生成绩" << endl;
	cout << "学号\t姓名\t成绩\n========================" << endl;
	PrintList(head1);
	
	cout << "请输入第二组3位学员的数据:" << endl;
	head2 = new list;
	SetList(head2);
	ptr = head2;
	for (int i = 1; i < 3; i++) {
		newnode = new list;
		SetList(newnode);
		newnode->next = nullptr;
		ptr->next = newnode;
		ptr = ptr->next;
	}
	cout << "========================" << endl;
	cout << "第二组学生成绩" << endl;
	cout << "学号\t姓名\t成绩\n========================" << endl;
	PrintList(head2);

	head1 = ConcatNode(head1, head2);

	cout << "========================" << endl;
	cout << "串接算法" << endl;
	cout << "学号\t姓名\t成绩\n========================" << endl;
	PrintList(head1);

	return 0;
}

输出结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1145963.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

标准ACL,扩展ACL,基本ACL,高级ACL

其实标准ACL&#xff0c;扩展ACL&#xff0c;基本ACL&#xff0c;高级ACL是同一个概念的不同名称&#xff0c;区别在于: 思科路由器支持标准ACL和扩展ACL两种类型的访问控制列表&#xff0c;没有”基本ACL“和”高级ACL“的概念&#xff0c;而华为路由器都支持 编号范围&…

2024年天津中德应用技术大学专升本自动化专业基础考试大纲

天津中德应用技术大学自动化专业&#xff08;高职升本科&#xff09;2024年专业基础考试大纲 一、试卷类型&#xff08;仅供参考&#xff09; 试卷卷面成绩共200分&#xff0c;考试时间为2小时。内容包含电工基础30%&#xff0c;电子技术30%&#xff0c;电机原理与拖动40%。试…

PLC程序常用模块

常用程序块 中继复位&#xff08;使用特殊中继SM&#xff09;初始化置位&#xff08;set&#xff09;初始化急停互锁按时断电模块&#xff08;按下按钮&#xff0c;1s后自动断电&#xff09;一次性开关循环的几种方法并联常开点定时器循环&#xff08;串联常闭&#xff0c;断电…

对Happens-Before的理解

Happens-Before Happens-Before 是一种可见性模型&#xff0c;也就是说&#xff0c;在多线程环境下。原本因为指令重排序的存在会导致数据的可见性问题&#xff0c;也就是 A 线程修改某个共享变量对 B 线程不可见。因此&#xff0c;JMM 通过 Happens-Before 关系向开发人员提供…

使用 kube-downscaler 降低Kubernetes集群成本

新钛云服已累计为您分享772篇技术干货 介绍 Kube-downscaler 是一款开源工具&#xff0c;允许用户定义 Kubernetes 中 pod 资源自动缩减的时间。这有助于通过减少非高峰时段的资源使用量来降低基础设施成本。 在本文中&#xff0c;我们将详细介绍 kube-downscaler 的功能、安装…

Vue全局事件总线实现任意组件间通信

一、安装全局事件总线 全局事件总线就像是一个工具&#xff0c;专门用于挂载自定义事件和。 想要所有的组件都能使用这个全局事件总线&#xff0c;就只有在Vue的原型身上添加一个能够绑定自定义事件的属性。 所以我们在创建Vue实例对象的时候就可以添加如下代码&#xff1a;…

C语言实现将密码译回原文,并输出密码和原文

完整代码&#xff1a; // 有一行电文&#xff0c;已按下面规律译成密码&#xff1a; // A→Z a→z // B→Y b→y // C→X c→x /*即第 1 个字母变成第 26 个字母&#xff0c;第 i 个字母变成第&#xff08;26-i1&#xff09;个字母&#xff0c;非字母字 符不变。要求编程序将…

UVa129 Krypton Factor(困难的串)

1、题目 2、题意 如果一个字符串包含两个相邻的重复子串&#xff0c;则称它是“容易的串”&#xff0c;其他串称为“困难的串”。例如&#xff0c;BB、ABCDACABCAB、ABCDABCD都是容易的的串&#xff0c;而D、DC、ABDAB、CBABCBA 都是困难的串。 输入正整数 k k k 和 L L L&a…

JavaScript_对象_Function_定义与参数

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Function对象</title><script>/*** Function&#xff1a;函数&#xff08;方法&#xff09;对象* 1.创建&#xff1a;* 1.…

cosover是什么?crossover23又是什么软件

cosover是篮球里的过人技巧。 1.crossover在篮球中的本意是交叉步和急速交叉步。crossover 是篮球术语&#xff0c;有胯下运球、双手交替运球&#xff0c;交叉步过人、急速大幅度变向等之意。 2.在NBA里是指包括胯下运球、变向、插花在内的过人的技巧。 NBA有很多著名的Cross…

3.5 Early-Z 与 Z Prepass

一、深度测试DepthTest 1.传统渲染管线中的深度测试 深度测试在逐片元操作中的第二步 2.解决物体可见遮挡性的问题 3.深度测试的逻辑 for(each triangle T) //对每一个三角形 { for(each fragment(x,y,z) in T)//对每一个三角形中的片元 { if(fragment.z < ZBuffe…

IOC课程整理-13 Spring校验

1. Spring 校验使用场景 2. Validator 接口设计 3. Errors 接口设计 4. Errors 文案来源 5. 自定义 Validator 6. Validator 的救赎 7. 面试题精选 Spring 校验接口是哪个 org.springframework.validation.Validator Spring 有哪些校验核心组件&#xff1f;

嵌入式项目电灯

1、原理&#xff0c;电灯有个正负极&#xff0c;当正确接入电源正负极就能点亮&#xff08;如正极5v,负极0v&#xff09;&#xff0c;单两边同时接入正极&#xff0c;就不会亮&#xff08;两端都是5v&#xff09;,所以通过控制电平&#xff0c;来实现控制led等的亮暗 cpu通过给…

Eclipse:编译前自动保存文件

Eclipse默认不会在编译前保存文件&#xff0c;所以有时修改了半天程序&#xff0c;但是忘记保存&#xff0c;结果编译报的问题与代码不一致&#xff0c;甚至调试半天才发现是文件没有保存&#xff0c;很是让人恼怒。 可以通过以下设置&#xff0c;让Eclipse在编译前自动保存文…

如何快速排查SSD IO延迟抖动问题?

一块固态硬盘设计背后&#xff0c;有硬件控制器&#xff0c;NAND闪存颗粒、DRAM&#xff0c;还有固件FTL算法等。SSD设计的本身其实是一件特别复杂的过程&#xff0c;需要考虑各种客户需求且要保证可靠性、性能、稳定性。 针对SSD的相关性能测试&#xff0c;SNIA也有专门针对SS…

制作自己的前端组件库并上传到npm上

最近实现了自己的一个前端组件库demo&#xff0c;目前只上传了几个小组件。话不多说&#xff0c;上图&#xff1a; 我分了三个项目&#xff1a;yt-ui组件库、使用文档、demo。线上地址如下&#xff1a; [yt-ui组件库](mhfwork/yt-ui - npm) [组件库使用文档](介绍 | mhfwork/y…

自动化项目实战 [个人博客系统]

自动化博客项目 用户注册登录验证效验个人博客列表页博客数量不为 0 博客系统主页写博客 我的博客列表页效验 刚发布的博客的标题和时间查看 文章详情页删除文章效验第一篇博客 不是 "自动化测试" 注销退出到登录页面,用户名密码为空 用户注册 Order(1)Parameterized…

【云备份|| 日志 day1】项目认识 环境准备

day1 项目总纲云备份实现目标 搭建环境词汇解释 项目总纲 云备份 自动将本地计算机上指定文件夹中需要备份的文件上传备份到服务器中。并且能够随时通过浏览器进行查看并且下载&#xff0c;其中下载过程支持断点续传功能&#xff0c;而服务器也会对上传文件进行热点管理&…

VScode远程连接错误:进程试图写入不存在的管道

使用VScode连接树莓派时&#xff0c;出现远程连接错误&#xff1a;进程试图写入不存在的管道 解决方案&#xff1a; &#xff08;1&#xff09;可以进入config所在文件夹&#xff0c;删除文件 &#xff08;2&#xff09;无法解决的化尝试下述方法 输入 Remotting-SSH:Settin…

使用 Python 连接到 PostgreSQL 数据库

本文介绍了创建与 PostgreSQL 上的数据库的连接的过程。 我们需要安装 PostgreSQL 和创建数据库等先决条件&#xff0c;如下所述。 在系统中安装 PostgreSQL 顾名思义&#xff0c;PostgreSQL 是一款为高效管理数据库系统而创建的 SQL 系统软件。 在连接Python之前需要创建数据…