数据结构——删除有序链表中所有相同的结点
链表:
删除有序链表中所有相同的结点
分析:
方法一:可以新建一个链表,将原链表中不重复的节点都拷贝并尾插到新链表中。但是要记录非重复的结点的位置。(不予实现)
方法二:在原链表上操作,思路如下:
下面是原链表的结构:
第一种情况:
第二种情况:
接下来我们用代码实现:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
}Node;
//创建结点
Node* BuyNode(int data) {
Node* node = (Node*)malloc(sizeof(Node));
node->data = data;
node->next = NULL;
return node;
}
//删除相同的结点
Node* DeleteNode(Node* head) {
//三个遍历指针
//用一个假头节点来记录删除节点后的链表的首节点
//后两个用来进行遍历、比较
Node* fake = (Node*)malloc(sizeof(Node));
fake->next = head;
Node* pre = fake;//记录当前结点的前一个位置
Node* cur = head;
Node* next = cur->next;
//先进行结点个数的判断:如果没有节点或只有一个结点,就直接返回头节点
if (cur == NULL || next == NULL) {
return head;
}
//开始进行比较、删除。
while (cur != NULL && cur->next != NULL) {
//遇到重复节点时
if (cur->data == next->data) {
//遇到重复的结点,就让next向后走,pre->next指向next
while (next != NULL && cur->data == next->data) {
next = next->next;
}
pre->next = next;
cur = next;
pre = cur;
}
//没有遇到重复节点时
else {
//就让pre指向当前节点,再继续向后遍历
pre = cur;
cur = next;
next = next->next;
}
}
head = fake->next;
return head;
}
//打印链表
void NodePrint(Node* head) {
Node* cur = head;
//先进行判空
if (cur == NULL) {
printf("链表为空!!!\n");
return;
}
while (cur != NULL) {
if (cur->next != NULL) {
printf("%d --> ", cur->data);
}
else {
printf("%d\n", cur->data);
}
cur = cur->next;
}
return;
}
int main() {
Node* n1 = BuyNode(1);
Node* n2 = BuyNode(2);
Node* n3 = BuyNode(2);
Node* n4 = BuyNode(2);
Node* n5 = BuyNode(2);
//连接链表
n1->next = n2;
n2->next = n3;
n3->next = n4;
n4->next = n5;
NodePrint(n1);
printf("\n\n删除相同节点后的链表:\n");
Node* result = DeleteNode(n1);
NodePrint(result);
system("pause");
return 0;
}
注意:
还是老话:操作时,先对链表进行判空(判空能省好多事呢,也能避免访问时对非法内存进行的非法操作。)