【数据结构】链表头插,尾插,删除,插入,有序合并-模板代码
文章目录
- 【数据结构】链表头插,尾插,删除,插入,有序合并-模板代码
- 1. 头插法
- 2. 尾插法
- 3. 删除
- 4. 插入单个节点
- 5. 有序链表合并
在数据结构中,单链表是一种常见的线性数据结构,它由一系列的节点组成,每个节点包含两部分:数据和指向下一个节点的指针。对于链表,我们可以进行以下操作等:
创建、插入、删除、查找、遍历、反转、连接、复制、排序…
以下是每一个链表的元素:
struct Node{int data;Node* next=nullptr;Node(int x):num(x){}Node(){}
};
1. 头插法
下面是插入第一个元素的过程:
下面是插入第二个元素的过程:
注意点:
- 头插法中,head位置不变,每一次插入的时候插入点都在head的正后面,并且之前的元素都会往后推
- 不能用数组的角度来考虑链表,这里只需要连接起来,不需要全部都循环往后挪
- 注意好①和②的顺序
- 注意好插入之后元素的顺序
以下是代码的实现:
// head没有值,示例代码以此为参考
void AddHead(Node* head, int x)
{ Node* add=new Node(x); add->next=head->next;head->next=add;
}
// head有值
void AddHead(Node* head, int x)
{Node* add = new Node(x);add->next = head;head = add;
}
2. 尾插法
这是第一个元素插入的过程:
这是第二个元素插入的过程:
注意点:
- 尾插法中,每一个插入时都是在最后尾巴的位置插入再接入空指针
- 我们可以定义一个指针来记录尾巴,但用循环来查找会更清晰明了,这里用循环来查找尾
- 注意好插入之后元素的顺序
以下是代码的实现:
void AddRear(Node*head, int x)
{Node* last=new Node(x); Node* index=head;while(index->next!=nullptr){index=index->next;}index->next=last;
}
3. 删除
链表的操作最容易犯错的就是把链表当作数组来对待,以为对中间元素进行操作就要影响后面所有的元素,其实我们把他们连起来就行了,不需要像数组或者顺序表那样将后面元素都往后挪或者往前挪之类的。根据上面的可视化过程,我们可以知道链表的删除操作:
//i为删除位置,可以根据自己选择修改为逻辑位置或是下标位置
void LL_del(int i)
{if (i > len || i < 1){//越界操作}Node* index = head;while (i--){index = index->next;}index = index->next;
}
4. 插入单个节点
以下是链表插入的示例代码,切记不要像数组一样将后面元素全部往后移,我们只需要连起来就行了,插入单个节点的方法可以参照头插法,只需要将前面一大部分当作头节点行了:
void LL_insert(int i, int item)
{if (i > len + 1 || i < 1){//越界操作}Node* index = head;i--;while (i--){index = index->next;}Node* add = new Node(item);add->next = index->next;index->next = add;
}
5. 有序链表合并
int LL_merge(Node* headA, Node* headB)
{Node* resultHead = new Node; // 创建一个新链表用于存放合并结果Node* index = resultHead;Node* pa = headA->next;Node* pb = headB->next;while (pa != nullptr && pb != nullptr){if (pa->data < pb->data){index->next = pa;pa = pa->next;}else{index->next = pb;pb = pb->next;}index = index->next;}// 处理剩余部分if (pa != nullptr){index->next = pa;}if (pb != nullptr){index->next = pb;}// 更新La的头指针,使其指向合并后的链表headA->next = resultHead->next;
}
以上代码需结合实际题目考虑