实验8.1 链表类的定义与实现

题目

参照教材中链表类LinkedList的定义(教材中的例程9-6.h),给出其实现,注意合理使用Node类(教材中的例程9-3.h)的成员函数。在测试程序中定义整型链表A和B,分别插入5个元素,使用循环语句显示链表中的元素,然后把B中的元素加入A的尾部,再显示出来。

C++代码如下:

//node.h

//node.h
#ifndef NODE_H//结点类模板
#define NODE_H
template<class T>
class linkedlist;//新添
template<class T>//新添
class node
{
private:
	node<T>* next;//指向后继指针的结点
public:
	T data;//数据域
	node(const T& data, node<T>* next = 0);//构造函数
	void insertAfter(node<T>* p);//在本结点之后插入一个同类的结点P
	node<T>* deleteAfter();//删除本结点的后继结点,并返回其地址
	node<T>* nextNode();//获取后继结点的地址
	const node<T>* nextNode()const;//获取后继结点的地址
	friend linkedlist<T>;//因操作需要将linkedlist<T>作为node的友元(新添)
};
template<class T>
node<T>::node(const T& data, node<T>* next/*=0*/) :data(data), next(next)
{
}
template<class T>
node<T>* node<T>::nextNode()
{
	return next;
}
template<class T>
const node<T>* node<T>::nextNode()const
{
	return next;
}
template<class T>
void node<T>::insertAfter(node<T>* p)
{
	p->next = next;
	next = p;
}
template<class T>
node<T>* node<T>::deleteAfter()
{
	node<T>* tempPtr = next;
	if (next == 0)return 0;
	next = tempPtr->next;
	return tempPtr;
}
#endif

//link.h

//link.h
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include<iostream>
using namespace std;
#include "node.h"
template<class T>
class linkedlist
{
private:
	node<T>* front, * rear;//表头和表尾指针
	node<T>* prevPtr, * currPtr;//记录表当前遍历位置的指针,由插入和删除操作更新
	int size;//表中的元素个数
	int position;//当前元素在表中的位置序号,由函数reset使用
	//函数成员:
	//生成新结点,数据域为item,指针域为ptrNext
	node<T>* nextNode(const T& item, node<T>* ptrNext = NULL);
	void freeNode(node<T>* p);//释放结点                                     (未用)
	//将链表L复制到当前表(假设当前表为空)
	//被复制构造函数和“operator=”调用
	void copy(linkedlist<T>& L);//(因实现需要,无法使用(linkedlist<T>const&L)作为形参表)
public:
	void print();//打印链表类里的数据及其数目(新添)
	linkedlist();
	linkedlist(linkedlist<T>& L);//复制构造函数(因实现需要,无法使用(linkedlist<T>const&L)作为形参表)
	~linkedlist();
	linkedlist<T>& operator=(linkedlist<T>& L);//重载赋值运算符(因实现需要,无法使用(linkedlist<T>const&L)作为形参表)
	int getSize()const;//返回链表中的元素个数
	bool isEmpty()const;//链表是否为空                                      (未用)
	void reset(int pos = 0);//初始化游标的位置(第一位数的位置设为0)
	void next();//使游标移动到下一个结点
	bool endOfList()const;//游标是否到了链尾
	int currentPosition(void);//返回游标当前的位置
	void insertFront(const T& item);//在表头插入结点
	void insertRear(const T& item);//在表尾添加结点
	void insertAt(const T& item);//在当前结点之前插入结点
	void insertAfter(const T& item);//在当前结点之后插入结点
	T deleteFront();//删除头结点
	void deleteCurrent();//删除当前结点
	T& data();//返回对当前结点成员数据的引用
	const T& data()const;//返回对当前结点成员数据的常引用
	//清空链表:释放所有结点的内存空间。被析构函数和“operator ="调用
	void clear();
};
template<class T>
node<T>* linkedlist<T>::nextNode(const T& item, node<T>* ptrNext)//生成新结点,数据域为item,指针域为ptrNext
{

	node<T>* tempPtr = new node<T>(item, ptrNext);
	return tempPtr;
}
template<class T>
void linkedlist<T>::freeNode(node<T>* p)//释放结点
{
	delete p;
}
template<class T>
void linkedlist<T>::print()//打印链表类里的数据及其数目(新添)
{
	reset();
	while (!endOfList())
	{
		cout << data() << " ";
		next();
	}
	cout << endl;
	cout << "size=" << getSize() << endl;
}
template<class T>
linkedlist<T>::linkedlist()//构造函数
{
	size = 0;
	front = rear = new node<T>(0);
	currPtr = prevPtr = front;
}
template<class T>
int linkedlist<T>::currentPosition(void)//返回游标当前的位置
{
	node<T>* tempPtr = front->nextNode();
	position = 0;
	while (tempPtr != currPtr)
	{
		tempPtr = tempPtr->nextNode();
		position++;
	}
	return position;
}

