代码
#include <iostream>
using namespace std;
#include<time.h>
#include<stdlib.h>
//节点类型
struct Node
{
Node(int data = 0)
{
this->data_ = data;
this->next_ = nullptr;
}
int data_;
Node* next_;
};
//单链表代码实现
class Clink
{
public:
Clink()
{
//给 head 初始化指向头结点
this->head_ = new Node();//调用构造函数
}
~Clink()
{
//节点的释放
Node* p = head_;
while (p != nullptr)
{
head_ = head_->next_;
delete p;
p = head_;
}
head_ = nullptr;
}
public:
//尾插 O(n)
void insertTail(int val)
{
//先找到当前链表的末尾节点
Node* p = head_;//p指向头结点
while (p->next_ != nullptr)
{
p = p->next_;
}
//生成新节点
Node* node = new Node(val);
//设置原来尾节点的地址域
p->next_ = node;
}
//头插法 O(1)
void insertHead(int val)
{
//生成新节点
Node* node = new Node(val);
//新节点设置地址域
node->next_ = head_->next_;
//头结点设置地址域
head_->next_ = node;
}
//链表打印
void show()
{
Node* p = head_->next_;//p指向第一个节点
while (p != nullptr)
{
cout << p->data_ << " ";
p = p->next_;
}
cout << endl;
}
//链表节点的删除——按值一个
void remove(int val)
{
Node* q = head_;
Node* p = head_->next_;
while (p != nullptr)
{
if (p->data_ == val)
{
q->next_ = p->next_;
delete p;
return;
}
else
{
q = q->next_;
p = p->next_;
}
}
}
//链表节点的删除——按值多个
void removeAll(int val)
{
Node* q = head_;
Node* p = head_->next_;
while (p != nullptr)
{
if (p->data_ == val)
{
q->next_ = p->next_;
delete p;//释放开辟的堆内存
p = q->next_;//对指针p进行重置
}
else
{
p = p->next_;
q = q->next_;
}
}
}
//搜索 list O(n)
bool find(int val)
{
Node* p = head_->next_;
while (p != nullptr)
{
if (p->data_ == val)
{
return true;
}
p = p->next_;
}
return false;
}
private:
Node* head_;//指向链表的头结点
Node* tail_;//指向链表的尾节点
};
int main()
{
Clink link;
srand(time(0));
for (int i = 0; i < 10; i++)
{
int val = rand() % 100;
link.insertTail(val);
cout << val << " ";
}
cout << endl;
link.insertTail(23);
link.insertHead(23);
link.insertHead(23);
link.show();
link.removeAll(23);
link.show();
}
单链表逆序
//单链表逆序
void reverseLink(Clink& link)
{
Node* head = link.head_;
Node* p = head->next_;
if (p == nullptr)
{
return;
}
head->next_ = nullptr;
while (p != nullptr)
{
Node* q = p->next_;//记录p的下一个元素位置
p->next_ = head->next_;//p的指针域
head->next_ = p;//头结点的指针域
p = q;
}
}
单链表倒数第k个节点
//单链表倒数第k个节点
bool getLastKNode(Clink&link,int k,int&val)
{
Node* p = link.head_;
Node* q = link.head_;
if (k < 1)//有效性判断
{
return false;
}
for (int i = 0; i < k; i++)
{
p = p->next_;//走到第1/2/3/4个节点
if (p == nullptr)
{
return false;
}
}
while (p != nullptr)
{
p = p->next_;
q = q->next_;
}
val = q->data_;
return true;
}
int main()
{
Clink link;
srand((unsigned int)time(0));
for (int i = 0; i < 10; i++)
{
int val = rand() % 100;
link.insertHead(val);
cout << val << " ";
}
cout << endl;
link.show();
reverseLink(link);
link.show();
int val = 0;
int k = 5;
if (getLastKNode(link, k, val))
{
cout << val << endl;
}
else
{
cout << "无" << endl;
}
}
合并两个有序的单链表
//合并两个有序的单链表
void mergeLink(Clink& link1, Clink& link2)
{
Node* p = link1.head_->next_;
Node* q = link2.head_->next_;
Node* last = link1.head_;
link2.head_ = nullptr;
while (p != nullptr && q != nullptr)
{
if (p->data_ < q->data_)
{
last->next_ = p;
p = p->next_;
}
else
{
last->next_ = q;
q = q->next_;
}
last = last->next_;
}
if (p == nullptr)
{
last->next_ = q;
}
else if (q == nullptr)
{
last->next_ = p;
}
}
int main()
{
int arr[] = { 25,37,52,78,88,92,102 };
int brr[] = { 13,23,40,56,89,100 };
Clink link1;
Clink link2;
for (int v : arr)
{
link1.insertTail(v);
}
for (int v : brr)
{
link2.insertTail(v);
}
link1.show();
link2.show();
mergeLink(link1, link2);
link1.show();
};
单链表判断是否有环?求环的入口节点
//单链表判断是否有环?求环的入口节点————快慢指针
bool isLinkHasCircle(Node*head,int &val)
{
Node* fast = head;
Node* slow = head;
while (fast != nullptr && fast->next_ != nullptr)
{
slow = slow->next_;
fast = fast->next_->next_;
if (slow == fast)
{
fast = head;
while (fast != slow)
{
slow = slow->next_;
fast = fast->next_;
}
val = slow->data_;
//快慢指针再次遇见,链表存在环
return true;
}
}
return false;
}
int main()
{
Node head;
Node n1(25), n2(67), n3(32), n4(18);
head.next_ = &n1;
n1.next_ = &n2;
n2.next_ = &n3;
n3.next_ = &n4;
n4.next_ = &n4;
int val = 0;
if (isLinkHasCircle(&head, val))
{
cout << val << endl;
}
else
{
cout << "无" << endl;
}
};
判断两个单链表是否相交,如果相交,返回相交节点的值
//判断两个单链表是否相交,如果相交,返回相交节点的值
bool isLinkHasMerge(Node* head1, Node* head2, int& val)
{
int len1 = 0, len2 = 0;
Node* p = head1;
Node* q = head2;
while (p != nullptr)
{
len1++;
p = p->next_;
}
while (q != nullptr)
{
len2++;
q = q->next_;
}
p = head1, q = head2;
if (len1 > len2)
{
int ans = len1 - len2;
for (int i = 0; i < ans; i++)
{
p = p->next_;
}
}
else
{
int ans = len2 - len1;
for (int i = 0; i < ans; i++)
{
q = q->next_;
}
}
while (p != nullptr)
{
if (p == q)
{
val = p->data_;
return true;
}
p = p->next_;
q = q->next_;
}
return false;
}
int main()
{
Node head1;
Node n1(25), n2(67), n3(32), n4(18);
head1.next_ = &n1;
n1.next_ = &n2;
n2.next_ = &n3;
n3.next_ = &n4;
Node head2;
Node n5(35);
head2.next_ = &n5;
n5.next_ = &n3;
n3.next_ = &n4;
int val = 0;
if (isLinkHasMerge(&head1,&head2,val))
{
cout << val << endl;
}
else
{
cout << "无" << endl;
}
return 0;
};
删除链表倒数第k个节点
bool removeLastKNode(Node* head, int k) {
Node* p = head;
Node* q = head;
if (head == nullptr || k < 1) {
return false;
}
for (int i = 0; i < k; i++) {
p = p->next_;
if (p == nullptr) {
return false;
}
}
while (p->next_ != nullptr) {
p = p->next_;
q = q->next_;
}
Node* temp = q->next_;
q->next_ = q->next_->next_;
return true;
}
int main()
{
Node head;
Node n1(25), n2(67), n3(32), n4(18);
head.next_ = &n1;
n1.next_ = &n2;
n2.next_ = &n3;
n3.next_ = &n4;
n4.next_ = nullptr;
Node* p = head.next_;
while (p != nullptr)
{
cout << p->data_ << " ";
p = p->next_;
}
cout << endl;
if (removeLastKNode(&head, 2))
{
p = head.next_;
while (p != nullptr)
{
cout << p->data_ << " ";
p = p->next_;
}
}
cout << endl;
return 0;
};
旋转链表
Node* func(Node* head, int k)
{
Node* p = head;
//求链表结点的总个数
int num = 0;
//O(n)
while (p->next_ != nullptr)
{
p = p->next_;
num++;
}
num = k % (num+1);//实际移动次数
if (num == 0)//移动次数为0的话,直接退出
{
return head;
}
//O(n)
Node* q = head;
p = head;
for (int i = 0; i < num; i++)
{
p = p->next_;
}
while (p->next_!= nullptr)
{
p = p->next_;//倒数第一个结点
q = q->next_;//倒数第k个结点的前一个结点
}
Node* temp = head->next_;//保存第一个节点位置
head->next_ = q->next_;//头结点连接倒数第k个节点
p->next_ = temp;//原来的尾节点连接原来的第一个节点
q->next_ = nullptr;//q成为尾结点
return head;
}
int main()
{
Node head;
Node n1(1), n2(2), n3(3), n4(4), n5(5);
head.next_ = &n1;
n1.next_ = &n2;
n2.next_ = &n3;
n3.next_ = &n4;
n4.next_ = &n5;
n5.next_ = nullptr;
//旋转前
Node* p = head.next_;
while (p != nullptr)
{
cout << p->data_ << " ";
p = p->next_;
}
cout << endl;
func(&head, 18);
//旋转后
p = head.next_;
while (p != nullptr)
{
cout << p->data_ << " ";
p = p->next_;
}
cout << endl;
return 0;
};