群体类和群体数据.docx
《群体类和群体数据.docx》由会员分享,可在线阅读,更多相关《群体类和群体数据.docx(51页珍藏版)》请在冰豆网上搜索。
群体类和群体数据
《面向对象得程序设计》实验报告
(
题目:
群体类与群体数据
学生姓名:
学院:
理学院
系别:
数学系
专业:
信息与计算科学
班级:
任课教师:
二〇一一年十一月
1、实验目得
1、了解节点类得声明与实现,学习其使用方法
2、了解链表类得声明与实现,学习其使用方法
3、了解栈类得声明与实现,学习其使用方法
4、了解队列类得声明与实现,学习其使用方法
5、掌握对数组元素排序得方法
6、掌握对数组元素查找得方法
2、实验内容
1.、编写程序Node、h实现例9-5得节点类,并编写测试程序lab9_1、cpp,实现链表得基本操作
2、编写程序link、h实现例9-6得链表类,在测试程序lab_2、cpp中声明两个整型链表A与B,分别插入5元素,然后把B中得元素加入A得尾部
3、编写程序queue.h,用链表实现队列(或栈),在测试程序lab9_3.cpp中声明一个整型队列(或栈)对象,插入5个整数,压入队列(或栈),再依次取出并显示出来、
4、将直接插入排序、直接选择排序、冒泡排序、顺序查找函数封装到第九章得数组类中,作为成员函数,实现并测试这个类。
3、实验程序及结果
1.程序一
//9_5。
h
#ifndefNODE_CLASS
#define NODE_CLASS
//类定义部分
template 〈classT>
classNode
{
private:
Node<T〉 *next; //指向后继节点得指针
public:
Tdata; //数据域
ﻩ //构造函数
Node (constT&item,Node〈T>*ptrnext=NULL);
//在本节点之后插入一个同类节点p
void InsertAfter(Node〈T〉*p);
//删除本节点得后继节点,并返回其地址
Node<T>*DeleteAfter(void);
//获取后继节点得地址
Node};
// 类得实现部分
//构造函数,初始化数据与指针成员
template 〈class T〉
Node〈T>:
:
Node(constT&item, Node<T〉*ptrnext):
ﻩ data(item), next(ptrnext)
{}
//返回私有得指针成员
template〈classT>
Node:
NextNode(void)const
{
returnnext;
}
//在当前节点之后插入一个节点p
template void Node<T>:
:
InsertAfter(Node〈T>*p)
{
p->next=next; //p节点指针域指向当前节点得后继节点
next=p; //当前节点得指针域指向p
}
//删除当前节点得后继节点,并返回其地址
template
Node<T>*Node〈T>:
:
DeleteAfter(void)
{
Node〈T〉*tempPtr=next; //将欲删除得节点地址存储到tempPtr中
if(next==NULL) //如果当前节点没有后继节点,则返回NULL
return NULL;
next=tempPtr-〉next; //使当前节点得指针域指向tempPtr得后继节点
returntempPtr; //返回被删除得节点得地址
}
#endif //NODE_CLASS
//Node.h
#ifndefNODE_LIBRARY
#defineNODE_LIBRARY
#include <iostream>
#include〈cstdlib〉
#include "9_5、h"
usingnamespacestd;
//生成结点:
创建一个结点,数据成员值为item,指向后继结点得指针值为nextPtr
template
Node〈T>*GetNode(constT& item,Node<T>*nextPtr= NULL)
{
Node〈T>*newNode;
//为新结点分配内存空间,然后将item与NextPtr传递给构造函数
newNode= newNode〈T〉(item, nextPtr);
if(newNode ==NULL)//如果分配内存失败,程序中止
{
cerr〈<”Memoryallocationfailure!
"<<endl;
exit
(1);
}
returnnewNode;
}
enumAppendNewline{noNewline,addNewline};
//输出链表
template <classT>
voidPrintList(Node〈T〉 *head, AppendNewlineaddnl =noNewline)
{
// currPtr初始指向表头结点,用于遍历链表
Node<T> *currPtr=head;
//输出结点数据,直到链表结束
while(currPtr!
=NULL)
{
//如果换行标志addl == addNewline,则输出换行符
if(addnl==addNewline)
cout〈< currPtr->data<〈 endl;
else
cout< // 使currPtr指向下一个结点
currPtr=currPtr-〉NextNode();
}
}
//查找结点
//在指针head所指向得链表中查找数据域等于item得结点
//找到则返回TRUE及其前趋结点得地址,否则返回FALSE
template <classT>
int Find(Node{
ﻩNodeprevPtr=NULL;
//通过循环遍历链表,直到表尾
while(currPtr!
=NULL)
ﻩ{
ﻩ //将item与结点得数据域比较,如果相等,则返回,否则继续处理下一个结点
ﻩ if(currPtr—>data ==item)
ﻩ return1;
prevPtr =currPtr; //记录下当前结点得地址
currPtr =currPtr->NextNode();
}
return 0; //找不到时
}
//在表头插入结点
template 〈classT>
voidInsertFront(Node{
//建立新结点,使其指针域指向原链表头结点head,然后更新head
head=GetNode(item,head);
}
//在表尾添加结点
template<classT>
voidInsertRear(Node〈T〉*&head, const T&item)
{
Node<T〉*newNode, *currPtr= head;
//如果链表为空,则插入在表头
if(currPtr==NULL)
InsertFront(head,item);
else
{
//寻找指针域为NULL得结点
while(currPtr-〉NextNode()!
=NULL)
currPtr =currPtr—>NextNode();
//建立新结点并插入在表尾(在currPtr之后)
newNode= GetNode(item);
currPtr—>InsertAfter(newNode);
}
}
//删除链表得第一个结点
template
voidDeleteFront(Node<T〉*&head)
{
Node if(head!
=NULL) //确认链表不空
{
head =head-〉NextNode();//将表头指针head移向第二个结点
delete p; //删除原第一个结点
}
}
//删除链表中第一个数据域等于key得结点
templatevoidDelete(Node<T>*& head, Tkey)
{
// currPtr用于遍历链表,prevPtr跟随其后
Node<T>*currPtr =head,*prevPtr=NULL;
//如果链表为空,则返回
if(currPtr==NULL)
return;
//通过循环遍历链表,直到找到数据域为key得结点,或达到表尾
while(currPtr!
=NULL&&currPtr->data!
=key)
{
//currPtr前行,prevPtr跟随其后
prevPtr =currPtr;
currPtr= currPtr->NextNode();
}
//若currPtr!
=NULL,则currPtr指向得结点数据域为key
if (currPtr!
=NULL)
{
if(prevPtr==NULL)//找到得就是链表第一个结点
head=head->NextNode();
else
//如果找到得就是第二个以后得结点,调用前趋结点得成员函数删除之
prevPtr-〉DeleteAfter();
deletecurrPtr; //释放被删除得结点所占得内存空间
}
}
//在有序链表中插入一个结点
template<classT〉
voidInsertOrder(Node{
//currPtr用于遍历链表,prevPtr跟随其后
Node //prevPtr ==NULL标志着应插入在表头
prevPtr=NULL;
currPtr=head;
//通过循环遍历链表,寻找插入点
while(currPtr!
=NULL)
{
ﻩ//如果item〈当前结点数据,则插入点应在当前结点之前
ﻩif(item <currPtr->data)
ﻩ break;
//currPtr前行,prevPtr跟随其后
prevPtr=currPtr;
currPtr= currPtr—〉NextNode();
}
//完成插入
if(prevPtr== NULL)//如果插入点在表头
InsertFront(head,item);
else
{
// 在prevPtr指向得结点之后插入新结点
newNode=GetNode(item);
prevPtr—〉InsertAfter(newNode);
}
}
//清空链表——删除链表中得所有结点
template<classT〉
voidClearList(Node〈T>*&head)
{
Node<T〉*currPtr, *nextPtr;
// 边遍历边删除结点
currPtr =head;
while(currPtr!
=NULL)
{
//记录下一个结点得地址,删除当前结点
nextPtr=currPtr->NextNode();
deletecurrPtr;
currPtr=nextPtr; //使指针currPtr指向下一个结点
}
head= NULL; //将头结点置为NULL,标志着链表为空
}
#endif //NODE_LIBRARY
//lab9_1。
cpp
#include<iostream>
#include "9_5。
h"
#include"node、h"
usingnamespacestd;
intmain()
{
//将表头指针置为 NULL
Node<int>*head =NULL,*prevPtr,*delPtr;
inti,key,item;
//输入10个整数依次向表头插入
for (i=0;i 〈 10;i++)
{
cin>〉item;
InsertFront(head,item);
}
// 输出链表
cout 〈<"List:
";
PrintList(head,noNewline);
cout <<endl;
//输入需要删除得整数
cout<<”请输入一个需要删除得整数:
”;
cin>> key;
//查找并删除结点
prevPtr =head;
while(Find(head,key,prevPtr) !
=NULL)
{
ﻩ if(prevPtr ==NULL)//找到得就是链表第一个结点
head =head-〉NextNode();
else
//如果找到得就是第二个以后得结点,调用前趋结点得成员函数删除之
delPtr=prevPtr—>DeleteAfter();
deletedelPtr;
}
//输出链表
cout 〈〈"List:
";
PrintList(head,noNewline);
cout<//清空链表
ClearList(head);
}
实验结果如下:
2程序二
//lab9_2.cpp
#include "link、h"
intmain()
{
LinkedList〈int〉A,B;
for(inti=0;i〈5;i++)
{
ﻩA.InsertRear(2*i+1);
ﻩB.InsertRear(2*i+2);
}
A、Reset();
ﻩcout〈<"链表A得元素为:
” ;
ﻩwhile(!
A、EndOfList())
{
ﻩcout<〈A、Data()〈< ”";
A.Next();
ﻩ}
cout<〈 endl;
B。
Reset();
ﻩcout<<”链表B得元素为:
" ;
ﻩwhile(!
B。
EndOfList())
{
ﻩcout<<B。
Data()<<” ";
ﻩﻩB、Next();
}
ﻩcout<< endl;
cout<<"把B中得元素插入A中、、、” <ﻩB、Reset();
while(!
B。
EndOfList())
{
ﻩA、InsertRear(B、Data());
ﻩﻩB.Next();
}
ﻩA。
Reset();
ﻩcout<<"此时,链表A得元素为:
”;
while(!
A、EndOfList())
ﻩ{
ﻩcout <〈 A、Data()<〈" ”;
A。
Next();
}
ﻩcout 〈〈 endl;
}
//link、h
#ifndefLINKEDLIST_CLASS
#define LINKEDLIST_CLASS
#include#include〈cstdlib>
usingnamespacestd;
#ifndefNULL
constintNULL=0;
#endif //NULL
#include"9-3、h
template<classT>
classLinkedList
{
private:
//数据成员:
//表头与表尾指针
Node〈T>*front,*rear;
// 记录表当前遍历位置得指针,由插入与删除操作更新
Node<T>*prevPtr,*currPtr;
//表中得元素个数
intsize;
//当前元素在表中得位置序号。
由函数Reset使用
int position;
//函数成员:
//生成新节点,数据域为item,指针域为ptrNext
Node<T> *GetNode(constT&item,Node<T>*ptrNext=NULL);
//释放节点
voidFreeNode(Node〈T> *p);
// 将链表L 拷贝到当前表(假设当前表为空)。
//被拷贝构造函数、operator=调用
voidCopyList(constLinkedList&L);
public:
// 构造函数
LinkedList(void);
LinkedList(constLinkedList&L);//拷贝构造函数
//析构函数
~LinkedList(void);
// 重载赋值运算符
LinkedList〈T〉&operator=(const LinkedList〈T〉&L);
//检查表得状态
intListSize(void)const; //返回链表中元素个数(size)
intListEmpty(void)const; //size等于0时返回TRUE,否则返回FALSE
//遍历表得函数
voidReset(intpos=0);
//将指针currPtr移动到序号为pos得节点,prevPtr相应移动
//position记录当前节点得序号
voidNext(void);//使prevPtr与currPtr移动到下一个节点
intEndOfList(void)const;
// currPtr等于NULL时返回TRUE,否则返回FALSE
intCurrentPosition(void)const;//返回数据成员position
//插入节点得函数:
插入一个数据域为item得节点
voidInsertFront(constT&item); //在表头插入
voidInsertRear(const T&item);//在表尾添加
void InsertAt(const T&item);//在当前节点之前插入
voidInsertAfter(const T&item);//在当前节点之后插入
//删除节点,释放节点空间,更新prevPtr、currPtr与size
TDeleteFront(void); //删除头节点
voidDeleteAt(void);//删除当前节点
//返回对当前节点成员data得引用(使数据域可以被使用或修改)
T&Data(void);
//清空链表:
释放所有节点得内存空间。
被析构函数、operator=调用
void ClearList(void);
};
template <classT〉
Node:
GetNode(const T&item,
Node<T〉*ptrNext)
{
Node〈T〉*p;
p=new Node(item,ptrNext);
if(p==NULL)
{
cout<〈 ”Memory allocationfailure!
\n";
exit
(1);
}
return p;
}
template 〈class T〉
void LinkedList<T〉:
:
FreeNode(Node<T>*p)
{
deletep;
}
//将L复制到当前链表
templatevoidLinkedList:
:
CopyList(const LinkedList<T〉& L)
{
//P用来遍历L
Node<T> *p=L、front;
intpos;
//将L中得每一个元素插入到当前链表最后
while(p!
=NULL)
{
InsertRear(p->data);
p=p->NextNode();
}
//如果链表空,返回
if (position ==-1)
return;
//在新链表中重新设置prevPtr与currPtr
prevPtr=NULL;
currPtr=front;
for(pos=0;pos!
=position;pos++)
{
prevPtr=currPtr;
currPtr=currPtr-〉NextNode();
}
}
//建立一个新链表,即:
将有关指针设置为空,size为0,position为-1
templateLinkedList<T>:
:
LinkedList(void):
front(NULL),rear(NULL),
prevPtr(NULL),currPtr(NULL), size(0),position(-1)
{}
template〈classT〉
LinkedList<T〉:
:
LinkedList(constLinkedList<T>&L)
{
front=rear=NULL;
prevPtr= currPtr = NULL;
size =0;
position = —1;
CopyList(L);
}
template〈classT>
void