轻松搞定面试中的链表问题:
1.链表的建立、输出链表.
2.链表的节点的个数
3.查找链表中第n个元素
4.删除节点
5.链表的逆转
6.使用递归的方法逆转链表
7.使用递归的方法从头到尾输出链表
8.使用stack方法输出链表,这种方法是逆序输出的,stack后进先出
9.使用两个指针移动的方法查找倒数第n个元素,我这里下标是从0算起
10.递归方法合并两个有序的链表,超简单
11.判断两个链表是否有环:思路两个指针,一次移动中一个指针移动一步,另一个指针移动两边,每次移动判断两个这两个节点指针是否相同。
12.判断两个链表是否相交:如果两个list相交,那么最后一个节点必然相同。
13. 求两个单链表相交的第一个节点
对第一个链表遍历,计算长度len1,同时保存最后一个节点的地址。
对第二个链表遍历,计算长度len2,同时检查最后一个节点是否和第一个链表的最后一个节点相同,若不相同,不相交,结束。
两个链表均从头节点开始,假设len1大于len2,那么将第一个链表先遍历len1-len2个节点,此时两个链表当前节点到第一个相交节点的距离就相等了,然后一起向后遍历,直到两个节点的地址相同。
一、创建单链表、打印链表
#include
using namespace std;
class list_node
{
public:
int data;
list_node *next;
};
// creat a forward list:创建一个单链表
list_node* creat_list()
{
list_node *head = nullptr;
list_node *p1 = new list_node;
list_node *p2 = new list_node;
cin >> p1->data;
p1->next = NULL;
while (p1->data > 0)
{
if (head == nullptr)
{
head = p1;
}
p2->next = p1;
p2 = p1;
p1 = new list_node;
cin >> p1->data;
p1->next = NULL;
}
delete p1;
return head;
}
/*
the second way let the list's sequence is opposite to input.
这种方法建立的单链表顺序和输入的顺序相反。
*/
list_node *creat_list2()
{
list_node *head = nullptr;
//list_node *p = new list_node;
list_node *p = new list_node;
std::cin >> p->data;
while (p->data > 0)
{
p->next = head;
head = p;
p = new list_node;
cin >> p->data;
}
return head;
}
//output the forward_list:输出单链表
void print_list(list_node *head)
{
if (head == NULL)
{
std::cout << "the list is empty" << std::endl;
}
else
{
while (head != NULL)
{
cout << head->data << " ";
head = head->next;
}
cout << std::endl;
}
}
int main()
{
list_node *head=NULL;
head = creat_list2();
print_list(head);
return 0;
}
二、链表中节点的个数
//The number of nodes in the chain table
int list_num(list_node*head)
{
int num = 0;
if (head == nullptr)
cout << "the is empty" << endl;
while (head != nullptr)
{
head = head->next;
num++;
}
return num;
}
//get the element of the list
int get_element(list_node *head, int n)
{
int i = 0;
while (head!=nullptr)
{
i++;
if (i == n)
break;
head = head->next;
}
return head->data;
}
//remove node of list
list_node *remove_node(list_node*head, int key)
{
list_node *p1, *p2=nullptr;
p1 = head;
while (key != p1->data&&p1->next != nullptr)
{
p2 = p1;//保存被删除节点的前一个节点
p1 = p1->next;
}
if (p1 == head)
head = head->next;
else
p2->next = p1->next;
return head;
}
五、逆转单链表
//reverse the list
list_node*reverse_list(list_node *head)
{
list_node*p1;
list_node*p2;
list_node*p3;
if (!head||!head->next)
return head;
p1 = head;
p2 = head->next;
p3 = head->next->next;
p1->next = NULL;
while (p3)
{
p2->next = p1;
p1 = p2;
p2 = p3;
p3 = p3->next;
}
p2->next = p1;
head = p2;
return head;
}
六、递归逆转链表
//print the list use recursion
list_node* digui_list(list_node*node)
{
if (node->next == NULL)
return node;
list_node*p1 = node;
list_node*p2 = node->next;
node = digui_list(p2);
p2->next = p1;
p1->next = NULL;
return node;
}
void recursion_print(list_node*head)
{
if (head == NULL)
return ;
else
{
recursion_print(head->next);
cout << head->data<<" ";
}
}
8.使用stack的方法逆序输出list
//using stack to print the list and the sequence is opposite.
void stack_print(list_node*head)
{
std::stack tmp;
list_node*p1 =NULL;
if (head == NULL)
return;
while (head != NULL)
{
tmp.push(head);
head = head->next;
}
while (!tmp.empty())
{
p1 = tmp.top();
cout << p1->data << " ";
tmp.pop();
}
cout << endl;
}
//search element form the bottom
int search_element(list_node*head,int n)
{
list_node*p1 = head;
list_node*p2 = head;
//if (head == nullptr)
// return;
int size = 0;
list_node*p = head;
while (p)
{
p = p->next;
size++;
}
for (int i = 0; i < size; i++)
{
if (i<=n)
p2 = p2->next;
else
{
p1 = p1->next;
p2 = p2->next;
}
}
return p1->data;
}
//merger two ordered list
list_node*merger_list(list_node*p1, list_node*p2)
{
if (p1 == nullptr)
return p2;
if (p2 == nullptr)
return p1;
list_node*merger = nullptr;
if (p1->data < p2->data)
{
merger = p1;
p1->next = merger_list(p1->next, p2);
}
else
{
merger = p2;
p2->next = merger_list(p1, p2->next);
}
return merger;
}
13. 求两个单链表相交的第一个节点
list_node* find_first_common_node(list_node * p1, list_node * p2)
{
if (p1 == NULL || p2 == NULL)
return NULL;
int len1 = 1;
list_node * pTail1 = p1;
while (pTail1->next != NULL)
{
pTail1 = pTail1->next;
len1++;
}
int len2 = 1;
list_node * pTail2 = p2;
while (pTail2->next != NULL)
{
pTail2 = pTail2->next;
len2++;
}
if (pTail1 != pTail2) // 不相交直接返回NULL
return NULL;
list_node * pNode1 = p1;
list_node * pNode2 = p2;
// 先对齐两个链表的当前结点,使之到尾节点的距离相等
if (len1 > len2)
{
int k = len1 - len2;
while (k--)
pNode1 = pNode1->next;
}
else
{
int k = len2 - len1;
while (k--)
pNode2 = pNode2->next;
}
while (pNode1 != pNode2)
{
pNode1 = pNode1->next;
pNode2 = pNode2->next;
}
return pNode1;
}