链表的基本操作都写在下面了
具体内容写在代码注释中了
#include <stack>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
struct ListNode
{
int val;
struct ListNode * next;
};
///增,传进来要增加尾的链表的表头
///可利用这个函数来建立链表
void create(ListNode** head, int val)
{
ListNode * new_node = new ListNode();
new_node->val = val;
new_node->next = nullptr;
if(*head==nullptr)
{
*head = new_node;
}
else
{
ListNode * phead = *head;
while(phead->next!=nullptr)
{
phead = phead->next;
}
phead->next = new_node;
}
return ;
}
///删,删掉链表中第一个值为val的节点
void delete_node(ListNode** head, int val)
{
if(head==nullptr||*head==nullptr)
return ;
ListNode* phead = *head;
if(phead->val==val)
{
*head = (*head)->next;
}
else
{
while(phead->next!=nullptr)
{
if(phead->next->val==val)
break;
phead = phead->next;
}
if(phead->next!=nullptr&&phead->next->val==val)
{
phead->next = phead->next->next;
}
}
return ;
}
///注意代码的鲁棒性,异常处理啊!!!!记住了呀
///倒数第k个节点,相当于只遍历一遍链表
ListNode * find_kth_tail(ListNode * head, int k)
{
if(k==0||head==nullptr)
return nullptr;
ListNode * quick = head;
ListNode * slow = head;
for(int i=1; i<k; i++)
{
quick = quick->next;
if(quick==nullptr)
return nullptr;
}
while(quick->next!=nullptr)
{
quick = quick->next;
slow = slow->next;
}
return slow;
}
///倒着打印链表,利用栈的特性,不建议用递归写,容易爆栈
void reverse_ListNode_print(ListNode * head)
{
stack<int>s;
while(!s.empty())
s.pop();
ListNode * phead = head;
while(phead!=nullptr)
{
s.push(phead->val);
phead = phead->next;
}
while(!s.empty())
{
printf("%d\n",s.top());
s.pop();
}
}
///利用快慢指针判断链表是否存在环
///原理:慢指针每次走一步,快指针每次走两步
///初始状态都处于链表头,同时出发,如果快指针走到表尾
///两个指针还没有相遇则证明没有环存在,如果相遇则存在环
///可类比于环形跑道
ListNode * check_ring(ListNode * head)
{
if(head==nullptr)
return nullptr;
ListNode * quick = head;
ListNode * slow = head;
while(quick->next!=nullptr)
{
if(quick->next->next!=nullptr)
quick = quick->next->next;
else
break;
if(slow->next!=nullptr)
slow = slow->next;
else
break;
if(slow->val==quick->val)
return slow;
}
return nullptr;
}
///计算环的长度
int len_of_ring(ListNode* start)
{
if(start==nullptr)
return 0;
int len = 1;
ListNode * tmp = start->next;
while(tmp!=nullptr&&tmp!=start)
{
len++;
tmp = tmp->next;
}
return len;
}
///寻找链表入口
ListNode* enter_of_ring(ListNode* head)
{
if(head==nullptr)
return nullptr;
ListNode* start = check_ring(head);
if(start==nullptr)
return nullptr;
int len = len_of_ring(start);
ListNode* quick = head;
ListNode* slow = head;
for(int i=0; i<len; i++)
quick = quick->next;
while(quick!=slow)
{
quick = quick->next;
slow = slow->next;
}
return slow;
}
///反转整个链表,返回值为反转后的表头
ListNode* reverse_list(ListNode* head)
{
if(head==nullptr)
return nullptr;
if(head->next==nullptr)
return head;
ListNode* pre = nullptr;
ListNode* now = head;
ListNode* next = nullptr;
while(now!=nullptr)
{
next = now->next;
now->next = pre;
pre = now;
now = next;
}
return pre;
}
///反转相邻元素,返回值为反转后的表头
ListNode* reverse_adjacent_element(ListNode* head)
{
if(head==nullptr)
return nullptr;
if(head->next==nullptr)
return head;
ListNode* pre = nullptr;
ListNode* now = head;
ListNode* next = head->next;
ListNode* ans = next;
while(next!=nullptr)
{
/// 1->2->3->4
///pre now next;
if(pre!=nullptr)
pre->next = next;
now->next = next->next;
next->next = now;
pre = now;
if(pre==nullptr)
break;
now = pre->next;
if(now==nullptr)
break;
next = now->next;
}
return ans;
}
///合并两个有序链表,返回值为合并后的链表头
ListNode* merge_list(ListNode* head1, ListNode* head2)
{
if(head1==nullptr)
return head2;
if(head2==nullptr)
return head1;
ListNode* ans = new ListNode();
ListNode* res = ans;
while(head1!=nullptr&&head2!=nullptr)
{
if(head1->val<head2->val)
{
ans->next = head1;
ans = ans->next;
head1 = head1->next;
}
else
{
ans->next = head2;
ans = ans->next;
head2 = head2->next;
}
}
while(head1!=nullptr)
{
ans->next = head1;
ans = ans->next;
head1 = head1->next;
}
while(head2!=nullptr)
{
ans->next = head2;
ans = ans->next;
head2 = head2->next;
}
ans = nullptr;
return res->next;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
ListNode * head = nullptr;
for(int i=0; i<n; i++)
{
int val;
scanf("%d",&val);
create(&head,val);
}
ListNode* head2 = nullptr;
for(int i=2; i<8; i++)
create(&head2,i);
reverse_ListNode_print(head);
//delete_node(&head,2);
ListNode * tmp = find_kth_tail(head,2);
if(tmp!=nullptr)
printf("%d\n",tmp->val);
// head = reverse_adjacent_element(head);
// while(head!=nullptr)
// {
// printf("%d\n",head->val);
// head = head->next;
// }
printf("---------\n");
head = merge_list(head,head2);
while(head!=nullptr)
{
printf("%d\n",head->val);
head = head->next;
}
}
return 0;
}