自己定义一个链表结点结构体
// 单链表
struct ListNode {
int val; // 节点上存储的元素
ListNode *next; // 指向下一个节点的指针
ListNode(int x) : val(x), next(NULL) {} // 节点的构造函数 给val的赋值为x,next的下一个结点指向了空
};
获取第index点的值,我之前的想法是定义一个k。让k++,直到k=index,有一个更简便的方法让index--,让指针移动。
// 获取到第index个节点数值,如果index是非法数值直接返回-1, 注意index是从0开始的,第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;
}
反转链表,定义两个指针,cur和pre,改变cur->next的指向
/**
* 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 *pre;
pre=NULL;//初始化空是因为第一个结点翻转后是最后一个结点,最后一个结点是指向空的
ListNode *temp;
while(head)
{
temp=head->next;
head->next=pre;//翻转
pre=head;//移动
head=temp;
}
return pre;
}
};
相邻2个结点互换(简单的模拟过程)
/**
* 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* swapPairs(ListNode* head) {
ListNode *newnode=new ListNode(0);
newnode->next=head;
ListNode* cur=newnode;
while(cur->next!=NULL&&cur->next->next!=NULL)
{
ListNode* temp=cur->next;
ListNode* temp1=cur->next->next->next;
cur->next=cur->next->next;
cur->next->next=temp;
temp->next=temp1;
cur=cur->next->next;//每次移动2个结点
}
return newnode->next;
}
};
删除倒数第几个指针,双指针经典用法
/**
* 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* removeNthFromEnd(ListNode* head, int n) {
ListNode *first=new ListNode(0);
first->next=head;
ListNode *fast=first;
ListNode *slow=first;
while(n--&&fast!=NULL)
{
fast=fast->next;
}
fast=fast->next;//让fast多走一个,这样slow指向的就是被删除的上一个结点方便操作
while(fast!=NULL)
{
slow=slow->next;
fast=fast->next;
}
ListNode *temp;
temp=slow->next;
slow->next=temp->next;
delete temp;
return first->next;//为什么不返回head 万一头结点被删了呢
}
};
查找2个链表相交的点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *first1=new ListNode(0);
ListNode *first2=new ListNode(0);
first1->next=headA;
first2->next=headB;
ListNode *cur1=first1;
ListNode *cur2=first2;
int a=0;//指向同一个结点 地址相同 要给他赋初值 没赋初值过不了
while(first1->next!=NULL)
{
a++;
first1=first1->next;
}
int b=0;//分别求链表长度 长度之差
while(first2->next!=NULL)
{
b++;
first2=first2->next;
}
if(a>b)
{
int c=a-b;
while(c>0)
{
cur1=cur1->next;
c--;
}
}
else
{
int d=b-a;
while(d>0)
{
cur2=cur2->next;
d--;
}
}/* 判断a,b可以简化的算法
if(a<b)
{
swap(a,b);交换a,b的值 交换之后a就b大了
swap(cur1,cur2);
}
int c=a-b;
while(c--)
{
cur1=cur1->next; 两个链表的指针对齐
}
*/
while(cur1->next!=NULL&&cur2->next!=NULL)
{
if(cur1->next==cur2->next)
{
return cur1->next;
}
cur1=cur1->next;
cur2=cur2->next;
}
return NULL;
}
};
环形链表(快慢指针相遇必有环)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
//判断有环 判断环入口 第一次相遇必在环中
// ListNode *first=new ListNode(0);
// first->next=head; 这几步好像没必要
ListNode *slow=head;
ListNode *fast=head;
while(fast!=NULL&&fast->next!=NULL)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
{
ListNode *cur1=head;
ListNode *cur2=fast;
while(cur1!=cur2)
{
cur1=cur1->next;
cur2=cur2->next;
}
return cur2;
}
//slow=slow->next;放在前面是因为要先让指针移动起来 因为如果不移动都从头结点开始 slow肯定等于fast
//fast=fast->next->next;
}
return NULL;
}
};