Reversing the direction of links in a singly linked circular list

You can reverse the direction of links in the circular list. If you do so, each link should be reversed.

# include <stdio.h>
# include <stdlib.h>
struct node {
	int data;
	struct node *link;
};
/* A function to reverse a singly linked circular list */
struct node *reverselist(struct node *p) {
	struct node *temp;
	struct node *prev = NULL;
	struct node *curr;
	if (p != NULL) {
		curr = p;
		temp = curr;
		while (curr->link != p) {
			curr = curr->link;
			temp->link = prev;
			prev = temp;
			temp = curr;
		}
		temp->link = prev;
		p->link = temp;
		p = temp;
	}
	return (p);
}

struct node *insert(struct node *p, int n) {
	struct node *temp;
	/* if the existing list is empty then insert a new node as the
	 starting node */
	if (p == NULL) {
		p = (struct node *) malloc(sizeof(struct node)); /* creates new node
		 data value passes
		 as parameter */

		if (p == NULL) {
			printf("Error\n");
			exit(0);
		}
		p->data = n;
		p->link = p; /* makes the pointer point to itself because it is
		 a circular list*/
	} else {
		temp = p;
		/* traverses the existing list to get the pointer to the last node of
		 it */
		while (temp->link != p)
			temp = temp->link;
		temp->link = (struct node *) malloc(sizeof(struct node)); /*
		 creates new node using
		 data value passes as
		 parameter and puts its
		 address in the link field
		 of last node of the
		 existing list*/
		if (temp->link == NULL) {
			printf("Error\n");
			exit(0);
		}
		temp = temp->link;
		temp->data = n;
		temp->link = p;
	}
	return (p);
}
void printlist(struct node *p) {
	struct node *temp;
	temp = p;
	printf("The data values in the list are\n");
	if (p != NULL) {
		do {
			printf("%d\t", temp->data);
			temp = temp->link;
		} while (temp != p);
	} else
		printf("The list is empty\n");
}
int main() {
	int n;
	int x;
	struct node *start = NULL;
	struct node *start1 = NULL;
	/* this will create at circular list */
	printf("Enter the number of nodes in the list \n");
	scanf("%d", &n);
	while (n-- > 0) {
		printf("Enter the data value to be placed in a node\n");
		scanf("%d", &x);
		start = insert(start, x);
	}
	printf("The list is\n");
	printlist(start);
	start1 = reverselist(start);
	printf("The reversed list is:\n");
	printlist(start1);
	getchar();
	return 0;
}

To reverse the links of a singly linked circular list, the list is required to be traversed from the start node until a node is encountered whose link points to the start node (that is, the last node in the list). For this, it is required to maintain the pointers to the current node and the previous node. An additional temporary pointer pointing to the current node is also required to be maintained. Initially, the current, temporary, and previous pointers are set as follows:

  1. Set the current as well as the temporary pointer to the start pointer.
  2. Set the previous pointer to NULL.
  3. The pointers are manipulated in each iteration as follows:
    1. Advance the current pointer to make it point to the next node.
    2. Set the link field of the node pointed to by the temporary pointer to the value of the previous pointer.
    3. Make the previous pointer point to the node pointed to by the temporary pointer.
    4. Make the temporary pointer point to the node pointed to by the current pointer.
    5. When the last node is encountered, its link field is made to point to the previous node. After that, the link field of the node pointed to by the start pointer (first node) is made to point to this last node. And the start pointer is made to point to this last node.

These manipulations are shown in the following diagrams.