9.5 KiB
title | localeTitle |
---|---|
Data Structure Linked List | 数据结构链表 |
就像用花朵制作的花环一样,链表由节点组成。我们称这个特殊花环上的每朵花都是一个节点。并且每个节点指向该列表中的下一个节点以及它具有数据(这里是花的类型)。
类型
- 单链表
单链表包含具有data
字段和next
字段的节点,该字段指向序列中的下一个节点。可以在单链表上执行的操作是插入,删除和遍历。
`
Singly Link List
head
|
|
+-----+--+ +-----+--+ +-----+------+
| 1 |o-----> | 2 |o-----> | 3 | NULL |
+-----+--+ +-----+--+ +-----+------+
`
应用
CPython的内部实现,框架和评估变量保存在堆栈中。
为此我们需要迭代前向aur得到头部,因此单独使用链表。
- 双重链表
双向链表包含具有data
字段的节点, next
字段和指向序列中前一节点的另一个链接字段prev
。
`
双重链表
head
|
|
+------+-----+--+ +--+-----+--+ +-----+------+
| | |o------> | |o------> | | |
| NULL | 1 | | 2 | | 3 | NULL |
| | | <------o| | <------o| | |
+------+-----+--+ +--+-----+--+ +-----+------+
`
应用
浏览器缓存,允许您点击BACK和FORWARD按钮。在这里,我们需要维护一个双向链表, URLs
作为数据字段,以允许双向访问。要转到上一个URL,我们将使用prev
字段,并转到下一页,我们将使用next
字段。
- 循环链表
循环链表是单链表,其中最后一个节点, next
字段指向序列中的第一个节点。
`
循环链表
head
|
|
+-----+--+ +-----+--+ +-----+--+
- > | 1 | o -----> | 2 | o -----> | 3 | o ----
| + ----- + - + + ----- + - + + ----- + - + |
| |
`
应用
分时问题由操作系统解决。
在分时环境中,操作系统必须维护当前用户的列表,并且必须允许每个用户一次使用一小部分CPU时间,一个用户。操作系统将选择一个用户,让他/她使用少量的CPU时间,然后转到下一个用户。
对于这个应用程序,应该没有NULL指针,除非绝对没有人请求CPU时间,即列表为空。
基本操作
- 插入
要向列表中添加新元素。
`
插入开头
- 使用给定数据创建新节点。
- 将新节点指向旧
head
next
。 - 点
head
到这个新的节点。
插入中间/结尾
在节点X之后插入。
- 使用给定数据创建新节点。
- 指向新节点的
next
老X的next
。 - 点X在此新节点
next
。
`
时间复杂度:O(1)
- 删除
从列表中删除现有元素。
`
删除开头
- 获取
head
指向的节点为Temp。 - 点
head
到温度的next
。 - Temp节点使用的可用内存。
在中间/结尾删除
节点X后删除。
- 获取
X
指向的节点为Temp。 - 点X
next
着Temp的next
。 - Temp节点使用的可用内存。
`
时间复杂度:O(1)
- 遍历
穿越列表。
`
穿越
- 获取
head
指向的节点为Current。 - 检查Current是否为空并显示它。
- 点电流为当前的
next
,并移动到上面的步骤。
`
时间复杂度:O(n)//这里n是链接列表的大小
履行
单链表的C ++实现
// Header files
#include <iostream>
struct node
{
int data;
struct node *next;
};
// Head pointer always points to first element of the linked list
struct node *head = NULL;
在每个节点中打印数据
// Display the list
void printList()
{
struct node *ptr = head;
// Start from the beginning
while(ptr != NULL)
{
std::cout << ptr->data << " ";
ptr = ptr->next;
}
std::cout << std::endl;
}
插入开头
// Insert link at the beginning
void insertFirst(int data)
{
// Create a new node
struct node *new_node = new struct node;
new_node->data = data;
// Point it to old head
new_node->next = head;
// Point head to new node
head = new_node;
std::cout << "Inserted successfully" << std::endl;
}
删除开头
// Delete first item
void deleteFirst()
{
// Save reference to head
struct node *temp = head;
// Point head to head's next
head = head->next;
// Free memory used by temp
temp = NULL:
delete temp;
std::cout << "Deleted successfully" << std::endl;
}
尺寸
// Find no. of nodes in link list
void size()
{
int length = 0;
struct node *current;
for(current = head; current != NULL; current = current->next)
{
length++;
}
std::cout << "Size of Linked List is " << length << std::endl;
}
搜索
// Find node with given data
void find(int data){
// Start from the head
struct node* current = head;
// If list is empty
if(head == NULL)
{
std::cout << "List is empty" << std::endl;
return;
}
// Traverse through list
while(current->data != data){
// If it is last node
if(current->next == NULL){
std::cout << "Not Found" << std::endl;
return;
}
else{
// Go to next node
current = current->next;
}
}
// If data found
std::cout << "Found" << std::endl;
}
节点后删除
// Delete a node with given data
void del(int data){
// Start from the first node
struct node* current = head;
struct node* previous = NULL;
// If list is empty
if(head == NULL){
std::cout << "List is empty" << std::endl;
return ;
}
// Navigate through list
while(current->data != data){
// If it is last node
if(current->next == NULL){
std::cout << "Element not found" << std::endl;
return ;
}
else {
// Store reference to current node
previous = current;
// Move to next node
current = current->next;
}
}
// Found a match, update the node
if(current == head) {
// Change head to point to next node
head = head->next;
}
else {
// Skip the current node
previous->next = current->next;
}
// Free space used by deleted node
current = NULL;
delete current;
std::cout << "Deleted succesfully" << std::endl;
}
单链表的Python实现
class Node(object):
# Constructor
def __init__(self, data=None, next=None):
self.data = data
self.next = next
# Function to get data
def get_data(self):
return self.data
# Function to get next node
def get_next(self):
return self.next
# Function to set next field
def set_next(self, new_next):
self.next = new_next
class LinkedList(object):
def __init__(self, head=None):
self.head = head
插入
# Function to insert data
def insert(self, data):
# new_node is a object of class Node
new_node = Node(data)
new_node.set_next(self.head)
self.head = new_node
print("Node with data " + str(data) + " is created succesfully")
尺寸
# Function to get size
def size(self):
current = self.head
count = 0
while current:
count += 1
current = current.get_next()
print("Size of link list is " + str(count))
搜索
# Function to search a data
def search(self, data):
current = self.head
found = False
while current and found is False:
if current.get_data() == data:
found = True
else:
current = current.get_next()
if current is None:
print("Node with data " + str(data) + " is not present")
else:
print("Node with data " + str(data) + " is found")
节点后删除
# Function to delete a node with data
def delete(self, data):
current = self.head
previous = None
found = False
while current and found is False:
if current.get_data() == data:
found = True
else:
previous = current
current = current.get_next()
if current is None:
print("Node with data " + str(data) + " is not in list")
elif previous is None:
self.head = current.get_next()
print("Node with data " + str(data) + " is deleted successfully")
else:
previous.set_next(current.get_next())
print("Node with data " + str(data) + " is deleted successfully")
好处
- 链表是一种动态数据结构,可以在程序运行时增长和收缩,分配和释放内存。
- 节点的插入和删除很容易在任何位置的链表中实现。
缺点
- 由于指针使用的内存(
next
和prev
),它们使用的内存比数组多。 - 链表中无法随机访问。我们必须按顺序访问节点。
- 它比数组更复杂。如果一种语言自动支持数组绑定检查,Arrays会更好地为您服务。
注意
我们必须在C中使用free()并在C ++中删除以释放已删除节点使用的空间,而在Python和Java中,可用垃圾收集器自动收集空间。