链表
- 链表的插入
如图所示
插入操作时,需要获得插入位置的前一个节点,这样插入到前一个节点的后方,即插入到n位置,因为前一个节点的next原本指向后一个节点,即位置n(n从0开始,head不算)。
所以当n为0时,head指向位置为0的节点,操作为如下:
当n大于0时,操作如下:
// n == 0
Node * p = new Node;
p->data = data //数据赋值
p->next = head; //插入节点尾指向前一个节点指向的节点
head = p; //前一个节点指向插入节点
// n > 0
Node * q = head;
Node * p = new Node;
p->data = data;
// 寻找插入节点的前一个节点
for (int i = 0; i < n - 1; ++i) {
q = q->next;
}
p->next = q->next; // 插入节点尾指向前一个节点指向的节点
q->next = p; // 前一个节点指向插入节点
- 链表的删除
观察上图的插入操作,可知删除操作一样需要得知删除节点前一个节点和删除节点,前一个节点的尾指向删除节点的尾即可从链中移除删除节点,最后再做清楚工作。
Node * q = head;
// 寻找插入节点的前一个节点
for (int i = 0; i < n - 1; ++i) {
q = q->next;
}
Node * p = q->next; // p即为删除节点,因为前一个节点的尾指向删除节点
q->next = p->next;
delete p; // 清除数据
- 链表的替换
链表的替换与前面的操作不同,只需要找到位置为n的节点,将其元素改变即可,但是有些时候,需要进行,删除节点,插入节点操作,即链的替换,而非元素的替换。
Node * q = head;
// 寻找位置为n的节点,所以不用-1
for (int i = 0;i < n; ++i) {
q = q->next;
}
// 替换操作
q->data = data;
- 链表的检索
同理,检索时为了查看指定位置的元素,所以只需要找到节点即可。
Node * q = head;
for (int i = 0; i < n; ++i) {
q = q->next;
}
return q->data;
- 链表的遍历
遍历需要访问所有节点,代码如下
Node * q = head;
// 当q不为NULL时为真
while (q) {
cout << q->data << " ";
}
cout << endl;
- 链表的清除
删除同样需要访问所有节点
while (head) {
Node * q = head;
head = head->next;
delte q;
// 可以加一步使q指向NULL
// q = NULL;
}