P37.1
有一个整型链表,删除第二次甚至更多次出现的元素。
(1)算法的基本设计思想
之前没有写过递归函数,因此用来练习。设链表的两个结点A,B。B是A的下一结点。
声明函数Del,首先判断链表是否到了尾部,方法是判断B是否为空,如果是,返回0。如果不是,判断该节点A是否与其下一节点B相等,若相等,则删除下一元素B,并从A开始再次调用Del;若不相等,则从B开始调用Del。
注意递归函数的结束,很容易弄晕。
调用Del->判断是否到尾部->判断相等->调用Del->判断是否到尾部->判断相等->调用Del->......->判断是否到尾部->到尾部->返回0->这个调用的Del完成->返回上一层Del继续运行->上一层Del中调用Del是最后一句->上一层Del完成->返回上一层的上一层->......->返回第一层Del->退出
关键在于要弄懂return之后是退出本层Del,但是上一层Del没有别的语句了。因此继续返回上一层,看上去就像return是最后一句一样,但是实际上return并不能结束所有的递归。
另外注意一点,递归函数中再次调用本函数所传的参数要进行判断,看是在本节点继续还是到下一节点再继续。
(2)代码如下
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef int ElemType;
typedef struct LNode {
ElemType data;
struct LNode *next;
}LNode, *LinkList;
void printList(LinkList &L)
{
printf("\n");
LNode *s = L->next;
while (s != NULL)
{
printf("%d ", s->data);
s = s->next;
}
}
LinkList CreatListend(LinkList &L)
{
int x;
L = (LinkList)malloc(sizeof(LNode));
LNode *s, *r = L;
scanf("%d", &x);
while (x != 9999)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = x;
r->next = s;
r = s;
scanf("%d", &x);
}
r->next = NULL;
return L;
}
int DelSame(LinkList &L)
{
LNode *Nownext = L->next;
if (Nownext == NULL)
{
return 0;//注意递归函数中的return,这是递归函数结束的地方。
}
else
{
if (L->data == Nownext->data)
{
L->next = Nownext->next;
free(Nownext);
//printList(L);
DelSame(L);
}
else
{
//printList(L);
DelSame(L->next);
}
}
}
void main()
{
int count;
LinkList L, _L;
CreatListend(L);
_L = L->next;
printList(L);
DelSame(_L);
printList(L);
}
(3)复杂度
时间复杂度O(n)
空间复杂度O(n)
附加:按从后向前输出链表中的每个值
(1)算法的基本设计思想
灵感来自于递归函数的特点,本层递归结束之后返回执行上层递归的代码。意思就是如果将递归函数分为这样三部分
f {
f1
f
f2
}
那么执行起来就是f11->f21->f31->......->fn1->fn2->f(n-1)2->f(n-2)2->......->f12
可以看出,递归函数调用之前,代码是顺序执行,调用之后则是逆序执行。这样便可以实现逆序输出。
(2)代码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef int ElemType;
typedef struct LNode {
ElemType data;
struct LNode *next;
}LNode, *LinkList;
void printList(LinkList &L)
{
printf("\n");
LNode *s = L->next;
while (s != NULL)
{
printf("%d ", s->data);
s = s->next;
}
}
LinkList CreatListend(LinkList &L)
{
int x;
L = (LinkList)malloc(sizeof(LNode));
LNode *s, *r = L;
scanf("%d", &x);
while (x != 9999)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = x;
r->next = s;
r = s;
scanf("%d", &x);
}
r->next = NULL;
return L;
}
void Printend(LinkList &L)
{
if (L->next != NULL)
Printend(L->next);
printf("%d ", L -> data);
}
void main()
{
int count;
LinkList L, _L;
CreatListend(L);
_L = L->next;
printList(L);
Printend(_L);
}