数据结构之单向链表类(C++实现)

Definition.h

// 链表节点定义
typedef struct _ListNode {
	_ListNode* next;
	int data;
}ListNode;

List.h

#include <iostream>
#include <stack>
#include "Definition.h"


// 链表定义及链表类
class List {
public:
	List(); //默认构造函数
	List(const List& ls); //拷贝构造函数
	~List(); //默认析构函数
	void AddEndNode(int val); //尾部添加节点
	void AddFrontNode(int val); //链表头部添加节点
	void ShowList(); //打印链表
	void ReverseShowList(); //反向打印链表
	void InsertNode(int val, int loc); //中间插入节点
	void DeleteNode(int val); //删除节点
	void DeleteFrontNode(); //删除头结点
	void DeleteEndNode(); //删除尾节点
	void ReverseList(); //反转链表
	void RemoveList(); //删除链表
	bool Find(int val); //查找节点
	bool IsEmpty(); //判断链表是否为空

private:
	ListNode* head;
	int length;
};

// 构造函数
List::List() 
{
	head = new ListNode;
	head->next = nullptr;
	length = 0;
}

//拷贝构造函数
List::List(const List& ls)
{
	// 初始化
	head = new ListNode;
	ListNode* node = ls.head->next;
	ListNode* curNode = head;

	// 遍历链表赋值
	while (node != nullptr) {
		ListNode* tmp = new ListNode;
		tmp->data = node->data;
		tmp->next = nullptr;
		curNode->next = tmp;
		// 节点前移
		curNode = curNode->next;
		node = node->next;
	}
	
	length = ls.length;
}

// 析构函数
List::~List()
{
	if (length) {
		RemoveList();
		delete head;
		head = nullptr;
		printf("Released~!\n");
	}
	else {
		delete head;
		head = nullptr;
		printf("0 Released~!\n");
	}
}

// 尾部添加节点
void List::AddEndNode(int val)
{
	ListNode* p = head;
	//遍历到链表尾部
	while (p->next != nullptr) {
		p = p->next;
	}
	//添加节点
	ListNode* newNode = new ListNode;
	newNode->data = val;
	newNode->next = nullptr;
	p->next = newNode;
	++length;
}

// 头部添加节点
void List::AddFrontNode(int val)
{
	ListNode* newNode = new ListNode;
	newNode->data = val;
	newNode->next = head->next;
	head->next = newNode;
	++length;
}

// 输出链表
void List::ShowList()
{
	// 链表是否为空
	if (!length) {
		printf("List is empty!\n");
		return;
	}

	ListNode* p = head->next;
	// 遍历链表打印
	while (p != nullptr) {
		printf("%d-->", p->data);
		p = p->next;
	}
	printf("ListEnd\n");
}

//反向打印链表
void List::ReverseShowList()
{
	//采用栈来反向输出
	std::stack<int> s;
	
	ListNode* p = head->next;
	while (p != nullptr) {
		s.push(p->data);
		p = p->next;
	}

	// 栈输出
	while (!s.empty()) {
		printf("%d<--", s.top());
		s.pop();
	}
	printf("ListHead\n");
}

// 在某节点后插入节点
void List::InsertNode(int val, int loc)
{
	ListNode* p = head->next;
	while (p != nullptr) {
		if (loc == p->data) break;
		p = p->next;
	}

	ListNode* newNode = new ListNode;
	newNode->data = val;
	// 如果没有遍历到结尾
	if (p != nullptr) {
		newNode->next = p->next;
		p->next = newNode;
		++length;
	}
	/*else {
		newNode->next = nullptr;
		p = newNode;
	}*/
}	

// 根据值删除某个节点
void List::DeleteNode(int val)
{
	// 链表是否为空
	if (!length) {
		printf("List is empty!\n");
		return;
	}

	// pre是p的上一个节点
	// 在删除时不需要重新遍历第二遍
	ListNode* toBeDel = head->next;
	ListNode* pre = head;
	bool found = false;
	// 遍历到需要删除的节点
	while (toBeDel != nullptr) {
		if (val == toBeDel->data) {
			found = true;
			break;
		}
		// 节点前移
		toBeDel = toBeDel->next;
		pre = pre->next;
	}

	if (!found) {
		printf("Node not been found!\n");
		return;
	}
	else {
		// 删除节点
		pre->next = toBeDel->next;
		delete toBeDel;
		toBeDel = nullptr;
		--length;
	}
}

// 删除头部节点
void List::DeleteFrontNode()
{
	// 链表是否为空
	if (!length) {
		printf("List is empty!\n");
		return;
	}

	// 删除头部节点
	ListNode* del = head->next;
	head->next = del->next;
	delete del;
	del = nullptr;
}

// 删除尾部节点
void List::DeleteEndNode()
{
	// 链表是否为空
	if (!length) {
		printf("List is empty!\n");
		return;
	}

	ListNode* pre = head;
	ListNode* del = head->next;
	// 遍历到链表尾部
	while (del->next != nullptr) {
		del = del->next;
		pre = pre->next;
	}

	delete del;
	del = nullptr;
	pre->next = nullptr;
}

// 翻转链表
void List::ReverseList()
{
	if (!head->next) {
		printf("List is empty!\n");
		return;
	}
	ListNode* pre = head->next, * node = head->next->next, * tmp;
	pre->next = nullptr;
	while (node) {
		tmp = node->next;
		node->next = pre;
		// 向前递进
		pre = node;
		node = tmp;
	}
	head->next = pre;
}

// 移除链表
void List::RemoveList()
{
	ListNode* p = head->next;
	ListNode* del;

	while (p != nullptr) {
		del = p;
		p = p->next;
		delete del;
	}

	head->next = nullptr;
	del = nullptr;
	p = nullptr;
	length = 0;
}

// 查找节点
bool List::Find(int val)
{
	ListNode* p = head->next;

	while (p != nullptr) {
		if (val == p->data) {
			printf("Node %d has been found\n", val);
			return true;
		}
		p = p->next;
	}
	printf("Node %d not been found\n", val);
	return false;
}

// 判断链表是否为空
bool List::IsEmpty()
{
	return length == 0;
}

main.cpp(测试代码)

#include <iostream>
#include "List.h"

int main()
{
	List MyList;
	// 空链表
	MyList.ShowList();
	// 尾部添加节点
	MyList.AddEndNode(1);
	MyList.AddEndNode(2);
	MyList.AddEndNode(3);
	MyList.InsertNode(6, 2);
	MyList.AddFrontNode(5);
	// 显示添加后的链表
	MyList.ShowList();
	MyList.ReverseShowList();
	MyList.Find(3);
	// 删除节点
	MyList.DeleteNode(8);
	MyList.DeleteNode(2);
	MyList.ShowList();
	MyList.DeleteFrontNode();
	MyList.DeleteEndNode();
	MyList.ShowList();

	List YourList(MyList);
	YourList.ShowList();
	
	return 0;
}
  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值