第14周-任务2-链表类

【关于题目】
  动态链表也是程序设计中的一种非常有用的数据结构。可以说,是否能够理解有关操作的原理,决定了你是否有资格称为“科班”出身。在C++程序设计中解决相关问题不免让人有些害怕,所幸在是,在后续的专业基础课中,相关的内容还会从不同的角度,反复地认识,反复地实践。不过,在现阶段多些体验,也是很有必要的了。
  先阅读下面的程序,回顾一下动态链表,阅读程序过程中,请用笔画一画形成链表的过程中指针值的变化。

#include <iostream>
using namespace std;
struct Student
{	int num;
	double score;
	struct Student *next;
};
int main( )
{	Student *head=NULL,*p,*q;
	//建立动态链表
	for(int i=0;i<3;i++)
	{
		p = new Student;
		cin>>p->num>>p->score;
		p->next=NULL;
		if (i==0) head=p;
		else q->next=p;
		q=p;
	}
	//输出动态链表
	p=head;
	while(p!=NULL)
	{	cout<<p->num<<" "<<p->score<<endl;
		p=p->next;
	}
}

  可以参考下图理解程序

【题目】建立专门的链表类处理有关动态链表的操作
  现在我们通过下面的任务,用面向对象的程序设计的思维看待最简单的动态链表,初步体验有关的操作。
  任务要求是:在已有代码的基础上完善程序,完成动态链表的简单操作。

class Student
{
public:
	Student(int n,double s){num=n;score=s;next=NULL;}
	Student *next;
	int num;
	double score;
};

class MyList
{
public:
	MyList(){head=NULL;}
	MyList(int n,double s){head=new Student(n,s);} //以Student(n,s)作为单结点的链表
	int display();  //输出链表,返回值为链表中的结点数
	void insert(int n,double s);  //插入:将Student(n,s)结点插入链表,该结点作为第一个结点
	void append(int n,double s);  //追加:将Student(n,s)结点插入链表,该结点作为最后一个结点
	void cat(MyList &il); //将链表il连接到当前对象的后面
	int length();  //返回链表中的结点数
private:
	Student *head;
};

int main()
{
	int n;
	double s;
	MyList head1;
	cout<<"input head1: "<<endl;  //输入head1链表
	for(int i=0;i<3;i++)
	{
		cin>>n>>s;
		head1.insert(n,s);  //通过“插入”的方式
	}
	cout<<"head1: "<<endl; //输出head1
	head1.display();

	MyList head2(1001,98.4);  //建立head2链表
	head2.append(1002,73.5);  //通过“追加”的方式增加结点
	head2.append(1003,92.8);
	head2.append(1004,99.7);
	cout<<"head2: "<<endl;   //输出head2
	head2.display();

	head2.cat(head1);   //反head1追加到head2后面
	cout<<"length of head2 after cat: "<<head2.length()<<endl;
	cout<<"head2 after cat: "<<endl;   //显示追加后的结果
	head2.display();

	system("pause");
	return 0;
}

【参考解答】

#include<iostream>
using namespace std;

class Student
{
public:
	Student(int n,double s){num=n;score=s;next=NULL;}
	Student *next;
	int num;
	double score;
};

class MyList
{
public:
	MyList(){head=NULL;}
	MyList(int n,double s){head=new Student(n,s);} //以Student(n,s)作为单结点的链表
	int display();  //输出链表,返回值为链表中的结点数
	void insert(int n,double s);  //插入:将Student(n,s)结点插入链表,该结点作为第一个结点
	void append(int n,double s);  //追加:将Student(n,s)结点插入链表,该结点作为最后一个结点
	void cat(MyList &il); //将链表il连接到当前对象的后面
	int length();  //返回链表中的结点数
private:
	Student *head;
};

int MyList::display()
{
	if(head==NULL)
	{
		cout<<"empty\n";
		return 0;
	}
	int cnt=0;
	Student *pt=head;
	while(pt)
	{
		++cnt;
		cout<<pt->num<<" "<<pt->score<<endl;
		pt=pt->next;
	}
	return cnt;
}

