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);
}