node* remove_same(node* head) { node* pi = head; while (pi != NULL) { node* p1 = pi->next; while (p1 != NULL) { if (p1->data == pi->data) { node* temp = p1; pi->next = p1->next; p1 = p1->next; delete temp; } else { p1 = p1->next; } } pi = pi->next; } return head; } 分析代码过程
时间: 2024-04-19 09:24:38 浏览: 63
这段代码是一个单链表的去重函数。我们来逐行分析代码的过程:
1. 定义了一个指针pi,初始化为头节点head。
2. 进入第一个while循环,判断pi是否为空,如果不为空则继续执行循环体内的代码。
3. 在循环体内定义了一个指针p1,初始化为pi的下一个节点。
4. 进入第二个while循环,判断p1是否为空,如果不为空则继续执行循环体内的代码。
5. 在循环体内,判断p1节点的数据是否和pi节点的数据相同。如果相同,则执行以下操作:
- 定义一个临时指针temp,指向p1节点。
- 将pi节点的next指针指向p1节点的next节点,即删除p1节点。
- 将p1指针指向下一个节点。
- 释放temp指针所指向的内存空间。
6. 如果p1节点的数据和pi节点的数据不相同,则将p1指针指向下一个节点。
7. 循环结束后,将pi指针指向下一个节点。
8. 返回头节点head。
这段代码的作用是移除链表中重复的节点。它使用了两个指针pi和p1,其中pi指向当前要比较的节点,p1用于遍历pi后面的节点。如果发现p1和pi节点的数据相同,则删除p1节点,并继续比较下一个节点。最后返回处理后的链表头节点。
相关问题
优化node* subdouble(node* head) { node* pre = NULL; node* tmp = head; while (tmp != NULL) { node* pi; for (pi = head; pi != tmp; pi = pi->next) { if (pi->next == tmp->next) { pre->next = tmp->next; tmp = tmp->next; break; } } if (pi = tmp) { pre = tmp; tmp = tmp->next; } } return head; }
这段代码的功能是将链表中重复的节点删掉,返回处理后的链表的头节点。但是代码存在一些问题,可以进行优化:
1. 在比较节点时,可以使用节点的值进行比较,而不是比较节点的指针,这样可以提高代码的效率。
2. 在找到重复节点时,可以直接将当前节点指向重复节点的下一个节点,而不是遍历整个链表找到前驱节点再删除。
3. 在比较节点时,可以从当前节点的下一个节点开始进行比较,而不是从头节点开始遍历,这样可以减少比较次数。
下面是优化后的代码实现:
```
node* subdouble(node* head) {
if (head == NULL) return NULL;
node* cur = head;
while (cur != NULL) {
node* pre = cur;
node* tmp = cur->next;
while (tmp != NULL) {
if (tmp->val == cur->val) {
pre->next = tmp->next;
tmp = pre->next;
} else {
pre = tmp;
tmp = tmp->next;
}
}
cur = cur->next;
}
return head;
}
```
优化后的代码采用了双重循环,外层循环遍历每个节点,内层循环从当前节点的下一个节点开始遍历比较,找到重复节点后直接删除。这样可以提高代码的效率。
#include <iostream> using namespace std; struct node { int data; node* next; }; node* createlist(int array[], int n); void printlist(node* head); int main() { int n; cin >> n; int array[100]; for (int i = 0; i < n; i++) { cin >> array[i]; } node* head = createlist(array, n); printlist(head); return 0; } node* createlist(int array[], int n) { node* head = NULL, * tail = NULL; for (int i = 0; i < n; i++) { node* tmp = new node; tmp->data = array[i]; tmp->next = NULL; if (head == NULL) head = tail = tmp; else { tail->next = tmp; tail = tmp; } } return head; } void printlist(node* head) { for (node* pi = head; pi != NULL; pi->next) { cout << pi->data << "-> "; } }该代码为何出现死循环
在函数`printlist`中,循环条件应该是`pi != NULL`,而不是`pi->next`。因为`pi->next`只是指向下一个节点,而没有将当前节点输出。因此,在遍历到最后一个节点时,`pi->next`为`NULL`,但是当前节点还没有被输出,因此会出现死循环。正确的循环条件应该是`pi != NULL`,即当当前节点为`NULL`时,退出循环。修改后的代码如下:
```
void printlist(node* head) {
for (node* pi = head; pi != NULL; pi = pi->next) {
cout << pi->data << "-> ";
}
}
```
阅读全文