在上一篇文章中,我们讨论了如何在每个节点的地址字段中仅使用一个空格来创建双向链接。在这篇文章中,我们将讨论内存高效的双向链表的实现。我们将主要讨论以下两个简单功能。
- 在开始处插入新节点的函数。
- 向前遍历列表的函数。
在下面的代码中, insert()函数在开始处插入一个新节点。我们需要更改“链表”的头指针,这就是为什么要使用双指针的原因(请参阅此)。让我们首先再讨论上一篇文章中讨论过的几件事。我们将下一个节点和上一个节点的XOR与每个节点存储在一起,我们将其称为npx,这是每个节点唯一的地址成员。当我们在开始处插入新节点时,新节点的npx将始终为NULL与当前头的XOR。并且必须将当前磁头的npx更改为新节点与当前磁头旁边的节点的XOR。
printList()向前遍历列表。它从每个节点打印数据值。要遍历列表,我们需要在每个点都获得指向下一个节点的指针。我们可以通过跟踪当前节点和上一个节点来获取下一个节点的地址。如果对curr-> npx和prev进行XOR,我们将获得下一个节点的地址。
C++
/* C++ Implementation of Memory
efficient Doubly Linked List */
#include
#include
using namespace std;
// Node structure of a memory
// efficient doubly linked list
class Node
{
public:
int data;
Node* npx; /* XOR of next and previous node */
};
/* returns XORed value of the node addresses */
Node* XOR (Node *a, Node *b)
{
return reinterpret_cast(
reinterpret_cast(a) ^
reinterpret_cast(b));
}
/* Insert a node at the beginning of the
XORed linked list and makes the newly
inserted node as head */
void insert(Node **head_ref, int data)
{
// Allocate memory for new node
Node *new_node = new Node();
new_node->data = data;
/* Since new node is being inserted at the
beginning, npx of new node will always be
XOR of current head and NULL */
new_node->npx = *head_ref;
/* If linked list is not empty, then npx of
current head node will be XOR of new node
and node next to current head */
if (*head_ref != NULL)
{
// *(head_ref)->npx is XOR of NULL and next.
// So if we do XOR of it with NULL, we get next
(*head_ref)->npx = XOR(new_node, (*head_ref)->npx);
}
// Change head
*head_ref = new_node;
}
// prints contents of doubly linked
// list in forward direction
void printList (Node *head)
{
Node *curr = head;
Node *prev = NULL;
Node *next;
cout << "Following are the nodes of Linked List: \n";
while (curr != NULL)
{
// print current node
cout<data<<" ";
// get address of next node: curr->npx is
// next^prev, so curr->npx^prev will be
// next^prev^prev which is next
next = XOR (prev, curr->npx);
// update prev and curr for next iteration
prev = curr;
curr = next;
}
}
// Driver code
int main ()
{
/* Create following Doubly Linked List
head-->40<-->30<-->20<-->10 */
Node *head = NULL;
insert(&head, 10);
insert(&head, 20);
insert(&head, 30);
insert(&head, 40);
// print the created list
printList (head);
return (0);
}
// This code is contributed by rathbhupendra
C
/* C Implementation of Memory
efficient Doubly Linked List */
#include
#include
#include
// Node structure of a memory
// efficient doubly linked list
struct Node
{
int data;
struct Node* npx; /* XOR of next and previous node */
};
/* returns XORed value of the node addresses */
struct Node* XOR (struct Node *a, struct Node *b)
{
return (struct Node*) ((uintptr_t) (a) ^ (uintptr_t) (b));
}
/* Insert a node at the beginning of the
XORed linked list and makes the newly
inserted node as head */
void insert(struct Node **head_ref, int data)
{
// Allocate memory for new node
struct Node *new_node = (struct Node *) malloc (sizeof (struct Node) );
new_node->data = data;
/* Since new node is being inserted at the
beginning, npx of new node will always be
XOR of current head and NULL */
new_node->npx = *head_ref;
/* If linked list is not empty, then npx of
current head node will be XOR of new node
and node next to current head */
if (*head_ref != NULL)
{
// *(head_ref)->npx is XOR of NULL and next.
// So if we do XOR of it with NULL, we get next
(*head_ref)->npx = XOR(new_node, (*head_ref)->npx);
}
// Change head
*head_ref = new_node;
}
// prints contents of doubly linked
// list in forward direction
void printList (struct Node *head)
{
struct Node *curr = head;
struct Node *prev = NULL;
struct Node *next;
printf ("Following are the nodes of Linked List: \n");
while (curr != NULL)
{
// print current node
printf ("%d ", curr->data);
// get address of next node: curr->npx is
// next^prev, so curr->npx^prev will be
// next^prev^prev which is next
next = XOR (prev, curr->npx);
// update prev and curr for next iteration
prev = curr;
curr = next;
}
}
// Driver program to test above functions
int main ()
{
/* Create following Doubly Linked List
head-->40<-->30<-->20<-->10 */
struct Node *head = NULL;
insert(&head, 10);
insert(&head, 20);
insert(&head, 30);
insert(&head, 40);
// print the created list
printList (head);
return (0);
}
Python3
# Python3 implementation of Memory
# efficient Doubly Linked List
# library for providing C
# compatible data types
import ctypes
# Node class for memory
# efficient doubly linked list
class Node:
def __init__(self, data):
self.data = data
# XOR of next and previous node
self.npx = 0
class XorLinkedList:
def __init__(self):
self.head = None
self.__nodes = []
# Returns XORed value of the node addresses
def XOR(self, a, b):
return a ^ b
# Insert a node at the beginning of the
# XORed linked list and makes the newly
# inserted node as head
def insert(self, data):
# New node
node = Node(data)
# Since new node is being inserted at
# the beginning, npx of new node will
# always be XOR of current head and NULL
node.npx = id(self.head)
# If linked list is not empty, then
# npx of current head node will be
# XOR of new node and node next to
# current head
if self.head is not None:
# head.npx is XOR of None and next.
# So if we do XOR of it with None,
# we get next
self.head.npx = self.XOR(id(node),
self.head.npx)
self.__nodes.append(node)
# Change head
self.head = node
# Prints contents of doubly linked
# list in forward direction
def printList(self):
if self.head != None:
prev_id = 0
curr = self.head
next_id = 1
print("Following are the nodes "
"of Linked List:")
while curr is not None:
# Print current node
print(curr.data, end = ' ')
# Get address of next node: curr.npx is
# next^prev, so curr.npx^prev will be
# next^prev^prev which is next
next_id = self.XOR(prev_id, curr.npx)
# Update prev and curr for next iteration
prev_id = id(curr)
curr = self.__type_cast(next_id)
# Method to return a new instance of type
# which points to the same memory block.
def __type_cast(self, id):
return ctypes.cast(id, ctypes.py_object).value
# Driver code
if __name__ == '__main__':
obj = XorLinkedList()
# Create following Doubly Linked List
# head-->40<-->30<-->20<-->10
obj.insert(10)
obj.insert(20)
obj.insert(30)
obj.insert(40)
# Print the created list
obj.printList()
# This code is contributed by MuskanKalra1
输出
Following are the nodes of Linked List:
40 30 20 10