在一个递增有序的线性表中,有数值相同的元素存在。若存储方式为单链表,设计算法,去掉数值相同的元素,使得表中不再有重复的元素。例如(7,10,10,21,30,42,42,42,51,70)将变为(7,10,21,30,42,51,70)。
分析:
- 递增有序的线性表中,数值相同的元素,其位置肯定相邻;
- 遍历链表,前后结点的值如果一致,就删除后一个结点;
void del_same_val(LinkList &L){//假设链表带有头结点;
if(L->next == NULL) return; //判断单链表是否为空;
LNode *pre = L->next;
while(pre->next != NULL){
if(pre->data == pre->next->data){//发现存在相同数值;
LNode *p = pre->next; //要被删除且释放的结点;
pre->next = p->next; //改写指针,将p结点断链;
free(p);
}else{
pre = pre->next;
}
}
}
该算法时间复杂度为O(n)。
如果将题目改成:
在一个递增有序的 顺序表 中,有数值相同的元素存在。设计算法,去掉数值相同的元素,使得表中不再有重复的元素,且存储方式改为单链表。例如(7,10,10,21,30,42,42,42,51,70)将变为(7,10,21,30,42,51,70)。
分析:
- 线性表上有序递增的;
- 在线性表中,删除完重复的元素后,得到一个元素不重复的线性表;
- 将新的线性表中的元素依次存储到链表中;
void del_same(SqList &A,LinkList &L){
int i = 1;
SqList B; //用来存储符合题意(数值均不相同)的元素
int j =0;
while(i < A.length){
if(A[i] != A[i+1]){//发现存在相同数值;
j++;
B[j] = A[i];
}
i++;
}
//得到符合题意的线性表B,将线性表中的元素依次存储到链表L中;
if(B.length >0){
L = (LinkList)malloc(sizeof(LNode));
//采用尾插法建立单链表;
List_TailInsert(L,B);
}
}
//尾插法建立单链表
LinkList List_TailInsert(LinkList &L,SqlList B){
*r = L; //尾指针为r的单链表;
r->next = NULL; //确保初始的链表为空;
int i=1;
while(i< B.length){
LNode *s;
s = (LNode *)malloc(sizeof(LNode));
s->data = B[i]; //创造结点*S;
r->next = s;
r=s;
i++;
}
r->next = NULL;
return L;
}
该算法时间复杂度为O(A.length+B.length),即O(2n),化简后为O(n)。