单链表ADT模板简单应用算法设计:按要求提纯链表

问题描述 :


目的:使用C++模板设计单链表的抽象数据类型(ADT)。并在此基础上,使用单链表ADT的基本操作,设计并实现单链表的简单算法设计。

内容:(1)请使用模板设计单链表的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考网盘中的ADT原型文件。)

(2)ADT的简单应用:使用该ADT设计并实现单链表应用场合的一些简单算法设计。

应用:假设用单链表 A存储m个整数,结点的结构为(data,next),且|data|<=N(N为正整数)。现要求设计一个时间复杂度尽可能高效的算法,对于链表A中的数据元素data的绝对值相等的结点,仅保留第一次出现的结点而删除其余绝对值相等的结点。

参考函数原型:

template
void Delete_Equal_Node( LinkList &A, int N );

输入说明 :


第一行:单链表A的长度 限定值N (以空格分隔)

第二行:单链表A的数据元素(数据元素之间以空格分隔)

输出说明 :


第一行:单链表A的遍历结果

空行

第二行:提纯后单链表A的遍历结果

单链表ADT模板简单应用算法设计:单链表的连接

#include<iostream>
using namespace std;
typedef int Elemtype;
//定义单链表结点类型
typedef struct LNode {
	Elemtype data;//每个节点存放一个数据元素
	struct LNode* next;//指针指向下一个元素
}LNode, * LinkList;
//正向建立单链表
LinkList List_TailInsert(LinkList& L, int length) {
	Elemtype x;
	L = new LNode;//建立头结点
	LNode* s, * r = L;//r为表尾指针
	for (int i = 0; i < length; i++) {
		cin >> x;
		s = new LNode;
		s->data = x;
		r->next = s;
		r = s;//r指向新的表尾结点
	}
	r->next = NULL;//尾结点指针置空
	return L;
}
//后插操作:在p结点之后插入元素e
bool InsertNextNode(LNode* p, Elemtype e) {
	if (p == NULL)
		return false;
	LNode* s = new LNode;
	if (s == NULL)//内存分配失败
		return false;
	s->data = e;//用结点s保存数据元素e
	s->next = p->next;
	p->next = s;//将结点s连接到p之后
	return true;
}
//前插操作:在p结点之前插入元素e
bool InsertPriorNode(LNode* p, Elemtype e) {
	if (p == NULL)
		return false;
	LNode* s = new LNode;
	if (s == NULL)
		return false;
	s->next = p->next;
	p->next = s;
	s->data = p->data;
	p->data = e;
	return true;

}
//输出单链表
void ListCout(LNode* p) {
	p = p->next;
	while (p != NULL) {
		cout << p->data << " ";
		p = p->next;
	}
}
//删除指定结点p
bool DeleteNode(LNode* p) {
	if (p == NULL)
		return false;
	LNode* q = p->next;//令q指向p的后继结点
	p->data = p->next->data;//和后继结点交换数据域
	p->next = q->next;//将*q结点从链中“断开”
	free(q);//释放后继结点的存储空间
	return true;
}
//求表的长度
int Length(LinkList L) {
	int len = 0;
	LNode* p = L;
	while (p->next != NULL) {
		p = p->next;
		len++;
	}
	return len;
}
//按位序删除(带头结点)
bool ListDelete(LinkList& L, int i) {
	if (i < 1)
		return false;
	LNode* p;//指针p指向当前扫描到的结点
	int j = 0;//当前p指向的是第几个结点
	p = L;//L指向头结点,头结点是第0个结点(不存数据)
	while (p != NULL && j < i - 1) {//循环找到第i-1个结点
		p = p->next;
		j++;
	}
	if (p == NULL)//i值不合法
		return false;
	if (p->next == NULL)//第i-1个结点之后已无其他结点
		return false;
	LNode* q = p->next;
	//e = q->data;//用e返回元素的值
	p->next = q->next;//将*q结点从链中”断开“
	free(q);//释放结点的存储空间
	return true;//删除成功
}
//按位查找,返回第i个元素(带头结点)
LNode* GetElem(LinkList L, int i) {
	int j = 1;
	LNode* p = L->next;
	if (i == 0)
		return L;
	if (i < 1)
		return NULL;
	while (p != NULL && j < i) {
		p = p->next;
		j++;
	}
	return p;
}
void Delete_Equal_Node(LinkList L)//测试数据限定为整数。实际应用时,不受其限制
{
	int len = Length(L);
	for (int i = 1; i < Length(L); i++) {
		for (int j = i + 1; j <= Length(L); j++) {
			if (abs(GetElem(L, i)->data) == abs(GetElem(L, j)->data))
				ListDelete(L, j);
		}
	}
	for (int i = 1; i < Length(L); i++) {
		for (int j = i + 1; j <= Length(L); j++) {
			if (abs(GetElem(L, i)->data) == abs(GetElem(L, j)->data))
				ListDelete(L, j);
		}
	}
	ListCout(L);
}
int main() {
	LinkList L;
	int length1;
	cin >> length1;

	int N;
	cin >> N;

	List_TailInsert(L, length1);
	ListCout(L);
	cout << endl << endl;
	Delete_Equal_Node(L);
	return 0;
}
上一篇:广工数据结构Anyview(C语言版)第一章答案


下一篇:链表必学算法(三):归并法