C++单链表with实现反转链表
单链表的实现(c++版)
最近写了一下剑指offer的链表题,但是刷题发现都是只写核心函数部分,发现不方便自己测试学习,就整合一下单链表的题目写成类的成员函数,顺带复习一下数据结构,弱鸡求大家指点(记录学习)。
单链表相关知识
个人认为还是要搞清楚单链表的头指针、头结点、首元节点之间的区别,因为有时候在看他人代码的时候有的人实现是用了头结点,有的没有用,所以有时候会理解不到,总是懵懵懂懂。
参考:个人认为介绍的很不错的博客
代码实现部分可以参考:单链表基础实现版,可以看出来这个是使用了头结点的
另外,很多初学者对指针可能不是特别熟悉的话,会对 ListNode * p = head,之后大部分操作就是对p这个临时指针操作来处理链表不是特别理解。实际上,将head的地址赋予该类的新指针p,此时p的地址与head的地址一样,对p操作就是对head操作(个人认为是可以是保持head不被修改)。
emmmm,大概先这样,想到什么再加,话不多说,上我自己修改的代码。
我的实现Part!
目前基于参考博客只加了打印单链表,反转链表部分,也是带头结点的版本,待续…
#include <iostream>
using namespace std;
//定义结构体
struct ListNode{
int val;
ListNode* next;
};
class LinkList
{
public:
LinkList(); //构建一个单链表;
~LinkList(); //销毁一个单链表;
void CreateLinkList(int n); //创建一个单链表
void TravalLinkList(); //遍历线性表
int GetLength(); //获取线性表长度
bool IsEmpty(); //判断单链表是否为空
int * Find(int data); //查找节点
void InsertElemAtEnd(int data); //在尾部插入指定的元素
void InsertElemAtIndex(int data, int n); //在指定位置插入指定元素
void InsertElemAtHead(int data); //在头部插入指定元素
void DeleteElemAtEnd(); //在尾部删除元素
void DeleteAll(); //删除所有数据
void DeleteElemAtPoint(int data); //删除指定的数据
void DeleteElemAtHead(); //在头部删除节点
void print(); //打印链表
void reverse(); //反转链表
ListNode* head; //头结点
};
LinkList::LinkList() {
head = new ListNode;
head->val = 0; //将头结点的数据域定义为0
head->next = NULL; //头结点的下一个定义为NULL
}
//销毁单链表
LinkList::~LinkList()
{
delete head; //删除头结点
}
void LinkList::CreateLinkList(int n) {
ListNode* pnew, *ptemp;
ptemp = head;
if (n < 0) { //当输入的值有误时,处理异常
cout << "输入结点个数有误";
exit(EXIT_FAILURE);
}
for (int i = 0; i < n; i++) //将值一个一个插入单链表中
{
pnew = new ListNode;
cout << "请输入第" << i + 1 << "个值:";
cin >> pnew->val;
pnew->next = NULL; //新节点的下一个地址为NULL
ptemp->next = pnew; //当前结点的下一个地址设为新节点
ptemp = pnew; // 将当前结点设为新节点
}
}
void LinkList::print() {
ListNode* p;
p = head->next;
while (p != NULL) {
cout << p->val<< " ";
p = p->next;
}
cout << endl;
}
int LinkList::GetLength(){
int count = 0;
ListNode *p = head->next;
while (p != NULL) {
count++;
p = p->next;
}
return count;
}
void LinkList::reverse() {
if (head->next == NULL || head->next->next == NULL) /*链表为空或只有一个元素则直接返回*/
return;
ListNode *t = NULL;
ListNode *p = head->next;
ListNode *q = head->next->next;
while (q != NULL) {
t = q->next;
q->next = p;
p = q;
q = t;
}
head->next->next = NULL;
head->next = p;
}
int main()
{
LinkList l;
int n;
cout << "请输入单链表的长度: ";
cin >> n;
l.CreateLinkList(n);
cout << "单链表的长度: " << l.GetLength() << endl;
l.print();
l.reverse() ;
l.print();
return 0;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件