[英]how to merge two sorted linked lists?
This is an interview question, but I don't if there's a best solution for it. 这是一个面试问题,但我没有最佳解决方案。
Question: Write a function (in C# or C++) to merge two already sorted linked lists. 问题:编写一个函数(用C#或C ++)合并两个已经排序的链表。 Given a data structure: C++:
给定一个数据结构:C ++:
class Node
{
public:
int data;
Node* next;
};
C#: C#:
class Node
{
public int data;
public Node next;
};
Implement the function: In C++: 实现函数:在C ++中:
Node* Merge (Node* head1, Node* head2)
{
…
}
In C#: 在C#中:
Node Merge (Node head1, Node head2)
{
…
}
It takes in two already sorted linked lists (in ascendant order) and is supposed to merge them into a single sorted linked list (in ascendant order) and returns the new head. 它接收两个已经排序的链表(升序),并应该将它们合并为一个排序的链表(升序)并返回新的头。 The 2 lists might have nodes with identical data (the int value).
2个列表的节点可能具有相同的数据(int值)。 We expect the result list doesn't have identical data.
我们希望结果列表中没有相同的数据。
My solution: 我的解决方案:
Node Merge(Node head1, Node head2)
{
Node merged = head1;
// Both lists are empty
if (head1 == null && head2 == null)
{
return null;
}
// List 1 is empty
else if (head1 == null && head2 != null)
{
return head2;
}
// List 2 is empty
else if (head2 == null && head1 != null)
{
return head1;
}
// Both lists are not empty
else
{
Node cursor1 = head1;
Node cursor2 = head2;
if (cursor1.next.data > cursor2.data)
{
Node temp = cursor1;
cursor1 = cursor2;
cursor2 = temp;
}
// Add all elements from list 2 to list 1
while (cursor1.next != null && cursor2 != null)
{
if (cursor1.next.data < cursor2.data)
{
cursor1 = cursor1.next;
}
else
{
Node temp1 = cursor1.next;
Node temp2 = cursor2.next;
cursor1.next = cursor2;
cursor2.next = temp1;
cursor1 = cursor1.next;
cursor2 = temp2;
}
}
if (cursor1.next == null)
{
cursor1.next = cursor2;
}
}
// Remove duplicates
head1 = merged;
while (head1.next != null)
{
if (head1.data < head1.next.data)
{
head1 = head1.next;
}
else if (head1.data == head1.next.data)
{
head1.next = head1.next.next;
}
}
return merged;
}
Please give some comments and let me know your smart and good solution. 请提出一些意见,并让我知道您的明智和好的解决方案。 Thank you!
谢谢!
After making sure that I was allowed to use the framework that goes with C#, this is what I would have done. 在确保允许我使用C#附带的框架之后,这就是我要做的。
Given this linked list class (same as yours but using properties) 给定此链接列表类(与您的类相同,但使用属性)
class Node
{
public int Data { get; set; }
public Node Next { get; set; }
}
Create an IEnumerator for the list 为列表创建一个IEnumerator
class NodeEnumerator : IEnumerator<int>
{
private Node _current_node;
public NodeEnumerator(Node first) {
_current_node = new Node { Data = 0, Next = first };
}
public int Current {
get { return _current_node.Data; }
}
object IEnumerator.Current {
get { return Current; }
}
public bool MoveNext() {
if (_current_node == null) {
return false;
}
_current_node = _current_node.Next;
return _current_node != null;
}
public void Reset() {
throw new NotSupportedException();
}
public void Dispose() {
}
}
Create the corresponding IEnumerable 创建相应的IEnumerable
class EnumerableNode : IEnumerable<int>
{
private Node _first;
public EnumerableNode(Node first) {
_first = first;
}
public IEnumerator<int> GetEnumerator() {
return new NodeEnumerator(_first);
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
Then use the awesome functions available to me in exchange for this little effort, namely Concat
and Distinct
然后使用我提供的强大功能来换取这点小小的努力,即
Concat
和Distinct
class Program
{
static void Main(string[] args) {
var list1 = new EnumerableNode(
new Node { Data = 1, Next =
new Node { Data = 2, Next =
new Node { Data = 3, Next = null }}});
var list2 = new EnumerableNode(
new Node { Data = 2, Next =
new Node { Data = 3, Next =
new Node { Data = 4, Next = null }}});
var merged = list1.Concat(list2).Distinct();
Console.WriteLine(String.Join(",", list1));
Console.WriteLine(String.Join(",", list2));
Console.WriteLine(String.Join(",", merged));
Console.ReadLine();
}
}
Output 产量
1,2,3
2,3,4
1,2,3,4
The interviewer was probably looking for algorithmics (like your solution), but I think this is more life-like, more elegant, and still shows problem-solving skills, as well as knowledge of the framework and the general concept of enumerators. 面试官可能正在寻找算法(例如您的解决方案),但是我认为这更逼真,更优雅,并且仍然显示出解决问题的能力,以及对框架的了解和枚举器的一般概念。 It works exactly the same in Java, Python and Ruby (and many others I'm sure).
它在Java,Python和Ruby(以及其他许多我确定的)中的工作原理完全相同。 I have no idea how it would translate to C++ though.
我不知道它将如何转换为C ++。
You might wanna check out how std::merge is implemented: 您可能想看看std :: merge是如何实现的:
http://www.cplusplus.com/reference/algorithm/merge/ http://www.cplusplus.com/reference/algorithm/merge/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.