赞
踩
int head, e[N], ne[N], idx;
其中:
head
表示头结点的下标 == first指针
e[i]
表示第i
个节点的值
ne[i]
表示下一个节点所在的下标
idx
表示下一个新建节点的下标
头节点指向 -1
下一个节点所在下标设置为0
// 初始化
void init() {
head = -1;
idx = 0;
}
常规链表头插法添加节点:
void CreateHead(LinkNode *&head,ElemType a[],int n) {
LinkNode *cur;
head = new LinkNode;
head->next = NULL;
for(int i = 0 ; i < n ; i++) {
cur = new LinkNode;
cur->data = a[i];
cur->next = head->next;
head->next = cur;
}
}
数组模拟实现:
// 头插法添加节点
void add(int x) {
e[idx] = x; // 赋值
ne[idx] = head; // 下一个节点指向头结点
head = idx; // 头结点指向新节点
idx++;
}
初始:
head = -1, idx = 0
存一个 1 :
e[0] = 1, ne[0] = -1, head = 0, idx = 1
存一个 2 :
e[1] = 2, ne[1] = 0, head = 1, idx = 2
存一个 3 :
e[2] = 3, ne[2] = 1, head = 2, idx = 3
现在:
head -> 3 -> 2 -> 1
i = head = 2; e[i] = e[2] = 3; i = ne[head] = ne[2] = 1;
所以可以看出,head
一般是比较大的,i
是在一个减小的过程,最后一个 i = 0
在idx
为pos
的元素后添加新节点:
// 插入节点
void insert(int pos, int x) { // 在插入到下标为pos的后一位
e[idx] = x; // 赋值
ne[idx] = ne[pos]; // 下一个节点为原本pos位置节点的下一个
ne[pos] = idx; // 原本位置的节点的下一个节点为新节点
idx++;
}
在第 k
个元素后添加一个新节点(从0开始数):
void insert2(int k, int x) {
int i = head;
if (head < i) return;
while (k > 0) {
i = ne[i];
k--;
}
e[idx] = x;
ne[idx] = ne[i];
ne[i] = idx;
idx++;
}
删除idx
为pos
的节点:
// 删除节点
void remove(int pos) { // 删除pos后面的一个节点
ne[pos] = ne[ne[pos]];
}
// 遍历链表
void disp() {
int i = head;
while (i != -1) {
cout << e[i] << "[" << i << "]->" ;
i = ne[i];
}
cout << endl;
}
#include <bits/stdc++.h> using namespace std; const int N = 100010; int head, e[N], ne[N], idx; // 初始化 void init() { head = -1; idx = 0; } // 头插法添加节点 void add(int x) { e[idx] = x; // 赋值 ne[idx] = head; // 下一个节点指向头结点 head = idx; // 头结点指向 idx++; } // 插入节点 void insert(int pos, int x) { // 在插入到下标为pos的后一位 e[idx] = x; // 赋值 ne[idx] = ne[pos]; // 下一个节点为原本pos位置节点的下一个 ne[pos] = idx; // 原本位置的节点的下一个节点为新节点 idx++; } void insert2(int k, int x) { int i = head; if (head < i) return; while (k > 0) { i = ne[i]; k--; } e[idx] = x; ne[idx] = ne[i]; ne[i] = idx; idx++; } // 删除节点 void remove(int pos) { // 删除pos后面的一个节点 ne[pos] = ne[ne[pos]]; } // 遍历链表 void disp() { int id = head; while (id != -1) { cout << e[id] << "[" << id << "]->" ; id = ne[id]; } cout << endl; } int main () { init(); add(2); add(5); add(17); add(8); disp(); insert(2,18); insert2(3,19); remove(1); disp(); }
int e[N], l[N], r[N], idx;
其中:
e[i]
表示第i
个节点的值l[i]
表示第i
个节点的前一个节点所在的下标r[i]
表示第i
个节点的后一个节点所在的下标idx
表示下一个新建节点的下标
设置节点0为起始节点,节点1为为尾节点,下标从2开始。不设head指针
注意:下面这样是不循环双向链表
void init() {
r[0] = 1;
l[1] = 0;
idx = 2;
}
这样是循环双向链表:
void init() {
r[0] = 1;
l[0] = 1;
l[1] = 0;
r[1] = 0;
idx = 2;
}
插入到idx
为k
的节点的右边:
void insert(int k, int x) {
e[idx] = x; // 赋值
l[idx] = k; // 新节点的左节点
r[idx] = r[k]; // 新节点的右节点
// 下面两步要注意顺序,如果先改变了r[k]此时的l[r[k]]就会受到影响
l[r[k]] = idx; // 原节点的右节点的左节点
r[k] = idx; // 原节点的右节点
idx++;
}
特殊位置插入:
插入到idx
为k
的节点的左边:
insert(l[k], x)
插入到第一个节点前
insert(0, x)
因为初始化时,第一个节点是 0
插入到最后一个节点后
insert(l[1], x)
因为初始化时,最后一个节点是 1
void remove(int k) { // 删除idx为k的节点的
r[l[k]] = r[k];
l[r[k]] = l[k];
}
可以分为向左遍历和向右遍历两种。两者的差异就是代码中的
r
和l
注意一般来说,
i = 0
和i = 1
的节点是不用输出的。
向左遍历:
void dispL(int k) { // 从下标为k的位置遍历链表 ,向左遍历
int i = k;
while (l[i] != k) {
if (i != 0 && i != 1)
cout << e[i] << "[" << i << "]->" ;
i = l[i];
}
if (i != 0 && i != 1)
cout << e[i] << "[" << i << "]->" ;
cout << endl;
}
向右遍历:
void dispR(int k) { // 从下标为k的位置遍历链表 ,向右遍历
int i = k;
while (r[i] != k) {
if (i != 0 && i != 1)
cout << e[i] << "[" << i << "]->" ;
i = r[i];
}
if (i != 0 && i != 1)
cout << e[i] << "[" << i << "]->" ;
cout << endl;
}
#include <bits/stdc++.h> using namespace std; const int N = 100010; int e[N], l[N], r[N], idx; void init() { r[0] = 1; l[0] = 1; l[1] = 0; r[1] = 0; idx = 2; } void insert(int k, int x) { // 在idx为k的节点后面插入一个新节点 e[idx] = x; // 赋值 l[idx] = k; // 新节点的左节点 r[idx] = r[k]; // 新节点的右节点 l[r[k]] = idx; // 原节点的右节点的左节点 r[k] = idx; // 原节点的右节点 idx++; } void remove(int k) { // 删除idx为k的节点的 r[l[k]] = r[k]; l[r[k]] = l[k]; } void dispR(int k) { // 从下标为k的位置遍历链表 ,向右遍历 int i = k; while (r[i] != k) { if (i != 0 && i != 1) cout << e[i] << "[" << i << "]->" ; i = r[i]; } if (i != 0 && i != 1) cout << e[i] << "[" << i << "]->" ; cout << endl; } void dispL(int k) { // 从下标为k的位置遍历链表 ,向左遍历 int i = k; while (l[i] != k) { if (i != 0 && i != 1) cout << e[i] << "[" << i << "]->" ; i = l[i]; } if (i != 0 && i != 1) cout << e[i] << "[" << i << "]->" ; cout << endl; } int main() { init(); insert(0, 1); insert(0, 2); insert(0, 3); dispR(0); dispL(0); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。