一、顺序表删除重复元素
1.1 问题描述
【问题描述】
设一顺序表有若干元素,编写程序实现删除表中值重复的元素,即重复元素只保留一个。
【输入形式】
第一行输入一个N(N不大于100),表示顺序表的长度;
第二行输入N个整数,表示顺序表元素;
【输出形式】
输出去重后的顺序表。
【样例输入】
7
2 2 2 3 3 2 2
【样例输出】
2 3
1.2 具体算法
顺序表实现删除重复元素,只需要找到重复元素的位置,再执行删除操作就好了
注意每次删除完以后要让第二重循环重新判断,否则会跳值,假设你删除的是第5个元素,删除完了以后,你的顺序表第5个元素后面的每个元素都向前移了1位,此时第5个元素实际上是本来的第6个元素,由于删除后j++了,那么下一次循环判断将从第6个元素开始判断,这样我们会漏掉对第5个元素的判断,所以我们应该每删除一个重复元素后让j--,这样我们删除掉第5个元素后再寻找的时候其实还是从第5个元素(删除前的第6个元素)开始判断。
简单来说,如果没有j--,那么当我们遇到连续重复元素的时候将只会删除1个重复元素,并不会将重复的元素都删除掉。
void Delete_Same_List(PList L){
int i,j,k;
for(i=0;i<L->len;i++){ //第一重循环
for(j=i+1;j<L->len;j++){ //第二重循环,用于寻找重复的元素
if(L->data[i]==L->data[j]){
for(k=j;k<L->len-1;k++){ //第三重循环,用于删除重复的元素
L->data[k]=L->data[k+1];
}
L->len--; //每删除一个,顺序表长度减少1
j--; //每删除一个,第二重循环要重新判断
} //切记要重新判断,不然j其实是j++,会跳过一个值不判断
}
}
}
1.3 代码实现
1.3.1 完整代码
#include<stdio.h>
#include<malloc.h>
#define SIZE 10
#define INCREAM 10
typedef struct List{
int * data;
int len;
int size;
}List,*PList;
PList Init_List(PList L){
L->data=(int *)malloc(sizeof(int)*SIZE);
L->len=0;
L->size=SIZE;
return L;
}
void Creat_List(PList L){
int n,i;
scanf("%d",&n);
if(L->len==L->size){
L->data=(int *)realloc(L->data,(L->size+INCREAM)*sizeof(int));
L->size+=INCREAM;
}
for(i=0;i<n;i++){
scanf("%d",&L->data[i]);
L->len++;
}
}
void Delete_Same_List(PList L){
int i,j,k;
for(i=0;i<L->len;i++){
for(j=i+1;j<L->len;j++){
if(L->data[i]==L->data[j]){
for(k=j;k<L->len-1;k++){
L->data[k]=L->data[k+1];
}
L->len--;
j--;
}
}
}
}
void Print_List(PList L){
int i;
for(i=0;i<L->len;i++){
printf("%d ",L->data[i]);
}
printf("\n");
}
int main(){
List L;
Init_List(&L);
Creat_List(&L);
Delete_Same_List(&L);
Print_List(&L);
return 0;
}
1.3.2 运行结果
二、删除带头结点的单链表中值重复的元素
2.1 问题描述
【问题描述】
建立带头结点的单链表,编写程序实现删除表中值重复的元素,即重复元素只保留一个。
【输入形式】
第一行输入一个N,表示建表的长度;
第二行输入N个整数,表示数据元素。
【输出形式】
输出去重后的单链表元素。
【样例输入】
5
2 2 2 3 3
【样例输出】
2 3
2.2 具体算法
删除带头结点单链表中值重复的元素时,我们要定义一个r用来保存要删除结点的前面一个结点。这样方便删除操作。
void Delete_Same_Node(PNode head){
PNode p,q,r;
p=head->next;
while(p){
r=p; //r保存p,r是q前面的结点
q=p->next; //q是p的下一个结点
while(q){ //循环遍历
if(p->data==q->data){ //当找到了重复元素时,执行删除操作
PNode s=q;
r->next=s->next; //r是q前面的结点
q=q->next; //删除后要让q变成q后面的结点,继续循环判断
free(s);
}else{
r=r->next; //r始终是q前面的结点,便于执行删除操作
q=q->next;
}
}
p=p->next;
}
}
2.3 代码实现
2.3.1 完整代码
#include<stdio.h>
#include<malloc.h>
typedef struct Node{
int data;
struct Node * next;
}Node,*PNode;
PNode Init_Node(){
PNode head=(PNode)malloc(sizeof(Node));
head->next=NULL;
return head;
}
void Creat_Node(PNode head){
int i,n;
scanf("%d",&n);
PNode Last=head;
for(i=0;i<n;i++){
PNode Pnew=(PNode)malloc(sizeof(Node));
scanf("%d",&Pnew->data);
Pnew->next=NULL;
Last->next=Pnew;
Last=Pnew;
}
}
void Delete_Same_Node(PNode head){
PNode p,q,r;
p=head->next;
while(p){
r=p;
q=p->next;
while(q){
if(p->data==q->data){
PNode s=q;
r->next=s->next;
q=q->next;
free(s);
}else{
r=r->next;
q=q->next;
}
}
p=p->next;
}
}
void Print_Node(PNode head){
PNode p=head->next;
while(p){
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
int main(){
PNode p;
p=Init_Node();
Creat_Node(p);
Delete_Same_Node(p);
Print_Node(p);
return 0;
}