User-defined Data structures in PythonUser-defined data structures are not inbuilt in Python, but we can still implement them. We can use the existing functional options in Python to create new data structures. For example, when we say a list = [], Python recognizes it as a list and calls everything related to a list. But when we say a linked list or a queue, Python won't know what these are. In this article, we will discuss some user-defined data structures in Python: 1. Linked ListsA linked list, like its name suggests, is linked. Every node in the linked list consists of two segments- the data field with the data/ value and the next field holding the reference to the next node, thus linking together. It is a linear data structure, but the elements are not stored in contiguous memory locations. Important points about Linked lists:
Further, linked lists are of three types:
A simple linked list looks like this:As shown in the above figure, the head is the first node, and the next (reference) part of the last node holds None. A double-linked list looks like this:In a double-linked list, every node will have three sections. Head holds the reference of the first node, the "previous" section of the first node holds None, and the next field of the last node refers to None. Each node will hold two references along with the data, one to its previous node and the next to the succeeding node. Circular linked list:A circular linked list can be single or double: Circular single linked list: It is a single linked list, but the last node in the list holds the reference of the first node like a circle. Circular double-linked list: It is a double-linked list, but the last node in the list holds the reference of the first node, and the 'previous' section of the first node holds the reference of the last node like a circle. Example Program:Output: Displaying the linked list: 10 -> 20 -> 30 -> None Traversing from node to node: 10 20 30 After inserting 5 at the beginning: 5 -> 10 -> 20 -> 30 -> None After inserting 40 at the end: 5 -> 10 -> 20 -> 30 -> 40 -> None After inserting a node after 15: 5 -> 10 -> 15 -> 20 -> 30 -> 40 -> None After inserting a node before 30: 5 -> 10 -> 15 -> 20 -> 25 -> 30 -> 40 -> None 2. StackStack is a linear data structure. It is implemented on the principle "LIFO" abbreviation: Last in, first out. It means that the element that is last inserted into a stack will be the first one that gets deleted. A stack only has one opening, which means to insert or delete elements; we need to use the same end. When we insert elements into a stack, we insert elements on top of each other-new elements on the existing element. After inserting all the elements, if we want to delete elements from the stack, the last element inserted will be the first to come out. Terminologies:
Functions in Python for stacks:Implementation of a stack:We can implement a stack:
Output: The elements of the stack 1 2 3 The first element to come out: 3 The second element to come out: 2 Final stack: [1]
Output: Stack without pushing any elements: head None Stack after pushing elements: head 14 13 12 11 10 None After pop 3 times: 14 13 12 Stack: head 11 10 None Element at the top of the stack: 11 Pop till stack becomes empty: 11 10 Traceback (most recent call last): File "D:\Programs\DSA \Language\Python data structures programs\stacks.py", line 59, in We wrote two methods push and pop, to implement a stack. We need to make sure of two points:
3. QueuesA queue is a linear data structure like a stack, but the principle of queue implementation is FIFO-First in, first out. It means that the first element inserted into the queue will be the first element to come out of the queue. Important points about a queue:
Terminology:
We can implement a queue in Python:
Output: Using lists: Queue: [] Inserting elements: Queue: [1, 2, 3, 4, 5] Deleting two elements: Final queue: [3, 4, 5] Using the deque class in the collection module Inserting elements: Queue: deque([6, 7, 8, 9, 10]) Deleting elements: Final queue: deque([8, 9, 10]) Using the Queue class in the queue module Inserting elements: Queue: 0 1 2 3 4 5 Is the queue full? True Deleting elements: Final queue: [2, 3, 4, 5] size of the queue: 4
There can be a scenario of high-priority situations where irrespective of the order, we must take care of some aspects first. For such situations, there is a type of queue: Priority Queue. Difference between Queue and Priority Queue
Implementation:Output: Created Q: 3 2 19 90 11 Dequeue operation: The element to be deleted: 90 Final Queue: 2 3 11 19 4. Binary TreeA tree is a hierarchical representation of nodes. Family trees are real-time examples of a tree. Every node is allowed to have only two children. The node at the highest hierarchy or the top-most node is called the "Root node". Important points about Binary tree:
Output: Preorder traversal: 4 3 2 3 5 Postorder traversal: 2 3 3 5 4 Inorder traversal: 2 3 3 4 5 BFS traversal: 4 3 5 2 3
Here is an example BST: 5. GraphsIn short form, G = (V, E). Here V represents vertices, and E represents edges. A graph is a non-linear Data structure. It consists of nodes/ vertices joined/ connected by edges. Both vertices and edges have to be a finite set. An edge can be represented as (u, v) given u and v are the two vertices the edge connects. A graph can be directed or undirected. In an undirected graph, E = (u, v) and E = (v, u) are the same, while in a directed graph, they are not the same as the directed matters. Hence, edges are represented as ordered pairs of vertices the edge joins. Important points about graphs:
Adjacency matrix: An adjacency matrix is a (V X V) 2D array where V represents the vertices in the graph. In the matrix, adj[u][v], if in the graph, there exists an edge between u and v, adj[u][v] = 1, else 0 is assigned.
Here is the representation: Here is a very simple code of adjacency matrix implementation for the graph: Output: 0 3 0 12 4 3 0 5 0 0 0 5 0 0 2 12 0 0 0 7 4 0 2 7 0 Adjacency list: To implement an adjacency list, we use an array/ list of linked lists to represent the vertices and edges in the graph. The number of linked lists used in the representation equals the number of vertices in the graph.
Here is the representation:
Here is a simple code with an adjacency list representation of a graph:Output: 0: -> 2 -> 1 1: -> 4 -> 2 -> 3 -> 0 2: -> 4 -> 1 -> 0 3: -> 4 -> 1 4: -> 2 -> 3 -> 1 Understanding:A list of the size number of vertices in the graph is created with all None values: [None, None, None, None, None] Now, when an edge(source, destination) call is made: Using the class node, a destination node is created, and its next is pointed to the source in the array, and then the linked list is assigned to the source position in the array. When edge(0, 1) is called: [1 -> None, 0 -> None, None, None, None] edge(0, 2): [2 -> 1 -> None, 0 -> None, 0 -> None, None, None] edge(1, 3): [2 -> 1 -> None, 3 -> 0 -> None, 0 -> None, 1 -> None, None] This way, all the adjacent nodes are attached to the linked lists in the array. Next TopicFind the Number that Appears Once |