面试算法之链表操作集锦

本文介绍了链表操作在面试中的常见问题,包括单链表的逆序打印、逆置、O(1)时间删除节点、找倒数第k个节点、合并两个排序链表、求第一个公共结点、判断相交、检查环以及求链表中间节点等。通过具体的代码实现解析了这些操作的高效解法。
摘要由CSDN通过智能技术生成

链表操作在面试过程中也是很重要的一部分,因为它和二叉树一样都涉及到大量指针的操作,而且链表本身很灵活,很考查编程功底,所以是很值得考的地方。下面是本文所要用到链表节点的定义:

template <typename Type>
struct ListNode{
    Type data;
    ListNode *next;
};
链表的创建可以采用下面的代码,采用尾插法进行链表的创建,返回的链表没有头节点:

/**
 * Create a list, without head node
 */
template <typename Type>
ListNode<Type> *CreatList(Type *data, int len)
{
	if(data == NULL || len <= 0)
		return NULL;

	ListNode<Type> *head, *last;

	head = new ListNode<Type>;
	last = head;

	for (int i = 0; i < len; ++i)
	{
		last->next = new ListNode<Type>;
		last->next->data = data[i];
		last = last->next;
	}

	last->next = NULL;

	last = head;
	head = head->next;

	delete last;

	return head;
}

1.单链表的逆序打印

单链表的逆序打印就是重表尾开始依次往前打印,直到表头截止,所以可以将链表逆置,然后顺序打印,但这是一种劳民伤财的做法,不仅容易出错,而且还破坏了链表的结构。这里可以采用额外的空间,来保存顺序遍历的节点,在遍历完后,就可以将该辅助空间的值逆序输出,下面是采用stack实现的代码:

/**
 * reversely print the list
 * method 1: use the stack
 */
template <typename Type>
void ReversePrintList_1(const ListNode<Type> *head)
{
	if(head == NULL)
		return;

	stack<Type> nodeStack;
	while (head)
	{
		nodeStack.push(head->data);
		head = head->next;
	}

	while(!nodeStack.empty())
	{
		cout<<nodeStack.top()<<" ";
		nodeStack.pop();
	}
	cout<<endl;
}
我们知道代码中,递归和栈很多时候可以相互转化,而且通过递归实现的代码会更加简洁。下面是通过递归的方式,来实现上面的功能,代码如下:

/**
 * reversely print the list
 * method 2: recursively
 */
template <typename Type>
void ReversePrintList_2(const ListNode<Type> *head)
{
	if(head == NULL)
		return;

	ReversePrintList_2(head->next);
	cout<<head->data<<" ";
}

2.单链表的逆置

在前面单链表的逆序打印中,有一种方法就是把单链表逆置后,再顺序打印。单链表的逆置最高效的方法,

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值