template<class T>
int linkedlist<T>::getSize()const//返回链表中的元素个数
{
	return size;
}


template<class T>
T& linkedlist<T>::data()//返回对当前结点成员数据的引用
{
	return currPtr->data;
}
template<class T>
const T& linkedlist<T>::data()const//返回对当前结点成员数据的常引用
{
	return currPtr->data;
}
template<class T>
void linkedlist<T>::next()//使游标移动到下一个结点
{
	prevPtr = currPtr;
	currPtr = currPtr->nextNode();
}
template<class T>
bool linkedlist<T>::endOfList()const//游标是否到了链尾
{
	if (currPtr == NULL)return true;
	else return false;
}
template<class T>
bool linkedlist<T>::isEmpty()const//链表是否为空  
{
	if (front == rear)return true;
	else return false;
}
template<class T>
void linkedlist<T>::reset(int pos)//初始化游标的位置(第一位数的位置设为0)
{
	prevPtr = front;
	currPtr = front->nextNode();
	position = pos;
	for (int i = 0; i < position; i++)
	{
		prevPtr = currPtr;
		currPtr = currPtr->nextNode();
	}
}
template<class T>
void linkedlist<T>::insertFront(const T& item)//在表头插入结点
{
	prevPtr = currPtr;
	currPtr = nextNode(item, front->nextNode());
	front->next = currPtr;
	if (rear == front)
	{
		rear = currPtr;
	}
	size++;
}
template<class T>
void linkedlist<T>::insertRear(const T& item)//在表尾添加结点
{
	prevPtr = currPtr;
	currPtr = nextNode(item, rear->nextNode());
	rear->next = currPtr;
	rear = currPtr;
	size++;
}
template<class T>
void linkedlist<T>::insertAfter(const T& item)//在当前结点之后插入结点
{
	prevPtr = currPtr;
	node<T>* tempPtr = nextNode(item, currPtr->nextNode());
	currPtr->next = tempPtr;
	if (currPtr == rear)
	{
		rear = tempPtr;
	}
	currPtr = tempPtr;
	size++;

}
template<class T>
void linkedlist<T>::insertAt(const T& item)//在当前结点之前插入结点
{
	currPtr = nextNode(item, prevPtr->nextNode());
	prevPtr->next = currPtr;
	size++;
}
template<class T>
T linkedlist<T>::deleteFront()//删除头结点
{
	currPtr = front->nextNode();
	delete front;
	front = currPtr;
	size--;
	return front->data;
}
template<class T>
void linkedlist<T>::deleteCurrent()//删除当前结点
{
	node<T>* tempPtr = currPtr;
	prevPtr->deleteAfter();
	delete currPtr;
	currPtr = prevPtr;
	size--;
}
template<class T>
void linkedlist<T>::clear()//清空链表:释放所有结点的内存空间。被析构函数和“operator ="调用
{
	node<T>* tempPtr = front->nextNode();
	while (tempPtr != NULL)
	{
		node<T>* tempQ = tempPtr;
		tempPtr = tempPtr->nextNode();
		delete tempQ;
		size--;
	}
	rear = front;
	currPtr = prevPtr = front;
}
template<class T>
linkedlist<T>::~linkedlist()//析构函数
{
	clear();
	delete front;
}
template<class T>
void linkedlist<T>::copy(linkedlist<T>& L)//将链表L复制到当前表(假设当前表为空)被复制构造函数和“operator=”调用
//(因实现需要,无法使用(linkedlist<T>const&L)作为形参表)
{
	//clear();
	L.reset();
	for (int i = 0; i < L.size; i++)
	{
		insertRear(L.data());
		L.next();
	}

}
template<class T>
linkedlist<T>& linkedlist<T>::operator =(linkedlist<T>& L)//重载赋值运算符(因实现需要,无法使用(linkedlist<T>const&L)作为形参表)
{
	clear();
	front->next = NULL;
	copy(L);
	cout << "调用重载运算符=" << endl;
	return *this;
}
template<class T>
linkedlist<T>::linkedlist(linkedlist<T>& L)//复制构造函数(因实现需要,无法使用(linkedlist<T>const&L)作为形参表)
{
	size = 0;
	front = rear = new node<T>(0);
	currPtr = prevPtr = front;
	copy(L);
	cout << "调用复制构造函数" << endl;
}
#endif

