sentinel->next = sentinel; first = sentinel; // before the first insertion (not shown) Note that the pointer sentinel has always to be kept at the end of the list. This has to be maintained by the insert and delete functions. It is, however, about the same effort as when using a NULL pointer. struct sll_node *SearchWithSentinelnode(struct sll_node *first, int search_key) { struct sll_node *node; // Prepare the “node” Sentinel for the search: sentinel->key = search_key; for (node = first; node->key != search_key; node = node->next) {} // Post-processing: if (node != sentinel) return node; // found // search_key is not contained in the list: return NULL; } The for-loop contains only one test (yellow line) per iteration: node->key != search_key;. Python implementation of a circular doubly-linked list Linked list implementations, especially one of a circular, doubly-linked list, can be simplified remarkably using a sentinel node to demarcate the beginning and end of the list. The list starts out with a single node, the sentinel node which has the next and previous pointers point to itself. This condition determines if the list is empty. In a non-empty list, the sentinel node's next pointer gives the head of the list, and the previous pointer gives the tail of the list. Following is a Python implementation of a circular doubly-linked list: class Node: def __init__(self, data, next=None, prev=None): self.data = data self.next = next self.prev = prev def __repr__(self) -> str: return f'Node(data={self.data})' class LinkedList: def __init__(self): self._sentinel = Node(data=None) self._sentinel.next = self._sentinel self._sentinel.prev = self._sentinel def pop_left(self) -> Node: return self.remove_by_ref(self._sentinel.next) def pop(self) -> Node: return self.remove_by_ref(self._sentinel.prev) def append_nodeleft(self, node): self.add_node(self._sentinel, node) def append_node(self, node): self.add_node(self._sentinel.prev, node) def append_left(self, data): node = Node(data=data) self.append_nodeleft(node) def append(self, data): node = Node(data=data) self.append_node(node) def remove_by_ref(self, node) -> Node: if node is self._sentinel: raise Exception('Can never remove sentinel.') node.prev.next = node.next node.next.prev = node.prev node.prev = None node.next = None return node def add_node(self, curnode, newnode): newnode.next = curnode.next newnode.prev = curnode curnode.next.prev = newnode curnode.next = newnode def search(self, value): self._sentinel.data = value node = self._sentinel.next while node.data != value: node = node.next self._sentinel.data = None if node is self._sentinel: return None return node def __iter__(self): node = self._sentinel.next while node is not self._sentinel: yield node.data node = node.next def reviter(self): node = self._sentinel.prev while node is not self._sentinel: yield node.data node = node.prev Notice how the add_node() method takes the node that will