【數據結構】課後作業——遞歸刪除鏈表中的多餘相同元素

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章