链表的典型题:找到链表倒数K个节点、链表逆转、合并两个链表

三个链表面试题目综合:找到链表倒数K个节点、链表逆转、合并两个链表。

#include <iostream>
using namespace std;

typedef struct linklist{
	linklist *link;
	int val;
}*listPoint;
//按节点值升序插入链表
void insertNode(listPoint &head,int val)
{
	linklist *pre,*current;
	pre=NULL;
	current=head;
	while (current!=NULL&&val>current->val)
	{
		pre=current;
		current=current->link;
	}
	linklist *newNode=new linklist;
	if (newNode==NULL)
	{
		cout<<"memory errors \n";
	}
	newNode->val=val;
	newNode->link=current;
	if (pre==NULL)
	{
		head=newNode;
	}
	else
		pre->link=newNode;
}
//这个函数最重要是注意边界条件,防止程序崩溃!
linklist *FindKthFromNail(linklist *head,int k)
{
	if (head==NULL||k<=0)
	{
		cout<<" 链表不符合条件 \n";
		return NULL;
	}
	linklist *ahead,*behind;
	ahead=behind=head;
	int i;
	/*
	最终情况是需要让ahead指向链表尾节点,然后此时behind则指向倒数K个节点
	ahead 与behind 相差K-1个距离。如果ahead 提前K-1走碰到NULL ,意味着链表节点数不够K个返回。
	*/
	for (i=0;i<k-1;i++)
	{
		if (ahead->link!=NULL)
		{
			ahead=ahead->link;
		}	
		else
		{
			return NULL;
		}
	}
	while (ahead->link!=NULL)
	{
		ahead=ahead->link;
		behind=behind->link;
	}
	return behind;
}
//实现链表反转
linklist * reverseList(linklist *head)
{
	linklist *pre=NULL,*current,*next;
	current=head;
	for (;current!=NULL;current=next)
	{
		next=current->link;
		current->link=pre;
		pre=current;
	}
	return pre;
}
void printList(linklist *head)
{
	if (head==NULL)
	{
		cout<<"empty linklist \n";
	}
	while (head!=NULL)
	{
		cout<<head->val<<" ";
		head=head->link;
	}
	cout<<endl;
}
//合并两个升序链表,返回头结点位置。递归可以很简单实习功能
linklist * mergeLinklist(linklist *head1,linklist *head2)
{
	/*
	合并时特别考虑代码健壮性,如果链表为NULL情况处理
	*/
	if (head1==NULL)
	{
		return head2;
	}
	else if (head2==NULL)
	{
		return head1;
	}
	linklist *Pmerge=NULL;
	if (head1->val<head2->val)
	{
		Pmerge=head1;
		Pmerge->link=mergeLinklist(head1->link,head2);
	}
	else
	{
		Pmerge=head2;
		Pmerge->link=mergeLinklist(head1,head2->link);
	}

	return Pmerge;
}
int main()
{
	int a[]={1,2,5,8,4,3};
	int b[]={6,7,9,10,12,11,14,13};
	int i;
	linklist *head1=NULL;
	linklist *head2=NULL;
	for (i=0;i<6;i++)
	{
		insertNode(head1,a[i]);	
	}
	for (i=0;i<8;i++)
	{
		insertNode(head2,b[i]);
	}
	printList(mergeLinklist(head1,head2));
}


题目及算法思想来源于剑指offer,感谢作者对代码健壮性的讲解。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值