单链表的头插法和尾插法
1. 头插法(Head Insertion)
- 原理:每次将新节点插入到链表的头部(即原头节点的前面)。
- 特点 :
- 插入顺序与最终链表顺序 相反。
- 时间复杂度:
O(1)
(无需遍历)。
- 示例 :
- 插入顺序:
1 → 2 → 3
→ 链表最终顺序:3 → 2 → 1
。
- 插入顺序:
2. 尾插法(Tail Insertion)
- 原理:每次将新节点插入到链表的尾部(即原尾节点的后面)。
- 特点 :
- 插入顺序与最终链表顺序 一致。
- 时间复杂度:若维护尾指针则
O(1)
,否则需遍历到尾部O(n)
。
- 示例 :
- 插入顺序:
1 → 2 → 3
→ 链表最终顺序:1 → 2 → 3
。
- 插入顺序:
C语言实现
头插法代码
c
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
} Node;
// 头插法函数
void insertHead(Node** head, int value) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = value;
newNode->next = *head; // 新节点指向原头节点
*head = newNode; // 更新头指针
}
// 打印链表
void printList(Node* head) {
Node* current = head;
while (current != NULL) {
printf("%d → ", current->data);
current = current->next;
}
printf("NULL\n");
}
int main() {
Node* head = NULL;
insertHead(&head, 1);
insertHead(&head, 2);
insertHead(&head, 3);
printList(head); // 输出:3 → 2 → 1 → NULL
return 0;
}
尾插法代码
c
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
} Node;
// 尾插法函数(需维护尾指针)
void insertTail(Node** head, Node** tail, int value) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = value;
newNode->next = NULL;
if (*head == NULL) { // 空链表时
*head = newNode;
*tail = newNode;
} else {
(*tail)->next = newNode; // 原尾节点指向新节点
*tail = newNode; // 更新尾指针
}
}
// 打印链表
void printList(Node* head) {
Node* current = head;
while (current != NULL) {
printf("%d → ", current->data);
current = current->next;
}
printf("NULL\n");
}
int main() {
Node* head = NULL;
Node* tail = NULL;
insertTail(&head, &tail, 1);
insertTail(&head, &tail, 2);
insertTail(&head, &tail, 3);
printList(head); // 输出:1 → 2 → 3 → NULL
return 0;
}
关键点总结
- 头插法:直接操作头指针,无需遍历。
- 尾插法:需维护尾指针(或每次遍历到尾部),效率更高。
- 注意事项 :
- 插入前需分配内存(
malloc
),删除时需释放内存(free
)。 - 处理空链表的边界条件(如首次插入时头/尾指针的初始化)。
- 插入前需分配内存(
总结
看上去的区别不太大
只是输出是相反的。和常识一致,是尾插法,先插进去的,位子靠前。
头插法;先处理s 后处理r
尾插法 先处理 r 后处理是;