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

目录

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

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++代码

cpp 复制代码
#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++代码

cpp 复制代码
#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++代码

cpp 复制代码
#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++代码

cpp 复制代码
#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++代码

cpp 复制代码
#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;
}

输出结果

相关推荐
是小Y啦8 分钟前
leetcode 106.从中序与后续遍历序列构造二叉树
数据结构·算法·leetcode
LyaJpunov8 分钟前
C++中move和forword的区别
开发语言·c++
程序猿练习生13 分钟前
C++速通LeetCode中等第9题-合并区间
开发语言·c++·leetcode
liuyang-neu18 分钟前
力扣 42.接雨水
java·算法·leetcode
z千鑫21 分钟前
【人工智能】如何利用AI轻松将java,c++等代码转换为Python语言?程序员必读
java·c++·人工智能·gpt·agent·ai编程·ai工具
一名路过的小码农23 分钟前
C/C++动态库函数导出 windows
c语言·开发语言·c++
y_dd25 分钟前
【machine learning-12-多元线性回归】
算法·机器学习·线性回归
m0_6312704025 分钟前
标准c语言(一)
c语言·开发语言·算法
万河归海42825 分钟前
C语言——二分法搜索数组中特定元素并返回下标
c语言·开发语言·数据结构·经验分享·笔记·算法·visualstudio
小周的C语言学习笔记30 分钟前
鹏哥C语言36-37---循环/分支语句练习(折半查找算法)
c语言·算法·visual studio