系列文章目录
前言
删除单链表中重复节点
一、题目描述
删除单链表中的重复节点,分为如下几种情况:
1、单链表无序,删除重复的多余节点,即重复的节点只保留一个
2、单链表无序,删除重复的所有节点,即出现重复的节点全部删除
二、c++代码
1.删除无序链表中的重复多余节点
代码如下:
#include <iostream>
#include <map>
using namespace std;
typedef char datatype ;
#define max_size 256
// 单链表节点结构如下
typedef struct link_node
{
datatype data;
struct link_node *link;
}link_node;
// 尾插法创建单链表(带头节点)
link_node *createEnd(char const *arr)
{
link_node *head = new link_node;
head->link = NULL; //生成头节点
link_node *end=head; //尾指针初始化
int i=0;
while (arr[i]!='\0')
{
link_node *temp = new link_node; //为每个元素建立一个节点
temp->data = arr[i];
end->link = temp; //将新节点插入到尾节点后面
end = temp;
++i;
}
end->link = NULL; //单链表建立完毕,将尾节点指向空
return head;
}
void print_link(link_node *p)
{
if(p == NULL)
{
printf("链表为空!\n");
return;
}
while (p->link!=NULL)
{
printf(" %c ",p->link->data);
p = p->link;
}
} //打印链表
// 第一种方法:hash表去重
link_node *delSame(link_node *p)
{
if (p == NULL || p->link == NULL)
return p;
int count[max_size]={0};
link_node *pre = p;
link_node *next = p->link;
link_node *del;
while (next!=NULL)
{
if(count[next->data]==0)
{
count[next->data]=1;
pre = next;
next = next->link;
} else{
del = next;
pre->link = next->link;
next = pre->link;
free(del);
}
}
return p;
}
// 第二种方法:非递归遍历
link_node *delSame1(link_node *p)
{
if (p == NULL || p->link == NULL)
return p;
link_node *cur,*next,*del;
cur = p->link;
while (cur!=NULL) //cur遍历链表
{
next = cur;
while (next->link!=NULL) //next遍历cur后面的结点,并与cur值做比较
{
if(next->link->data == cur->data)
{
del = next->link; //del为要删除的结点
next->link = del->link; //需要删掉的结点的前后结点相接
free(del);
} else
next = next->link;
}
cur = cur->link;
}
return p;
}
int main() {
char const *arr = "a1xbeffeaghbm";
link_node *head = createEnd(arr);
// 去重之前
printf("原字符串为:\n");
print_link(head);
printf("\n");
delSame1(head);
// 去重之后
printf("去掉重复元素后的字符串为:\n");
print_link(head);
printf("\n");
return 0;
}
2.删除无序链表中的所有重复节点
代码如下(示例):
#include <iostream>
#include <map>
using namespace std;
typedef char datatype ;
// 单链表节点结构如下
typedef struct link_node
{
datatype data;
struct link_node *link;
}link_node;
// 尾插法创建单链表(带头节点)
link_node *createEnd(char const *arr)
{
link_node *head = new link_node;
head->link = NULL; //生成头节点
link_node *end=head; //尾指针初始化
int i=0;
while (arr[i]!='\0')
{
link_node *temp = new link_node; //为每个元素建立一个节点
temp->data = arr[i];
end->link = temp; //将新节点插入到尾节点后面
end = temp;
++i;
}
end->link = NULL; //单链表建立完毕,将尾节点指向空
return head;
}
void print_link(link_node *p)
{
if(p == NULL)
{
printf("链表为空!\n");
return;
}
while (p->link!=NULL)
{
printf(" %c ",p->link->data);
p = p->link;
}
} //打印链表
link_node *delSame(link_node *p)
{
if (p == NULL || p->link == NULL)
return p;
link_node *s = p;
link_node *cur = s->link;
link_node *next,*del,*temp;
int flag = 0;
while (cur!=NULL) //cur遍历链表
{
next = cur;
while (next->link!=NULL) //next遍历cur后面的结点,并与cur值做比较
{
if(next->link->data == cur->data)
{
flag = 1;
del = next->link; //del为要删除的结点
next->link = del->link; //需要删掉的结点的前后结点相接
free(del);
} else
next = next->link;
}
if(flag == 0)
{
s = cur;
cur = cur->link;
}
else {
flag = 0;
temp = cur;
cur = cur->link;
s->link = cur;
free(temp);
}
}
return p;
}
int main() {
char const *arr = "a1xbeffeaghbm";
link_node *head = createEnd(arr);
// 去重之前
printf("原字符串为:\n");
print_link(head);
printf("\n");
delSame(head);
// 去重之后
printf("去掉重复元素后的字符串为:\n");
print_link(head);
printf("\n");
return 0;
}