#include <iostream>
class MyLinkList
{
public:
struct ListNode
{
// 节点数据域
int val;
// 节点指针域
ListNode *next;
// 有参构造,用于初始化head指针;
ListNode(int val) : val(val), next(nullptr) {}
};
// 无参构造函数,创建head指针
MyLinkList()
{
_size = 0;
_ListHead = new ListNode(0);
}
// 数据域
private:
// 链表尺寸
int _size;
// 链表头节点
ListNode *_ListHead;
public:
// 1. int get(int index) 合法获取链表第index个节点的值
int get(int index)
{
if (index > (_size - 1) || index < 0)
// 1.1 原判断为 if (index > _size || index < 0);
// 当index = 0,size = 0,非法但是跳过判断,
// 该结果不是我们所需要的,更改上述以解决
{
std::cout << "index error ! " << std::endl;
return -1;
}
// 1.2 定义一个中间变量来保存 head 的值,某些操作我们不能直接拿 head 进行操作
// 链表能连续访问重要的是 head 和 尾节点的 next == NULL
ListNode *tmp = _ListHead->next;
// 1.3 访问第 index 个节点 也就是循环 index 次
while (index--)
{
tmp = tmp->next;
}
return tmp->val;
}
// 2. void push_front(int val) 在链表的第一个元素之前增加元素
void push_front(int val)
{
// 2.1 为新元素开辟内存,并调用有参构造函数赋值
ListNode *new_node = new ListNode(val);
// 2.2 接入元素尾指针指向 $原第一个元素$ 头部
new_node->next = _ListHead->next; // _ListHead->next 第一个元素头部
// 2.3 将 head 更改为指向 $现在的$ 第一个元素
_ListHead->next = new_node;
// 2.4 有添加操作一定要更改链表尺寸
_size++;
}
// 3. void push_back(int val) 在链表最后加入元素
void push_back(int val)
{
ListNode *new_node = new ListNode(val);
// 3.1 定义一个中间变量来保存 head 的值,同上 1.2
ListNode *tmp_Head = _ListHead;
// 3.2 该循环是直接循环整个链表,当某节点的 next 指针为 NULL,结束
// 显然只有最后一个节点我们一直让它指向空
while (tmp_Head->next != nullptr)
{
tmp_Head = tmp_Head->next;
}
// 3.3 循环结束 此时 中间变量 head 指向最后一个节点的头部
// 3.4 将原来的最后一个节点的尾指针指向新节点位置
tmp_Head->next = new_node; // 3.5 因为我们使用了有参构造函数,
// 值为val,next为NULL ,否则要宁起一行使 此时最后一个元素 next为NULL
_size++;
}
// 4. void pushList_index(int val,int index) 指定链表节点前加入元素
void pushList_index(int val, int index)
{
if (_size == 0 && index == 0) // 该种情况为特殊(指对于我赋予该函数的功能)
goto here; // 条件满足跳到 here
if (index > _size || index < 0)
{
std::cout << "index error ! " << std::endl;
return;
}
here:
ListNode *new_node = new ListNode(val);
ListNode *tmp_Head = _ListHead;
while (index--)
{
tmp_Head = tmp_Head->next;
}
// 新节点的尾部指向 index节点的头,(tmp_Head->next是某个节点的指针)
new_node->next = tmp_Head->next;
tmp_Head->next = new_node;
_size++;
}
// 5. int size() 获取节点数
int size()
{
int count = 0;
ListNode *tmp_Head = _ListHead;
while (tmp_Head->next != nullptr)
{
tmp_Head = tmp_Head->next;
count++;
}
return count;
}
// 6. bool empty(val) 搜索链表中是否含有val
bool empty(int val)
{
ListNode *tmp_Head = _ListHead;
while (tmp_Head->next != nullptr)
{
if (val == tmp_Head->val)
{
return true;
}
tmp_Head = tmp_Head->next;
}
return false;
}
// 7. int pop_front() 删除链表的第一个元素,并且返回销毁的数值
int pop_front()
{
if (0 == _size)
{
return -1;
}
ListNode *tmp_Head = _ListHead;
_ListHead = _ListHead->next;
int tmp = tmp_Head->next->val;
delete tmp_Head;
tmp_Head = nullptr;
_size--;
return tmp;
}
// 8. int pop_end() 删除链表的最后一个元素,并且返回销毁的数值
int pop_end()
{
if (0 == _size)
{
return -1;
}
ListNode *tmp_Head = _ListHead;
while (tmp_Head->next->next != nullptr)
{
tmp_Head = tmp_Head->next;
}
ListNode *last_Head = tmp_Head->next;
int val = last_Head->val;
delete last_Head;
last_Head->next = nullptr;
tmp_Head->next = nullptr;
_size--;
return val;
}
// 9. int pop_index()指定位置删除链表元素,并且返回销毁的数值
int pop_index(int index)
{
if (index > (_size - 1) || index < 0)
{
return -1;
}
ListNode *tmp_Head = _ListHead;
int val;
if (0 == index)
{
_ListHead = _ListHead->next;
val = tmp_Head->val;
delete tmp_Head;
tmp_Head = nullptr;
}
else
{
while (index--)
{
tmp_Head = tmp_Head->next;
}
ListNode *t = tmp_Head->next;
val = t->val;
tmp_Head->next = tmp_Head->next->next;
delete t;
t = nullptr;
}
_size--;
return val;
}
// 10. void print_list()输出整个链表
void print_list()
{
ListNode *tmp_Head = _ListHead;
int tmp = 0;
if (0 == _size)
{
std::cout << "List NULL " << std::endl;
return;
}
while (tmp_Head->next != nullptr)
{
tmp_Head = tmp_Head->next;
std::cout << "The " << tmp << " : " << tmp_Head->val << ", ";
tmp++;
}
std::cout << std::endl;
}
};
// 1. int get(int index) 合法获取链表第index个节点的值
// 2. void push_front(int val) 在链表的第一个元素之前增加元素
// 3. void push_back(int val) 在链表最后加入元素
// 4. void pushList_index(int val,int index) 指定链表节点前加入元素
// 5. int size() 获取节点数
// 6. bool empty(val) 搜索链表中是否含有val
// 7. int pop_front() 删除链表的第一个元素,并且返回销毁的数值
// 8. int pop_end() 删除链表的最后一个元素,并且返回销毁的数值
// 9. int pop_index()指定位置删除链表元素,并且返回销毁的数值
// 10. void print_list()输出整个链表
int main(int argc, char const *argv[])
{
MyLinkList ob;
std::cout << ob.get(0) << std::endl;
ob.push_front(3); // 3
ob.push_front(6); // 6 3
ob.push_back(4); // 6 3 4
std::cout << ob.get(0) << std::endl;
ob.pushList_index(99, 1); // 6 99 3 4
ob.print_list();
std::cout << ob.size() << std::endl;
std::cout << ob.empty(3) << std::endl; // 1 true
std::cout << ob.empty(100) << std::endl; // 0 false
std::cout << ob.pop_front() << std::endl;
ob.print_list();
std::cout << ob.pop_end() << std::endl;
ob.print_list();
std::cout << ob.pop_index(3) << std::endl;
ob.print_list();
return 0;
}