I am supposed to count and list the mirror points in the circular doubly linked list. A particular element in the list is a mirror point if traversing the list in the clockwise direction from that element results in the same sequence of values as traversing the list from that element in the anticlockwise direction. All I can do is traverse in forward and backward direction.
void traversal(struct Node* start)
{
struct Node *temp = start;
printf("\nTraversal in forward direction \n");
while (temp->next != start)
{
printf("%d ", temp->data);
temp = temp->next;
}
printf("%d ", temp->data);
printf("\nTraversal in reverse direction \n");
Node *last = start->prev;
temp = last;
while (temp->prev != last)
{
printf("%d ", temp->data);
temp = temp->prev;
}
printf("%d ", temp->data);
}
any idea of how to solve the problem will be appreciated...
You have the ingredients. You should perform both traversals in tandem: use distinct pointers for these traversals, and move them at the same time:
bool traversal(struct Node* start)
{
struct Node *forward = start->next;
struct Node *backward = start->prev;
while (forward != start)
{
if (forward->data != backward->data) {
return false;
}
forward = forward->next;
backward = backward->prev;
}
return true;
}
This will return true when the given node is a mirror point. Remains for you to call this function for each node and count the number of times you get true as a return value...
I am currently trying to formulate a mergeSort mechanism for a singly linked list. Through research and finding consistent ideas about A) a merge sort being the best way to sort a singly linked list, and B) that these are the key components for performing such an operation, I have arrived at this following code. It almost works exactly as intended, but will only return all of the integers larger than the last inputted number. For example, inputting 7, 6, 5, 4, 3, 2, 1 will return 1, 2, 3, 4, 5, 6, 7, but inputting 1, 2, 3, 4, 5 will only return 5. I've used random input orders so it's not a problem localised to just inputting the numbers in reverse order, but literally any order. If a number is smaller than the final number, it gets removed from the list in the sort process. I cannot locate the cause for this at all. My original problem was caused by an errant while loop that was stopping the iterations after one go, so once I removed that the merge sort was working, but for this problem I have just described.
Any and all advice or suggestions are more than welcome, and thanks for any input you have. My knowledge of linked lists and recursion isn't the greatest, so I really welcome all input/constructive criticism here.
public Node mergeSort(Node head) {
if (head == null || head.getNext() == null) return head;
Node midpoint = findMidpoint(head);
Node rightliststart = midpoint.getNext();
midpoint.setNext(null);
Node rightlist = mergeSort(rightliststart);
Node sorted = sort(leftlist, rightlist);
return sorted;
}
public Node findMidpoint(Node head) {
if (head == null) return head;
Node slowpointer = head;
Node fastpointer = slowpointer.getNext();
while (fastpointer != null) {
fastpointer = fastpointer.getNext();
if (fastpointer != null) {
slowpointer = slowpointer.getNext();
fastpointer = fastpointer.getNext();
}
}
return slowpointer;
}
public Node sort(Node one, Node two) {
Node temp = null;
if (one == null) return two;
if (two == null) return one;
if (one.getData() <= two.getData()) {
temp = one;
temp.setNext(sort(one.getNext(), two));
} else {
temp = two;
temp.setNext(sort(one, two.getNext()));
}
return temp;
}
Example merge code. This shows how the dummy node is used to simplify the code (avoids special case to update head on first node merged).
// merge two already sorted lists
static Node merge(Node list0, Node list1) {
if(list0 == null)
return list1;
if(list1 == null)
return list0;
Node temp = new Node(); // dummy node
Node dest = temp;
while(true){
if(list0.data <= list1.data){
dest.next = list0;
dest = list0;
list0 = list0.next;
if(list0 == null){
dest.next = list1;
break;
}
} else {
dest.next = list1;
dest = list1;
list1 = list1.next;
if(list1 == null){
dest.next = list0;
break;
}
}
}
return temp.next;
}
Example top down merge sort code. It scans the list one time to get the size of the list to avoid double scanning (fast, slow), only scanning n/2 nodes for each recursive split.
// return size of list
static int size(Node head) {
int i = 0;
while(head != null){
head = head.next;
i++;
}
return i;
}
// advance to node n
static Node advance(Node head, int n) {
while(0 < n--)
head = head.next;
return head;
}
// top down merge sort for single link list entry function
static Node sorttd(Node head) {
int n = size(head);
if(n < 2)
return head;
head = sorttdr(head, n);
return head;
}
// top down merge sort for single link list recursive function
static Node sorttdr(Node head, int n) {
if(n < 2)
return head;
int n2 = (n/2);
Node node = advance(head, n2-1);
Node next = node.next;
node.next = null;
head = sorttdr(head, n2);
next = sorttdr(next, n-n2);
head = merge(head, next);
return head;
}
Example bottom up merge sort code. It uses a small (32) array of lists, where array[i] is a list with 0 (empty slot) or 2^i nodes. array[{0 1 2 3 4 ...}] = sorted sub-lists with 0 or {1 2 4 8 16 ...} nodes. Nodes are merged into the array one at a time. A working list is created via a sequence of merge steps with a caller's list node and the leading non-empty slots in the array. The size of the working list doubles with each merge step. After each non-empty slot is used to merge into the working list, that slot is set to empty. After each sequence of merge steps is done, the first empty slot after the leading non-empty slots is set to the working list. A prior slots will now be empty. Once all nodes are merged into the array, the array is merged into a single sorted list. On a large list that doesn't fit in cache, and with randomly scattered nodes, there will be a lot of cache misses for each node accessed, in which case bottom up merge sort is about 30% faster than top down.
// bottom up merge sort for single link list
static Node sortbu(Node head) {
final int NUMLIST = 32;
Node[] alist = new Node[NUMLIST];
Node node;
Node next;
int i;
// if < 2 nodes, return
if(head == null || head.next == null)
return null;
node = head;
// merge node into array
while(node != null){
next = node.next;
node.next = null;
for(i = 0; (i < NUMLIST) && (alist[i] != null); i++){
node = merge(alist[i], node);
alist[i] = null;
}
if(i == NUMLIST) // don't go past end of array
i--;
alist[i] = node;
node = next;
}
// node == null
// merge array into single list
for(i = 0; i < NUMLIST; i++)
node = merge(alist[i], node);
return node;
}
Given a pointer to a linked list, I'm trying to reverse a linked using iteration(not recursive approach) in java. This is my code snippet.
Node reverse(Node head)
{
Node cur = head.next;
Node prev = head;
Node nxt;
while(cur!=null){
nxt = cur.next;
cur.next = prev;
prev = cur;
cur = nxt;
}
return prev;
}
But when I run it it gives error-"Time Limit Exceeded". So, there might be an infinite loop somewhere but I can't figure out where. Any help will be appreciated. Thank you.
You have not set next pointer of head node to null. firstnode.next is still pointing to the second node of given linkedlist which resulted in infinite looping.
Node cur = head.next;
Node prev = head;
prev.next = null; // add this
Can anyone suggest an algorithm to convert a Binary Search Tree to a singly linked list.
Also note that at each step of conversion the highest values node in the list should point to the smallest valued node in the list.
if(!tree.isEmpty())
{
Node node1 = tree.removeMin();
Node node2;
Node currentNode;
Node temp;
if(!tree.isEmpty())
{
node2 = tree.removeMax();
node2.setNext(node1);
currentNode = node2;
while(!tree.isEmpty())
{
temp = tree.removeMin();
temp.setNext(currentNode);
currentNode = temp;
}
}
Node head = temp;
}
This conforms to a singly linked list and the maximum value in the list always points to the least value in the list. No other qualifications were given.
public static LinkedListNode<Integer> constructLinkedList(BinaryTreeNode<Integer> root) {
if(root == null)
return null;
LinkedListNode<Integer> newHead = constructLinkedList(root.left);
LinkedListNode<Integer> temp = newHead;
if(newHead == null)
newHead = new LinkedListNode<>(root.data);
else
{
while(temp != null && temp.next != null)
{
temp = temp.next;
}
temp.next = new LinkedListNode<>(root.data);
}
LinkedListNode<Integer> rightHead = constructLinkedList(root.right);
if(newHead.next == null)
newHead.next = rightHead;
else
temp.next.next = rightHead;
return newHead;
}
Given a problem to insert a new node within a sorted linked list in the correct position, I have come up with the following solution.
void SortedInsert(node** headref, node* newnode) {
node* prev = NULL;
node* curr = *headref;
for (; curr; ) {
if (curr->info > newnode->info) {
break;
}
prev = curr;
curr = curr->next;
}
if (!prev) {
newnode->next = *headref;
*headref = newnode;
} else {
newnode->next = prev->next;
prev->next = newnode;
}
}
Does this work.
Are there any edge cases this does not work for. Is there a simpler solution.
Instead of making curr point to the node before which you want to insert, make curr point to the pointer that points to the node before which you want to insert.