1反转单链表
#include<iostream>
using namespace std;
class node{
public:
int value;
node *next;
node(int data):value(data),next(NULL){};
};
node *reverseLinkedList(node *head)//返回node*的原因:链表反转后原先的头结点已经不是
//现在的头结点
{
node *pre=NULL;
node *next=NULL;
while(head!=NULL)
{
next=head->next;
head->next=pre;
pre=head;
head=next;
}
return pre;
}
2反转双链表
#include<iostream>
using namespace std;
class doublenode{
public:
int value;
doublenode *last;
doublenode *next;
doublenode(int data):value(),last(NULL),next(NULL){}
};
doublenode* reverseDoubleList(doublenode *head)
{
doublenode *pre=NULL;
doublenode *next=NULL;
while(head!=NULL)
{
next=head->next;
head->next=pre;
head->last=next;
pre=head;
head=next;
}
return pre;
}
3单链表实现栈和队列
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
template <typename V>
class Node {
public:
V value;
Node<V>* next;
Node(V v) : value(v), next(nullptr) {}
};
template <typename V>//用链表实现队列
class MyQueue {
private:
Node<V>* head;
Node<V>* tail;
int size;
public:
MyQueue() : head(nullptr), tail(nullptr), size(0) {}//初始时均指向空
bool isEmpty() {
return size == 0;
}
int getSize() {
return size;
}
void offer(V value){//向尾部添加一个元素
Node<V>* cur = new Node<V>(value);
if (tail == nullptr) {
head = cur;
tail = cur;
} else {
tail->next = cur;
tail = cur;
}
size++;
}
V poll() {//移除头部元素
V ans;
if (head != nullptr) {
ans = head->value;
Node<V>* next = head->next;
delete head;
head = next;
size--;
if (head == nullptr) {
tail = nullptr;
}
}
return ans;
}
V peek() {//获取队头元素
return head != nullptr ? head->value : NULL;
}
};
template <typename V>
class MyStack {
private:
Node<V>* head;
int size;
public:
MyStack() : head(nullptr), size(0) {}
bool isEmpty() {
return size == 0;
}
int getSize() {
return size;
}
void push(V value) {
Node<V>* cur = new Node<V>(value);
if (head == nullptr) {
head = cur;
} else {
cur->next = head;
head = cur;
}
size++;
}
V pop() {
V ans;
if (head != nullptr) {
ans = head->value;
Node<V>* next = head->next;
delete head;
head = next;
size--;
}
return ans;
}
V peek() {
return head != nullptr ? head->value : NULL;
}
};
4用双链表实现双端队列
#include <iostream>
#include <deque>
#include <cstdlib>
template<typename V>
class Node {
public:
V value;
Node<V>* last;
Node<V>* next;
Node(V v) : value(v), last(nullptr), next(nullptr) {}
};
template<typename V>
class MyDeque {
private:
Node<V>* head;
Node<V>* tail;
int size;
public:
MyDeque() : head(nullptr), tail(nullptr), size(0) {}
bool isEmpty() {
return size == 0;
}
int getSize() {
return size;
}
void pushHead(V value) {//头部加入一个元素
Node<V>* cur = new Node<V>(value);
if (head == nullptr) {
head = cur;
tail = cur;
} else {
cur->next = head;
head->last = cur;
head = cur;
}
size++;
}
void pushTail(V value) {//尾部插入一个元素
Node<V>* cur = new Node<V>(value);
if (head == nullptr) {
head = cur;
tail = cur;
} else {
tail->next = cur;
cur->last = tail;
tail = cur;
}
size++;
}
V pollHead() {//获取头部元素并删除
V ans = V();
if (head == nullptr) {
return ans;
}
size--;
ans = head->value;
if (head == tail) {
delete head;
head = nullptr;
tail = nullptr;
} else {
Node<V>* temp = head;
head = head->next;
head->last = nullptr;
delete temp;
}
return ans;
}
V pollTail() {//获取尾部元素并删除
V ans = V();
if (head == nullptr) {
return ans;
}
size--;
ans = tail->value;
if (head == tail) {
delete tail;
head = nullptr;
tail = nullptr;
} else {
Node<V>* temp = tail;
tail = tail->last;
tail->next = nullptr;
delete temp;
}
return ans;
}
V peekHead() {
V ans = V();
if (head != nullptr) {
ans = head->value;
}
return ans;
}
V peekTail() {
V ans = V();
if (tail != nullptr) {
ans = tail->value;
}
return ans;
}
~MyDeque() {
while (head != nullptr) {
Node<V>* temp = head;
head = head->next;
delete temp;
}
}
};
5 K个节点的组内逆序调整问题:
给定一个单链表的头节点head,和一个正数k
实现k个节点的小组内部逆序,如果最后一组不够k个就不调整
例子:
调整前:1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8,k = 3
调整后:3 -> 2 -> 1 -> 6 -> 5 -> 4 -> 7 -> 8
#include<iostream>
struct ListNode{
int val;
ListNode* next;
ListNode(int x):val(x),next(NULL){}
};
ListNode* getKGroupEnd(ListNode* start, int k)//往后移动k个元素找到每个k组的尾巴
{
while(--k!=0&&start!=NULL)//移动k下且当不够k组时退出
{
start=start->next;
}
return start;
}
void reverse(ListNode* start, ListNode* end)//反转某个片段链表
{
end=end->next;//e下一个指针也得调整所以e要往下移动一位
ListNode* pre = NULL;
ListNode* cur = start;
ListNode* next = NULL;
while (cur != end) {
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
start->next=end;//最后头部的要指到end
}
ListNode* reverseKGroup(ListNode* head, int k)//第一组和后面组反转不一样
//第一组的end反转完后没有前指针,但后面的需要调整前指针
{
ListNode* start=head;
ListNode* end=getKGroupEnd(start,k);
if(end==NULL)//一组都凑不够
{
return head;
}
head=end;//head往后移动
reverse(start,end);
ListNode* lastEnd=start;//保存上一个的末尾节点以接到下一个k组
while (lastEnd->next != nullptr) {
start = lastEnd->next;
end = getKGroupEnd(start, k);
if (end == nullptr) {
return head;
}
reverse(start, end);
lastEnd->next = end;
lastEnd = start;
}
return head;
}
6 两个链表相加问题
给定两个链表的头节点head1和head2,
认为从左到右是某个数字从低位到高位,返回相加之后的链表
例子 4 -> 3 -> 6 2 -> 5 -> 3
返回 6 -> 8 -> 9
解释 634 + 352 = 986
#include <iostream>
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
int listLength(ListNode* head)//先求出链表长度分出长短链表
{
int len=0;
while(head!=NULL)
{
len++;
head=head->next;
}
return len;
}
ListNode* addTwoNumbers(ListNode* head1, ListNode* head2)
{
int len1=listLength(head1);
int len2=listLength(head2);
ListNode *l=len1>=len2?head1:head2;//长链表的头部,最后要返回长链表头
ListNode *s=l==head1?head2:head1;//转到另一个链表头部
ListNode *curL=l;
ListNode *curS=s;
ListNode *last=curL;//最后如果有进位1就补上
int carry=0;//进位数
int curNum=0;
while(curS!=NULL)//先把短链表跑完
{
curNum=curL->val+curS->val+carry;
curL->val=curNum%10;
carry=curNum/10;
last=curL;
curL=curL->next;
curS=curS->next;
}
while(curL!=NULL)
{
curNum=curL->val+carry;
curL->val=curNum%10;
carry=curNum/10;
last=curL;
curL=curL->next;
}
if(carry!=0)
last->next=new ListNode(1);
return l;
}
7 两个有序链表的合并
给定两个有序链表的头节点head1和head2,
返回合并之后的大链表,要求依然有序
例子 1 -> 3 -> 3 -> 5 -> 7 2 -> 2 -> 3 -> 3-> 7
返回 1 -> 2 -> 2 -> 3 -> 3 -> 3 -> 3 -> 5 -> 7
#include <iostream>
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* mergeTwoLists(ListNode* head1, ListNode* head2)
{
if(head1==NULL||head2==NULL)//两个之内有空链表
return head1==NULL?head2:head1;
ListNode *head=head1->val<=head2->val?head1:head2;//去小头链表的头
ListNode *cur1=head->next;
ListNode *cur2=head==head1?head2:head1;
ListNode *pre=head;
while(cur1!=NULL&&cur2!=NULL)
{
if(cur1->val<=cur2->val)
{
pre->next=cur1;
cur1=cur1->next;
}
else
{
pre->next=cur2;
cur2=cur2->next;
}
pre=pre->next;
}
pre->next=cur1!=NULL?cur1:cur2;//把没结束的链表补到后面
return head;
}