數據結構之單向鏈表類(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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章