【数据结构】课后作业——递归删除链表中的多余相同元素

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

 

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