链表
头结点和首结点的区别:
"头结点"和"首结点"是链表中两个相关但有区别的概念。
1. **头结点(Head Node):**
- **含义:** 头结点是一个附加在链表前面的额外节点。这个节点并不包含实际的数据,而是用于简化链表的操作。
- **作用:** 头结点的引入可以使得链表中的第一个真正的节点称为首结点(包含实际数据的第一个节点),同时头结点也可以包含一些链表的其他信息。头结点的引入有时候可以简化一些操作,例如插入和删除节点的情况,因为头结点使得链表的第一个节点不需要特殊处理。
2. **首结点(First Node):**
- **含义:** 首结点是链表中的第一个包含数据的节点。它是链表的起始点,是第一个存储实际数据的节点。
- **作用:** 在一些不使用头结点的链表实现中,首结点也被称为链表的头部(Head)。首结点是链表的开头,通过它可以访问链表的其他节点。
在一些实现中,头结点和首结点可能同时存在,而在其他实现中可能只有其中之一。头结点的使用取决于具体的设计和需求。在某些情况下,头结点可能不包含数据,仅用于标识链表的起始位置和其他属性。在其他情况下,头结点可能包含一些额外的信息或者与首结点相同。
解法一,考虑头结点
//删除链表中指定元素
//定义名为Solution的类
class Solution{
public:
//定义名为removeElements 的成员函数,用于删除链表中所有值为val的结点
ListNode* removeElements(ListNode* head, int val)
{
//删除头结点
//循环检查链表头部是否有值为val的结点,有的话就删除
while(head != NULL && head->val == val)
{
ListNode* temp = head; // 创建一个临时指针temp, 指向头结点
head = head->next; // 将head->next设置为头指针
delete temp; // 释放原头结点的内存
}
//删除非头结点
ListNode* cur= head; // 创建一个指针cur, 指向头指针
while(cur != NULL && cur->next != NULL)
{
if(cur->next->val == val) //如果结点值等于val,则删除该结点
{
ListNode* temp = cur->next; // 创建一个临时指针temp,指向需要删除的结点
cur->next = cur->next->next; // 移动指针
delete temp;
}
else
{
cur = cur->next; // 如果当前结点不需要删除,则将指针移动到下一个结点
}
}
return head; // 返回处理后的链表头
}
}
解法二:设计虚拟结点
class Solution
{
public:
// 定义名为removeElements 的成员函数,用于删除链表中的所有值为val的节点
ListNode* removeElements(ListNode* head, int val)
{
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* cur = dummyHead;
while (cur->next != NULL)
{
if(cur->next->val == val)
{
ListNode* temp = cur->next;
cur->next=cur->next->next;
delete temp;
}
else
{
cur->cur->next;
}
}
// 更新head指针,使其指向删除操作后的链表头部
head = dummyHead->next;
delete dummyHead;
return head;
}
}
class MyLinkedList {
public:
// 定义链表结构体
struct LinkedNode{
int val;
LinkedNode* next;
LinkedNode(int val):val(val),next(nullptr){}
//LinkedNode(int val)这是构造函数声明,接收参数val
// val(val),next(nullptr)成员初始化列表,将参数val值传递给结点的成员变量,nullptr是c++中表示空指针的特殊关键字
};
// 初始化链表
MyLinkedList() {
_dummyHead = new LinkedNode(0); // 定义头结点,是一个虚拟头结点
_size = 0;
}
// 获取到第index个结点数值,index从0开始
int get(int index) {
if(index >(_size-1) || index<0){
return -1;
}
LinkedNode* cur = _dummyHead->next;
while(index--){//如果--index就会陷入死循环
cur = cur->next;
}
return cur->val;
}
// 插入头结点
void addAtHead(int val) {
LinkedNode* newnode = new LinkedNode(val); //将值结点化
newnode->next = _dummyHead->next;
_dummyHead->next = newnode;
_size++;
}
//链表尾部插入结点
void addAtTail(int val) {
LinkedNode* newnode = new LinkedNode(val);
LinkedNode* cur = _dummyHead;
while(cur->next != nullptr){
cur = cur->next;
}
cur->next = newnode;
_size++;
}
//在链表指定位置插入值
void addAtIndex(int index, int val) {
if(index>_size) return;//
if(index<0) index=0;
LinkedNode* newnode = new LinkedNode(val);
LinkedNode* cur = _dummyHead;
while(index--){
cur=cur->next;
}
newnode->next=cur->next;
cur->next = newnode;
_size++;
}
//删除指定位置结点
void deleteAtIndex(int index) {
if (index >= _size || index<0){
return;
}
LinkedNode* cur = _dummyHead;
while(index--){
cur = cur->next;
}
LinkedNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
tmp = nullptr;
_size--;
}
private: int _size;
LinkedNode* _dummyHead;
};
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList* obj = new MyLinkedList();
* int param_1 = obj->get(index);
* obj->addAtHead(val);
* obj->addAtTail(val);
* obj->addAtIndex(index,val);
* obj->deleteAtIndex(index);
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val)
{
ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点
dummyHead ->next = head; // 虚拟头结点指向head
ListNode* cur = dummyHead;
while (cur->next !=NULL)
{
if(cur->next->val==val)
{
ListNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
}
else{
cur=cur->next;
}
}
head = dummyHead->next;
delete dummyHead;
return head;
}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* temp;// 保存cur的下一个结点
ListNode* cur = head;
ListNode* pre = NULL;
while(cur){
temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
return pre;
}
};
先这样写着,一会儿再补