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

目录

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

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

输出结果

相关推荐
JSU_曾是此间年少4 分钟前
数据结构——线性表与链表
数据结构·c++·算法
许野平17 分钟前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
也无晴也无风雨20 分钟前
在JS中, 0 == [0] 吗
开发语言·javascript
狂奔solar29 分钟前
yelp数据集上识别潜在的热门商家
开发语言·python
此生只爱蛋1 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
blammmp1 小时前
Java:数据结构-枚举
java·开发语言·数据结构
何曾参静谧1 小时前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++
暗黑起源喵1 小时前
设计模式-工厂设计模式
java·开发语言·设计模式
WaaTong1 小时前
Java反射
java·开发语言·反射
咕咕吖1 小时前
对称二叉树(力扣101)
算法·leetcode·职场和发展