赞
踩
数据结构学习视频:数据结构-单链表_哔哩哔哩_bilibili
参考代码(C语言):数据结构系列2-单链表 | tyrantlucifer
单链表是一种基础且重要的数据结构,它属于链式存储结构,用于存储线性表中的数据元素。在单链表中,数据不是以连续的内存空间形式存储,而是通过“节点”相互链接起来。
单链表的每个节点由两个部分组成:
从逻辑结构上看,单链表中的节点按照一定的逻辑顺序链接在一起,形成一个线性序列。第一个节点通常被称为头节点,它的指针域指向第二个节点;后续每个节点的指针域都指向其后继节点,直到最后一个节点,它的指针域指向 NULL
或者 nullptr
(在不同的编程语言中可能有不同的表示方式),表示链表的结束。
单链表的主要特点包括:
- #include <iostream>
-
- #define TRUE 1
- #define FALSE 0
-
- /**
- * Define the struct of list node
- */
- struct Node {
- int data;
- Node* next;
- };
-
- /**
- * Initialize a linked list
- * @return the head pointer of the linked list's head
- */
- Node* initList() {
- Node* L = new Node;
- L->data = 0;
- L->next = nullptr;
- return L;
- }
-
- /**
- * Insert an item at the head of the linked list
- * @param L the head pointer of the linked list
- * @param data the data you want to insert
- */
- void headInsert(Node* L, int data) {
- Node* node = new Node;
- node->data = data;
- node->next = L->next;
- L->next = node;
- L->data++;
- }
-
- /**
- * Insert an item at the tail of the linked list
- * @param L the head pointer of the linked list
- * @param data the data you want to insert
- */
- void tailInsert(Node* L, int data) {
- Node* node = L;
- // 遍历整个链表
- for (int i = 0; i < L->data; i++) {
- node = node->next; // 得到尾节点
- }
- Node* n = new Node;
- n->data = data;
- n->next = nullptr;
- node->next = n;
- L->data++;
- }
-
- /**
- * Delete an item from the linked list
- * @param L the head pointer of the linked list
- * @param data the data you want to delete
- * @return success flag
- */
- int deleteNode(Node* L, int data) {
- Node* preNode = L;
- Node* node = L->next;
-
-
- while (node) {
- if (node->data == data) {
- preNode->next = node->next;
- delete node;
- L->data--;
- return TRUE;
- }
- preNode = node;
- node = node->next;
- }
- return FALSE;
- }
-
- /**
- * Print all items in a linked list
- * @param L the head pointer of the linked list
- */
- void printList(Node* L) {
- Node* node = L->next;
- while (node) {
- std::cout << "node = " << node->data << std::endl;
- node = node->next;
- }
- }
-
- /**
- * Main function
- * @return 0
- */
- int main() {
- Node* L = initList();
- headInsert(L, 1);
- headInsert(L, 2);
- headInsert(L, 3);
- headInsert(L, 4);
- headInsert(L, 5);
- tailInsert(L, 6);
- tailInsert(L, 7);
- printList(L);
-
- if (deleteNode(L, 3)) {
- std::cout << "Success delete" << std::endl;
- }
- else {
- std::cout << "Fail delete" << std::endl;
- }
- printList(L);
-
- // Cleanup: free allocated memory
- Node* current = L;
- while (current) {
- Node* next = current->next;
- delete current;
- current = next;
- }
-
- return 0;
- }
运行结果:
单循环链表是一种链式存储的数据结构,它是线性表的一种链式存储结构的变体。在单循环链表中,除了保留单链表的基本特性外,其特殊之处在于最后一个结点的指针域不再是指向空(NULL),而是指回链表的头结点,这样就形成了一个环状结构。
单循环链表主要由以下部分组成:
结点(Node):每个结点包含两个部分,即数据域(Data Field)和指针域(Link Field)。
头结点(Header Node):单循环链表通常有一个头结点,它不存放实际数据或者也可以存放特定信息,并且它的指针域指向链表中的第一个实际数据结点。
链表结构:通过各个结点之间的指针连接形成一个闭环,从任一结点出发,沿着指针方向不断遍历,最终都能回到起点,即头结点。
因此,单循环链表的特点是可以在不修改指针的情况下,从任何一个结点开始都可以连续地遍历到链表的所有元素,提高了某些算法的效率,例如在查找、排序等操作中有一定优势。
- #include <iostream>
-
- #define TRUE 1
- #define FALSE 0
-
- /**
- * Define the struct of list node
- */
- struct Node {
- int data;
- Node* next;
- };
-
- /**
- * Initialize a linked list
- * @return the head pointer of the linked list's head
- */
- Node* initList() {
- Node* L = new Node();
- L->data = 0;
- L->next = L;
- return L;
- }
-
- /**
- * Insert an item at the beginning of the linked list
- * @param L the head pointer of the linked list
- * @param data the data you want to insert
- */
- void headInsert(Node* L, int data) {
- Node* node = new Node();
- node->data = data;
- node->next = L->next;
- L->next = node;
- L->data++;
- }
-
- /**
- * Insert an item at the end of the linked list
- * @param L the head pointer of the linked list
- * @param data the data you want to insert
- */
- void tailInsert(Node* L, int data) {
- Node* n = L;
- Node* node = new Node();
- node->data = data;
- while (n->next != L) {
- n = n->next; // 找到链表尾部
- }
- node->next = L; // 新节点的next指向头节点
- n->next = node; // 原尾节点的next指向新节点
- L->data++;
- }
-
- /**
- * Delete an item from the linked list
- * @param L the head pointer of the linked list
- * @param data the data you want to delete
- * @return success flag
- */
- int deleteNode(Node* L, int data) {
- // 将新节点的next指向原链表的第一个元素,
- // 再更新链表头的next指向新节点
- Node* preNode = L;
- Node* node = L->next;
- while (node != L) {
- if (node->data == data) {
- preNode->next = node->next;
- delete node;
- L->data--;
- return TRUE;
- }
- preNode = node;
- node = node->next;
- }
- return FALSE;
- }
-
- /**
- * Print all items in a linked list
- * @param L the head pointer of the linked list
- */
- void printList(Node* L) {
- Node* node = L->next;
- while (node != L) {
- std::cout << node->data << "->";
- node = node->next;
- }
- std::cout << "NULL" << std::endl;
- }
-
- /**
- * Main function
- * @return 0
- */
- int main() {
- Node* L = initList();
- headInsert(L, 1);
- headInsert(L, 2);
- headInsert(L, 3);
- headInsert(L, 4);
- headInsert(L, 5);
- tailInsert(L, 6);
- tailInsert(L, 7);
- printList(L);
- deleteNode(L, 4);
- deleteNode(L, 7);
- printList(L);
- return 0;
- }
运行结果:
双链表(也称为双向链表)是链表的一种复杂形式,它是一种线性数据结构,由一系列节点(或称为元素)构成,每个节点包含两部分:
因此,在双向链表中,从任何一个节点出发,不仅可以找到其下一个节点(如同单链表),还可以找到其前一个节点。这样的设计使得在双向链表上的操作(如插入、删除和遍历)更加灵活,特别是在需要频繁进行双向遍历时更为高效。
- #include <iostream>
-
- #define TRUE 1
- #define FALSE 0
-
- /**
- * Define the struct of list node
- */
- struct Node {
- int data;
- Node* pre;
- Node* next;
- };
-
- /**
- * Initialize a linked list
- * @return the head pointer of the linked list
- */
- Node* initList() {
- Node* L = new Node();
- L->data = 0;
- L->pre = nullptr;
- L->next = nullptr;
- return L;
- }
-
- /**
- * Insert an item at the head of the linked list
- * @param L the head pointer of the linked list
- * @param data the data you want to insert
- */
- void headInsert(Node* L, int data) {
- Node* node = new Node();
- node->data = data;
- node->next = L->next;
- node->pre = L;
- if (L->next) {
- L->next->pre = node; // 如果原链表非空,那么原头节点的下一个节点的前驱指针应该指向新插入的节点
- L->next = node; // 更新原头节点的 next 指针使其指向新插入的节点
- }
- else {
- L->next = node; // 当链表为空时,新插入的节点成为链表的第一个节点
- }
- L->data++;
- }
-
- /**
- * Insert an item at the tail of the linked list
- * @param L the head pointer of the linked list
- * @param data the data you want to insert
- */
- void tailInsert(Node* L, int data) {
- Node* node = L;
- Node* n = new Node();
- n->data = data;
- while (node->next) {
- node = node->next; // 找到链表尾部的节点
- }
- n->next = node->next;
- node->next = n;
- n->pre = node;
- L->data++;
- }
-
- /**
- * Delete an item in the linked list
- * @param L the head pointer of the linked list
- * @param data the data you want to delete
- * @return success flag
- */
- int deleteNode(Node* L, int data) {
- Node* node = L->next;
- while (node) {
- if (node->data == data) {
- node->pre->next = node->next;
- if (node->next) {
- node->next->pre = node->pre;
- }
- L->data--;
- delete node;
- return TRUE;
- }
- node = node->next;
- }
- return FALSE;
- }
-
- /**
- * Print all items in a linked list
- * @param L the head pointer of the linked list
- */
- void printList(Node* L) {
- Node* node = L->next;
- while (node) {
- std::cout << node->data << " -> ";
- node = node->next;
- }
- std::cout << "NULL" << std::endl;
- }
-
- /**
- * Main function
- * @return null
- */
- int main() {
- Node* L = initList();
- headInsert(L, 1);
- headInsert(L, 2);
- headInsert(L, 3);
- headInsert(L, 4);
- tailInsert(L, 5);
- tailInsert(L, 6);
- printList(L);
- deleteNode(L, 6);
- printList(L);
- return 0;
- }
运行结果:
双循环链表是一种特殊类型的链表数据结构,它是双向链表与循环链表特性的结合。
组成部分:
节点(Node):双循环链表中的每个节点通常包含三个主要部分:
链表结构:整个链表通过这些节点相互连接形成,每个节点的“后继指针”指向下一个节点,“前驱指针”指向前一个节点。
- #include <iostream>
-
- /**
- * Define the struct of list node
- */
- struct Node {
- int data;
- Node* pre;
- Node* next;
- };
-
- /**
- * Init a linked list
- * @return The head pointer of the linked list's head
- */
- Node* initList() {
- Node* L = new Node();
- L->data = 0;
- L->pre = L;
- L->next = L;
- return L;
- }
-
- /**
- * Insert item at the head of the linked list
- * @param L The head pointer of the linked list
- * @param data The data you want to insert
- */
- void headInsert(Node* L, int data) {
- Node* node = new Node();
- node->data = data;
- node->next = L->next;
- node->pre = L;
- L->next->pre = node;
- L->next = node;
- L->data++;
- }
-
- /**
- * Insert item at the tail of the linked list
- * @param L The head pointer of the linked list
- * @param data The data you want to insert
- */
- void tailInsert(Node* L, int data) {
- Node* node = L;
- while (node->next != L) {
- node = node->next;
- }
- Node* n = new Node();
- n->data = data;
- n->pre = node;
- n->next = L;
- L->pre = n;
- node->next = n;
- L->data++;
- }
-
- /**
- * Delete item in the linked list
- * @param L The head pointer of the linked list
- * @param data The data you want to delete
- * @return Success flag
- */
- int deleteNode(Node* L, int data) {
- Node* node = L->next;
- while (node != L) {
- if (node->data == data) {
- node->pre->next = node->next;
- node->next->pre = node->pre;
- delete node;
- L->data--;
- return 1;
- }
- node = node->next;
- }
- return 0;
- }
-
- /**
- * Print all items in a linked list
- * @param L The head pointer of the linked list
- */
- void printList(Node* L) {
- Node* node = L->next;
- while (node != L) {
- std::cout << node->data << " -> ";
- node = node->next;
- }
- std::cout << "NULL" << std::endl;
- }
-
- /**
- * Main function
- * @return Null
- */
- int main() {
- Node* L = initList();
- headInsert(L, 1);
- headInsert(L, 2);
- headInsert(L, 4);
- headInsert(L, 5);
- printList(L);
- tailInsert(L, 6);
- tailInsert(L, 7);
- printList(L);
- deleteNode(L, 7);
- printList(L);
- return 0;
- }
运行结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。