void MyList::insert(int n, double s)
{
	Student * pt=new Student(n,s);
	pt->next =head;
	head=pt;
}

void MyList::append(int n,double s)
{
	Student * pt=new Student(n,s);
	if(head==NULL)
		head=pt;
	else
	{
		Student *pts=head;
		Student *pte=pts->next;
		while(pte)
		{
			pts=pte;
			pte=pts->next;
		}
		pts->next=pt;
	}
}

void MyList::cat(MyList& il)
{
	Student *pt=il.head;
	while(pt)
	{
		append(pt->num,pt->score);
		pt=pt->next;
	}
}

int MyList::length()
{
	int cnt=0;
	Student *pt=head;
	while(pt)
	{
		++cnt;
		pt=pt->next ;
	}
	return cnt;
}

int main()
{
	int n;
	double s;
	MyList head1;
	cout<<"input head1: "<<endl;  //输入head1链表
	for(int i=0;i<3;i++)
	{
		cin>>n>>s;
		head1.insert(n,s);  //通过“插入”的方式
	}
	cout<<"head1: "<<endl; //输出head1
	head1.display();

	MyList head2(1001,98.4);  //建立head2链表
	head2.append(1002,73.5);  //通过“追加”的方式增加结点
	head2.append(1003,92.8);
	head2.append(1004,99.7);
	cout<<"head2: "<<endl;   //输出head2
	head2.display();

	head2.cat(head1);   //反head1追加到head2后面
	cout<<"length of head2 after cat: "<<head2.length()<<endl;
	cout<<"head2 after cat: "<<endl;   //显示追加后的结果
	head2.display();

	system("pause");
	return 0;
}

【任务扩展一(选做)】

  任务中的结点只处理包含包含学号和分数的学生信息。如何将之用于其他应用,一种办法是修改Student类,增加学生的姓名、年龄……。Students类也可换作描述其他事物的类。请设计建立一个动态链表,其中有5个结点,分别描述5个三角形,从头结点开始,逐个输出三角形的信息。

【任务扩展二(选做)】

  上面的处理,仍然不够抽象,所以,只能就事论事地做,这是设计的大忌。实际上,结点的类型可以定义为以下模板类:

template <class T>
class Node
{
public:
	Node *next;
	T data;
};

  这样,“一劳永逸”地解决了data的类型,只要在定义类时,对T进行实例化即可。在这里,T类型中也不需要涉及有关链表中指针的内容。
  请按这种思路重写程序,为了测试,在main()函数中建立一个MyArray<double>型对象进行测试。另外,再建立一个MyArray<Triangle>型对象进行测试(Triangle为自定义三角形类)。

【任务扩展三(选做)】

  本任务实现的是最简单的单向链表中的最基本的操作。从链表的类型上,还可以有双向链表(有头结点和尾结点,方便从前往后和从后往前的访问)、十字链表等,类似的方法可以构造二叉树、多叉树、图(例如,计算机网络结构可以抽象描述为图,社交网络中用户的关系也是图,顶有用的结构)。从操作角度,单链表在插入时,可以让结点保持有序;可以从链表中查找元素;很多的应用中涉及的算法需要借助于数据结构和算法的设计获得最佳的处理性能。关于这方面的内容不再以具体任务的形式给出,在后续的专业基础课中将会逐渐引出。另外,有程序设计基础,同学们是可以自己往前走一走,找相关的教材和书籍(数据结构、算法类)看一看,是否能依靠自己的力量往前走一走了。

时间: 2024-10-06 07:57:58

第14周-任务2-链表类的相关文章

C++第15周项目2 -链表类

课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565,本周题目链接:http://blog.csdn.net/sxhelijian/article/details/9018813 [项目2]建立专门的链表类处理有关动态链表的操作 动态链表也是程序设计中的一种非常有用的数据结构.可以说,是否能够理解有关操作的原理,决定了你是否有资格称为"科班"出身.在后续的专业基础课中,相关的内容还会从不同的角度,反复地认识,反复地

C++第14周项目2 - 形状类族的中的纯虚函数

