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

目录

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

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

输出结果

相关推荐
刚学HTML23 分钟前
leetcode 05 回文字符串
算法·leetcode
蜀黍@猿27 分钟前
【C++ 基础】从C到C++有哪些变化
c++
Am心若依旧40928 分钟前
[c++11(二)]Lambda表达式和Function包装器及bind函数
开发语言·c++
明月看潮生30 分钟前
青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试
开发语言·青少年编程·单元测试·编程与数学·goweb
Yan.love36 分钟前
开发场景中Java 集合的最佳选择
java·数据结构·链表
zh路西法38 分钟前
【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(一):从电梯出发的状态模式State Pattern
c++·决策树·状态模式
大G哥40 分钟前
java提高正则处理效率
java·开发语言
AC使者42 分钟前
#B1630. 数字走向4
算法
冠位观测者1 小时前
【Leetcode 每日一题】2545. 根据第 K 场考试的分数排序
数据结构·算法·leetcode
VBA63371 小时前
VBA技术资料MF243:利用第三方软件复制PDF数据到EXCEL
开发语言