用于从线段链接列表中删除中间点的 C++ 程序
给定一个坐标链表,其中相邻点形成垂直线或水平线。从链表中删除位于水平或垂直线中间的点。
例子:
Input: (0,10)->(1,10)->(5,10)->(7,10)
|
(7,5)->(20,5)->(40,5)
Output: Linked List should be changed to following
(0,10)->(7,10)
|
(7,5)->(40,5)
The given linked list represents a horizontal line from (0,10)
to (7, 10) followed by a vertical line from (7, 10) to (7, 5),
followed by a horizontal line from (7, 5) to (40, 5).
Input: (2,3)->(4,3)->(6,3)->(10,3)->(12,3)
Output: Linked List should be changed to following
(2,3)->(12,3)
There is only one vertical line, so all middle points are removed.
来源:微软面试体验
这个想法是跟踪当前节点、下一个节点和下一个下一个节点。当下一个节点与下一个节点相同时,继续删除下一个节点。在这个完整的过程中,我们需要密切关注指针的移动并检查 NULL 值。
以下是上述想法的实现。
C++
// C++ program to remove intermediate points
// in a linked list that represents horizontal
// and vertical line segments
#include
using namespace std;
// Node has 3 fields including x, y
// coordinates and a pointer
// to next node
class Node
{
public:
int x, y;
Node *next;
};
/* Function to insert a node
at the beginning */
void push(Node ** head_ref,
int x,int y)
{
Node* new_node =new Node();
new_node->x = x;
new_node->y = y;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
/* Utility function to print
a singly linked list */
void printList(Node *head)
{
Node *temp = head;
while (temp != NULL)
{
cout << "(" << temp->x <<
"," << temp->y << ")-> ";
temp = temp->next;
}
cout << endl;
}
// Utility function to remove Next
// from linked list and link nodes
// after it to head
void deleteNode(Node *head,
Node *Next)
{
head->next = Next->next;
Next->next = NULL;
free(Next);
}
// This function deletes middle nodes
// in a sequence of horizontal and
// vertical line segments represented
// by linked list.
Node* deleteMiddle(Node *head)
{
// If only one node or no node...
// Return back
if (head == NULL ||
head->next == NULL ||
head->next->next == NULL)
return head;
Node* Next = head->next;
Node *NextNext = Next->next ;
// Check if this is a vertical line
// or horizontal line
if (head->x == Next->x)
{
// Find middle nodes with same x
// value, and delete them
while (NextNext != NULL &&
Next->x == NextNext->x)
{
deleteNode(head, Next);
// Update Next and NextNext
// for next iteration
Next = NextNext;
NextNext = NextNext->next;
}
}
// If horizontal line
else if (head->y == Next->y)
{
// Find middle nodes with same y
// value, and delete them
while (NextNext != NULL &&
Next->y == NextNext->y)
{
deleteNode(head, Next);
// Update Next and NextNext for
// next iteration
Next = NextNext;
NextNext = NextNext->next;
}
}
// Adjacent points must have either
// same x or same y
else
{
puts("Given linked list is not valid");
return NULL;
}
// Recur for next segment
deleteMiddle(head->next);
return head;
}
// Driver code
int main()
{
Node *head = NULL;
push(&head, 40,5);
push(&head, 20,5);
push(&head, 10,5);
push(&head, 10,8);
push(&head, 10,10);
push(&head, 3,10);
push(&head, 1,10);
push(&head, 0,10);
cout << "Given Linked List: ";
printList(head);
if (deleteMiddle(head) != NULL);
{
cout << "Modified Linked List: ";
printList(head);
}
return 0;
}
// This is code is contributed by rathbhupendra
输出:
Given Linked List:
(0,10)-> (1,10)-> (3,10)-> (10,10)-> (10,8)-> (10,5)-> (20,5)-> (40,5)->
Modified Linked List:
(0,10)-> (10,10)-> (10,5)-> (40,5)->
上述解决方案的时间复杂度为 O(n),其中 n 是给定链表中的节点数。
锻炼:
上面的代码是递归的,针对同样的问题写一个迭代代码。请参阅下面的解决方案。
删除线段链表中点的迭代方法
请参阅完整的文章给定线段的链表,删除中间点以获取更多详细信息!