//lab9_1.cpp

//lab9_1.cpp
#include<iostream>
#include"link.h"
using namespace std;
int main()
{
	linkedlist<int>A, B;
	cout << "Please enter 5 numbers of A"<<endl;
	for (int i = 0; i < 5; i++)
	{
		int item;
		cin >> item;
		A.insertFront(item);
	}
	cout << "Please enter 5 numbers of B"<<endl;
	for (int i = 0; i < 5; i++)
	{
		int item;
		cin >> item;
		B.insertFront(item);
	}
	cout << "The list A:" << endl;
	A.reset();
	while (!A.endOfList())
	{
		cout << A.data() << " ";
		A.next();
	}
	cout << endl;
	cout << "The list B:" << endl;
	B.reset();
	while (!B.endOfList())
	{
		cout << B.data() << " ";
		B.next();
	}
	cout << endl;
	cout << "Insert elements from B into A" << endl;
	B.reset();
	while (!B.endOfList())
	{
		A.insertRear(B.data());
		B.next();
	}
	cout << "Now,the list A:" << endl;
	A.reset();
	while (!A.endOfList())
	{
		cout << A.data() << " ";
		A.next();
	}
	cout << endl;
	return 0;
}
  • 10
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
NUDT程序设计模拟测试 1. 请创建一个数据型为T的链表模板List实现以下成员函数: 1) 默认构造函数List(),将该链表初始化为一个空链表(10分) 2) 拷贝构造函数List(const List& list),根据一个给定的链表构造当前链表(10分) 3) 析构函数~List(),释放链表中的所有节点(10分) 4) Push_back(T e)函数,往链表最末尾插入一个元素为e的节点(10分) 5) operator<<()友元函数,将链表的所有元素按顺序输出(10分) 6) operator=()函数实现两个链表的赋值操作(10分) 7) operator+()函数实现两个链表的连接,A=B+C(10分) 2. 请编写main函数,测试该模板的正确性: 1) 用List模板定义一个List型的模板对象int_listB,从键盘读入m个整数,调用Push_back函数将这m个整数依次插入到该链表中;(4分) 2) 用List模板定义一个List型的模板对象int_listC,从键盘读入n个整数,调用Push_back函数将这n个整数依次插入到该链表中;(4分) 3) 用List模板定义一个List型的模板对象int_listA,调用List的成员函数实现A = B + C;(4分) 4) 用cout直接输出int_listA的所有元素(3分) 5) 用List模板定义List型的模板对象double_listA, double_listB, double_listC,重复上述操作。(15分) 3. 输入输出样例: 1) 输入样例 4 12 23 34 45 3 56 67 78 3 1.2 2.3 3.4 4 4.5 5.6 6.7 7.8 2) 输出样例 12 23 34 45 56 67 78 1.2 2.3 3.4 4.5 5.6 6.7 7.8
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值