链表常考题

1 单链表逆序,是在原基础上逆序

        最常见的方式新建两个节点分别指向当前node节点的前一个节点和后一个节点,然后将node->next指向前一个节点pre,再将pre节点更改为node,最后将node节点移至next,即完成了对当前node节点的更改。实现代码见下:

void back_list(Node* node)
{
	Node* pre = NULL; // 指向node节点的前一个节点
	Node* next = NULL; //指向node节点的下一个节点
	if(node==NULL) return NULL;
	while(node!=NULL)
	{
		next = node->next;
		node->next = pre;
		pre = node;
		node = next;
	}
}

2 找出单链表中倒数第n个节点

        同样新建两个指针,一个快指针,一个慢指针,让快指针先走n步,然后快慢指针同时每次前进一步,直到快指针前进到null结束。实现代码见下:

Node* backwards_n_list(Node* head,int n)
{
	if(head==NULL) return NULL;
    Node* after = head;
    Node* front = head;
    for(int i=0;i<n;i++)
    {
       if(front->next)
       {
           front=front->next;
       }
       else
       {
           if(i==n-1) return after;
           else return NULL;
       }
    }
    while(front)
    {
       front = front->next;
       after = after->next;
    }
    return after;
}

3 判断单链表中是否有环

        比较简单的做法:新建两个快慢指针,快指针走两步,满指针走一步,若有循环,则快指针必会转过一圈,在此之后,快指针与满指针的距离每次都会减1,当减到0的时候,二者相遇。使用此原理,实现代码如下:

bool is_hoop(Node* head)
{
	Node* after = head;
    Node* front = head;
    while(front!=NULL&& front->next!=NULL)
    {
        front = front->next->next;
        after = after->next;
        if(front == after) return true;
    }
    return false; 
}

4 找出环形单链表中环的入口

        在有环的基础上,有一入环点和相遇点,假设头指针的位置到入环点的距离为a,入环点到相遇点的距离为b,相遇点到入环点的距离为b,慢指针到达相遇点距离为a+b,快指针到达相遇点的距离为a+b+(b+c)k,由于快指针走两步,慢指针走一步,因此快指针走的距离是慢指针的两倍。因此有2(a+b) = a+b+(b+c)k ,即a = c+k(b+c)(k-1),也就是说当两指针到达相遇点时,让慢指针回到头结点位置,此时两者同时以步长为1开始前进,两者再次相遇时候就是入环点。实现代码如下:

Node* hoop_entrance(Node* head) 
{
    // write code here
     Node* after = head;
     Node* front = head;
     while(front && front->next)
     {
        front = front->next->next;
        after = after->next;
        if(front == after) break;
     }
     if(front == NULL||front->next == NULL) return NULL;
     after = head;
     while(after!=front)
     {
        after = after->next;
        front = front->next;
     }
     return front;
}

5 合并两个有序列表(升序),合并后依然有序

不新建链表,只在原有链表基础上修改。

        新建三个新指针,s,n1,n2,s指向链表第一个节点数据较小的那个节点,n1和n2分别指向两个链表的节点,每次比较n1和n2的数据,s每次指向较小的那个,直至n1或n2指向NULL为止。实现代码如下:

Node* merge_Linked_list(Node* head1,Node* head2)
{
	if(head1==NULL||head2==NULL) return NULL;
	if(head1==NULL&&head2!=NULL) return head2;
	if(head1!=NULL&&head2==NULL) return head1;
	Node* n1 = head1;
	Node* n2 = head2;
	Node* s = NULL;
	if(n1->data < n2->data)
	{
		s = n1;
		n1 = n1->next;
	}
	else
	{
		s = n2;
		n2=n2->next;
	}
	
	while(n1&&n2)
	{
		if(n1->data <= n2->data)
		{
			s->next = n1;
			s = n1;
			n1 = n1->next;
		}
		else
		{
			s->next = n2;
			s = n2;
			n2 = n2->next;
		}
	}
	if(n1 == NULL) s->next = n2;
	if(n2 == NULL) s->next = n1;
	if(head1->data < head2->data) return head1;
	else return head2;
}

6 判断两个链表是否是y型链表

        最简单的实现方式:设置两个新指针,分别指向两个链表,让二者开始同时前进,当n1碰到NULL的时候,再让它回到另一个链表的头节点为止前进,n2同理。二者相遇,即y型链表。实现代码如下:

Node* is_yList(Node* head1,Node* head2)
{
    Node *n1 = head1;
    Node *n2 = head2;
        
    while(n1!=n2)
    {
        n1 = (n1 ==NULL ? head2 : n1->next);
        n2 = (n2 ==NULL ? head1 : n2->next);
    }
    return n1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

就酱77叭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值