- 一、单链表实现
- 二、测试代码
单链表结构:数据域+指针域
单链表操作:1.创建单链表 2.遍历单链表 3.获取单链表的长度 4.判断单链表是否为空 5.获取节点 6.在尾部插入指定元素 7.在指定位置插入指定元素 8.在头部插入指定元素 9.在尾部删除元素 10.删除所有元素 11.删除指定元素 12.在头部删除元素 13.遍历反转链表 14.递归反转链表 0.退出
list.h
using DataType = int;
struct Node {
DataType val; // 数据域
Node *next; // 指针域
};
class LinkList {
private:
Node *head;
public:
LinkList();
~LinkList();
void CreatLinkList(int n);
void TraceLinkList();
int GetLength();
bool IsEmpty();
Node* Find(DataType val);
void InsertElemAtIndex(DataType val, int n);
void InsertElemAtHead(DataType val);
void InsertElemAtEnd(DataType val);
void DeleteElemAtHead();
void DeleteElemAtEnd();
void DeleteAll();
void DeleteElemVal(DataType val);
void ReverseLinkList();
Node* RecReverseLinkList(Node *head);
void RecReverseLinkListFun();
};
list.cc
#include "./list.h" #include二、测试代码// @description: 创建单链表 LinkList::LinkList() { head = new Node(); head->val = 0; head->next = nullptr; } // @description: 销毁单链表 LinkList::~LinkList() { delete head; } // @description: 创建n个结点的单链表 void LinkList::CreatLinkList(int n) { Node *pnew, *ptemp; ptemp = head; if (n < 0) { std::cout << "input linklist size is error" << std::endl; return; } for (int i = 0; i < n; i++) { pnew = new Node(); pnew->val = static_cast (i); pnew->next = nullptr; ptemp->next = pnew; // 增加新节点 ptemp = pnew; // 节点后移一位 } } // @description: 遍历链表 void LinkList::TraceLinkList() { if (head == nullptr || head->next == nullptr) { std::cout << "linklist is null" << std::endl; } Node *temp = head; int index = 0; while (temp->next != nullptr) { temp = temp->next; std::cout << "linklist index is " << index++; std::cout << ", linklist val is " << temp->val << std::endl; } } // @description: 获取链表长度 int LinkList::GetLength() { int count = 0; Node *node = head->next; while(node != nullptr) { ++count; node = node->next; } return count; } // @description: 判断链表是否为空 bool LinkList::IsEmpty() { if (head->next == nullptr) { return true; } return false; } // @description: 查找指定数据的地址 Node *LinkList::Find(DataType data) { Node *node = head; if (node == nullptr) { std::cout << "find link list is nullptr" << std::endl; return nullptr; } else { while(node->next != nullptr) { if (node->val == data) { return node; } node = node->next; } return nullptr; } } // @description: 尾部插入指定数据 void LinkList::InsertElemAtEnd(DataType data) { Node *new_node = new Node(); // 新增的结点 new_node->val = data; new_node->next = nullptr; Node *temp = head; if (head == nullptr) { head = new_node; } else { while (temp->next != nullptr) { temp = temp->next; } temp->next = new_node; // 新增结点加入尾部 } } // @description: 指定位置插入数据 void LinkList::InsertElemAtIndex(DataType data, int n) { if (n < 1 || GetLength() < n) { std::cout << "input value error" << std::endl; } else { Node *node = new Node(); node->val = data; int count = 1; Node *temp = head; while (count < n) { // 遍历n temp = temp->next; count++; } node->next = temp->next; temp->next = node; } } // @description: 头部插入指定数据 void LinkList::InsertElemAtHead(DataType data) { Node *new_node = new Node(); new_node->val = data; Node *temp = head; // 防止修改head指向 if (head == nullptr) { head = new_node; } new_node->next = temp->next; temp->next = new_node; } // @description: 删除尾部元素 void LinkList::DeleteElemAtEnd() { Node *node = head; Node *temp = nullptr; if (node->next == nullptr) { std::cout << "link list is nullptr" << std::endl; } else { while (node->next != nullptr) { temp = node; node = node->next; } delete node; node = nullptr; temp->next = nullptr; } } // @description: 删除全部元素 void LinkList::DeleteAll() { Node *node = head->next; Node *temp = new Node(); while (node != nullptr) { temp = node; node = node->next; head->next = node; temp->next = nullptr; delete temp; } head->next = nullptr; } // @description: 删除指定数据 void LinkList::DeleteElemVal(DataType data) { Node *temp = Find(data); if (temp == head->next) { DeleteElemAtHead(); } else { Node *node = head; while(node->next != temp) { node = node->next; } node->next = temp->next; delete temp; temp = nullptr; } } // @description: 删除头部元素 void LinkList::DeleteElemAtHead() { Node *node = head; if (node == nullptr || node->next == nullptr) { std::cout << "link list is nullptr" << std::endl; } else { Node *temp = nullptr; node = node->next; temp = node->next; delete node; node = nullptr; head->next = temp; } } // @description: 遍历链表 void LinkList::ReverseLinkList() { // 1->2->3->4->5 // 5->4->3->2->1 // https://leetcode-cn.com/problems/reverse-linked-list/ Node *node = head; if (node == nullptr || head->next == nullptr) { std::cout << "link list is nullptr" << std::endl; return; } node = node->next; Node *temp = nullptr; // 临时保存的指针 Node *new_list = temp; // 保存已经反转之后的链表,最终需要返回的指针 while (node != nullptr) { // 循环遍历每一个变量 temp = node; // 指向当前需要反转的结点1 node = node->next; // 当前结点指向下一个结点2 temp->next = new_list; // 切断当前结点和后面结点之间的联系,指向已经反转之后的结点 new_list = temp; // 保存已经反转之后的指针 } head->next = new_list; } // @description: 递归遍历链表 Node* LinkList::RecReverseLinkList(Node *head) { if (head == nullptr || head->next == nullptr) { return head; } Node *new_head = RecReverseLinkList(head->next); // 递归 head->next->next = head; // 改变head->next的指向 head->next = nullptr; // head->next赋值为nullptr return new_head; } void LinkList::RecReverseLinkListFun() { head->next = RecReverseLinkList(head->next); }
test.cc
#include "./list.h" #includevoid LinkListPrint() { std::cout << "1.创建单链表 2.遍历单链表 3.获取单链表的长度 4.判断单链表是否为空 5.获取节点n"; std::cout << "6.在尾部插入指定元素 7.在指定位置插入指定元素 8.在头部插入指定元素n"; std::cout << "9.在尾部删除元素 10.删除所有元素 11.删除指定元素 12.在头部删除元素n"; std::cout << "13.遍历反转链表 14.递归反转链表 0.退出" << std::endl; } void LinkListTest() { LinkList list; int index; do { (void)LinkListPrint(); std::cout << "input index to execute" << std::endl; std::cin >> index; switch (index) { case 1: int length; std::cout << "input link list length" << std::endl; std::cin >> length; list.CreatLinkList(length); break; case 2: list.TraceLinkList(); break; case 3: std::cout << "link list length is " << list.GetLength() << std::endl; break; case 4: if (list.IsEmpty() == true) { std::cout << "link list is empty" << std::endl; } else { std::cout << "link list is not empty" << std::endl; } break; case 5: DataType data; std::cout << "input data you want get" << std::endl; std::cin >> data; std::cout << "the data val is " << list.Find(data)->val << std::endl; break; case 6: DataType end_data; std::cout << "add data in the end of link list" << std::endl; std::cin >> end_data; list.InsertElemAtEnd(end_data); break; case 7: DataType index_data; int i; std::cout << "input data" << std::endl; std::cin >> index_data; std::cout << "input index" << std::endl; std::cin >> i; list.InsertElemAtIndex(index_data, i); break; case 8: DataType head_data; std::cout << "inset data at head" << std::endl; std::cin >> head_data; list.InsertElemAtHead(head_data); break; case 9: list.DeleteElemAtEnd(); break; case 10: list.DeleteAll(); break; case 11: DataType delete_data; std::cout << "input data you want to delete" << std::endl; std::cin >> delete_data; list.DeleteElemVal(delete_data); break; case 12: list.DeleteElemAtHead(); break; case 13: list.ReverseLinkList(); break; case 14: list.RecReverseLinkListFun(); default: break; } } while (index != 0); } void TestReverseLinkList() { LinkList list; std::cout << "before reserse link list" << std::endl; list.CreatLinkList(10); list.TraceLinkList(); std::cout << "after reserse link list" << std::endl; list.ReverseLinkList(); list.TraceLinkList(); } int main() { std::cout << "hello lch !!!" << std::endl; (void)LinkListTest(); (void)TestReverseLinkList(); std::cout << "end lch !!!" << std::endl; return 0; }