课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565,本周题目链接:http://blog.csdn.net/sxhelijian/article/details/8987478 [项目2]写一个程序,定义抽象基类Shape,由它派生出3个派生类,Circle(圆形).Rectangle(矩形).Triangle(三角形).用如下的main()函数,求出定义的几个几何体的面积和.  int main() { Circle c

第14周-任务1-数组类的构造

[关于题目]数组是几乎所支持的组织数据的方法.C和C++对数组类型提供了内置支持,使我们利用数组实现软件中需要的各种实用的功能.但是,这种支持仅限于用来读写单个元素的机制.C++不支持数组的抽象abstraction,也不支持对整个数组的操作.例如:把一个数组赋值给另外一个数组,对两个数组进行相等比较或者想知道数组的大小size,等等.对C++而言,数组是从C语言中继承来的,它反映了数据与对其进行操作的算法的分离,有浓厚的过程化程序设计的特征.数组并不是C++语言的一等公民.所以在实际项目中,对

C++第14周项目3 -立体类族共有的抽象类

课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565,本周题目链接:http://blog.csdn.net/sxhelijian/article/details/8987478 [项目3]设计一个抽象类CSolid,含有两个求表面积及体积的纯虚函数.设计个派生类CCube.CBall.CCylinder,分别表示正方体.球体及圆柱体.在main()函数中,定义基类的指针p(CSolid *p;),利用p指针,输出正方体.球

C++程序设计课程师生互动(2012年春第14周)

第14周出了一次差将上课调整到了周二,给同学们造成了些小混乱.教师的各种事务,和同学们的学习,不可兼得啊.尽管将自己的出差降到最少,但这也真是不可避免. 为了综合运用,也为了将来给专业基础课的学习找些感觉,出的题目是数组类和链表类.预料会难,这也是对同学们的一次考验.以至于,周三晚上在旅馆照例打开同学们的博客看,看完了一个班的,再没有心情继续看下去:没有及时提交的同学太多了.延后一周再看,大部分同学补了上来,但未提交的比例较之前要多. 同学们,继续努力啊.. [学习心得] 拷贝构造函数是个"好函

C02-程序设计基础提高班(C++)第14周上机任务-文件操作

第14周:阅读教材第13章(p417-458),主要内容是输入输出,重点是文件的操作,完成第14周上机任务: (回到C02-程序设计基础提高班(C++)学习安排) [任务1]涨工资从文件salary.txt中读入500名工人的工资,全部增加100元后进行排序,将排序后的结果在屏幕上输出,并保存到文件ordered_salary.txt中.[ 参考:涨工资了 - http://blog.csdn.net/sxhelijian/article/details/7632245 ] [任务2]学生成绩排

C#数据结构篇(一链表类) killertang(原作)

C#数据结构篇(一)线性表           作者: 寒羽狼 (Dark_Slaer_Tang)             最近,马子跑了,你说女人老是容易翻脸...,看来做程序员必定要 "茕茕孑立,行影相吊"悲惨命运了.还是老老实实编程吧,我发现用c# 编一些数据接结构的类也瞒不错的,于是想把数据结构的算法,用C#重写一遍,打发无聊的时光,下面是数据结构中的链表的实现.        首先定义结点类型,定义了,前一个指针域,后一个指针域,如下: using System; names

c-C++链表类前插法与尾插法问题

问题描述 C++链表类前插法与尾插法问题 #include using namespace std; class StudentRecord { public: string stuName; int stuNo; StudentRecord(string s,int n) { stuName=s; stuNo=n; } void print() { cout<<"Name:"< } }; class StudentNode { public: StudentReco

《C++语言基础》实践项目——链表类及其应用

返回:贺老师课程教学链接 [项目 - 链表类]动态链表也是程序设计中的一种非常有用的数据结构.可以说,是否能够理解有关操作的原理,决定了你是否有资格称为"科班"出身.在后续的专业基础课中,相关的内容还会从不同的角度,反复地认识,反复地实践.不过,在现阶段多些体验,也是很有必要的了.(1)阅读下面的程序,回顾一下动态链表,阅读程序过程中,请用笔画一画形成链表的过程中指针值的变化. #include <iostream> using namespace std; struct