实验名称 |
线性表的链式存储结构 |
专 业 |
软件工程 |
||
姓 名 |
|
学 号 |
|
班 级 |
|
- 实验目的:
1、熟悉链表结构;
2、掌握链表结构上的各种操作;
3、学会运用链表结构求解问题;
- 实验内容:
建立一个单链表,在此链表上实现以下几种操作:
1、求此单链表的长度;
2、在此单链表的第i个元素节点之前插入一个结点;
3、删除此单链表的第i个元素结点;
- 实验设备及软件环境:
Microsoft Word
Eclipse
- 实验过程及结果:
#include<stdio.h>
#include<iostream>
using namespace std;
template<class ElemType>
struct Node
{
ElemType data;
Node<ElemType> *next;
Node();
Node(ElemType item, Node<ElemType> *link=NULL);
};
template<class ElemType>
Node<ElemType>::Node()
{
next=NULL;
}
template<class ElemType>
Node<ElemType>::Node(ElemType item, Node<ElemType> *link)
{
data=item;
next=link;
}
template<class ElemType>
class SimpleLinkList
{
protected:
Node<ElemType> *head;
Node<ElemType> *GetElemPtr(int position) const;
public:
SimpleLinkList();
virtual~SimpleLinkList();
int Length() const;
bool Empty()const;
void Clear();
void Traverse(void(*visit)(const ElemType &)) const;
bool GetElem(int position,ElemType &e) const;
bool SetElem(int position,const ElemType &e);
bool Delete(int position,ElemType &e);
bool Insert(int position,const ElemType &e);
SimpleLinkList(const SimpleLinkList<ElemType>©);
SimpleLinkList<ElemType>&operator=(const SimpleLinkList<ElemType>©);
};
template<class ElemType>
Node<ElemType> *SimpleLinkList<ElemType>::GetElemPtr(int position) const
{
Node<ElemType> *tmpPtr=head;
int pos=0;
while(tmpPtr!=NULL &&pos<position)
{
tmpPtr=tmpPtr->next;
pos++;
}
if(tmpPtr!=NULL&&pos==position)
{
return tmpPtr;
}
else
{
return NULL;
}
}
template<class ElemType>
SimpleLinkList<ElemType>::SimpleLinkList()
{
head=new Node<ElemType>;
}
template<class ElemType>
SimpleLinkList<ElemType>::~SimpleLinkList()
{
Clear();
delete head;
}
template<class ElemType>
int SimpleLinkList<ElemType>::Length() const
{
int count=0;
for(Node<ElemType> *tmpPtr=head->next; tmpPtr!=NULL; tmpPtr=tmpPtr->next)
{
count++;
}
return count;
}
template<class ElemType>
bool SimpleLinkList<ElemType>::Empty()const
{
return head->next==NULL;
}
template<class ElemType>
void SimpleLinkList<ElemType>::Clear()
{
ElemType tmpElem;
while(!Empty())
{
Delete(1,tmpElem);
}
}
template<class ElemType>
void SimpleLinkList<ElemType>::Traverse(void(*visit)(const ElemType &)) const
{
for(Node<ElemType> *tmpPtr=head->next; tmpPtr!=NULL; tmpPtr=tmpPtr->next)
{
(*visit)(tmpPtr->data);
}
}
template<class ElemType>
bool SimpleLinkList<ElemType>::GetElem(int position,ElemType &e) const
{
if(position<1||position>Length())
{
return false;
}
else
{
Node<ElemType> *tmpPtr;
tmpPtr=GetElemPtr(position);
e=tmpPtr->data;
return true;
}
}
template<class ElemType>
bool SimpleLinkList<ElemType>::SetElem(int position,const ElemType &e)
{
if(position<1||position>Length())
{
return false;
}
else
{
Node<ElemType> *tmpPtr;
tmpPtr=GetElemPtr(position);
tmpPtr->data=e;
return true;
}
}
template<class ElemType>
bool SimpleLinkList<ElemType>::Delete(int position,ElemType &e)
{
if(position<1||position>Length())
{
return false;
}
else
{
Node<ElemType> *tmpPtr;
tmpPtr=GetElemPtr(position-1);
Node<ElemType>*nextPtr=tmpPtr->next;
tmpPtr->next=nextPtr->next;
e=nextPtr->data;
return true;
}
}
template<class ElemType>
bool SimpleLinkList<ElemType>::Insert(int position,const ElemType &e)
{
if(position<1||position>Length()+1)
{
return false;
}
else
{
Node<ElemType> *tmpPtr;
tmpPtr=GetElemPtr(position-1);
Node<ElemType> *newPtr;
newPtr=new Node<ElemType>(e,tmpPtr->next);
tmpPtr->next=newPtr;
}
}
int main()
{
int n,i;
SimpleLinkList<int> a1;
printf("你想输入几个数字: \n");
scanf("%d",&n);
for(i=1; i<=n; i++)
{
int s;
scanf("%d",&s);
a1.Insert(i,s);//i为position只代表位置,与data和后继指针无关系。
}
printf("当前链表长为:%d\n",a1.Length());
printf("当前元素为:");
for(i=1; i<a1.Length()+1; i++)
{
int s;
a1.GetElem(i,s);
printf("%d%c",s,i==a1.Length()?'\n':' ');
}
int e,f;
printf("在第几个节点插入节点:");
scanf("%d",&e);
printf("数字为:");
scanf("%d",&f);
a1.Insert(e,f);
printf("当前元素为:");
for(i=1; i<a1.Length(); i++)
{
int s;
a1.GetElem(i,s);
printf("%d%c",s,i==a1.Length()?'\n':' ');
}
printf("删除哪个节点:");
scanf("%d",&e);
a1.Delete(e,f);
printf("%d被删除",f);
printf("当前元素为: ");
for(i=1; i<a1.Length()+1; i++)
{
int s;
a1.GetElem(i,s);
printf("%d%c",s,i==a1.Length()?'\n':' ');
}
}
- 总结:
在这次实验中,我上机体验了链表的功能,在代码书写过程中还存在卡顿的问题,我觉得后期的我还得多加记忆链表部分的代码,以便于以后更好的把链表的东西应用到实际的程序当中,快速记忆代码,才能更完美的应用,我也明白了链表中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起,每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针。如果要访问链表中一个元素,需要从第一个元素开始,一直找到需要的元素位置。但是增加和删除一个元素对于链表数据结构就非常简单了,只要修改元素中的指针就可以了。如果应用需要经常插入和删除元素你就需要用链表。数据结构的学习内容范围光,深度深,我觉得这是我的个人目标和发展方向,我会通过自己的努力继续的学习数据结构的更多内容,不仅是链表
实验成绩: 指导教师: 年 月 日
实验名称 |
栈和队列的实现和应用 |
专 业 |
软件工程 |
||
姓 名 |
|
学 号 |
|
班 级 |
|
一、实验目的:
1. 熟练掌握栈、队列的建立方法;
2.熟练掌握栈和队列基本操作;
3. 栈和队列的实例应用 。
二、实验内容:
1、选用一种存储结构建立栈、队列
2、编写一个程序,读入以升序排列的一系列整数,然后以降序打印出这些整数。一旦读到的整数不大于前面的数,则输入终止,然后将这些整数以降序打印输出。
三、实验设备及软件环境:
Microsoft Word
实验室电脑
CodeBlocks
四、实验过程及结果:
#include<stdio.h>
#include<iostream>
using namespace std;
template<class ElemType>
struct Node
{
ElemType data;
Node<ElemType> *next;
Node();
Node(ElemType item, Node<ElemType> *link=NULL);
};
template<class ElemType>
Node<ElemType>::Node()
{
next=NULL;
}
template<class ElemType>
Node<ElemType>::Node(ElemType item, Node<ElemType> *link)
{
data=item;
next=link;
}
template<class ElemType>
class LinkStack
{
protected:
Node<ElemType> *top;
int count;
public:
LinkStack();
virtual~LinkStack();
int Length() const;
bool Empty()const;
void Clear();
void Traverse(void(*visit)(const ElemType &)) const;
bool Push(const ElemType &e);
bool Top(ElemType &e) const;
bool Pop(ElemType &e);
LinkStack(const LinkStack<ElemType>©);
LinkStack<ElemType>&operator=(const LinkStack<ElemType>©);
};
template<class ElemType>
LinkStack<ElemType>::LinkStack()
{
top=NULL;
count=0;
}
template<class ElemType>
LinkStack<ElemType>::~LinkStack()
//
{
Clear();
}
template<class ElemType>
int LinkStack<ElemType>::Length() const
{
return count;
}
template<class ElemType>
bool LinkStack<ElemType>::Empty()const
{
return top==NULL;
}
template<class ElemType>
void LinkStack<ElemType>::Clear()
{
ElemType tmpElem;
while(!Empty())
{
Pop(tmpElem);
}
}
template<class ElemType>
void LinkStack<ElemType>::Traverse(void(*visit)(const ElemType &)) const
{
Node<ElemType> *tmpPtr;
LinkStack<ElemType>tmpS;
for(tmpPtr=top; tmpPtr!=NULL; tmpPtr=tmpPtr->next)
{
tmpS.Push(tmpPtr->data);
}
for(tmpPtr=tmpS.top; tmpPtr!=NULL; tmpPtr=tmpPtr->next)
{
(*visit)(tmpPtr->data);
}
}
template<class ElemType>
bool LinkStack<ElemType>::Push(const ElemType &e)
{
Node<ElemType> *newTop=new Node<ElemType>(e,top);
if(newTop==NULL)
{
return false;
}
else
{
top=newTop;
count++;
return true;
}
}
template<class ElemType>
bool LinkStack<ElemType>::Top(ElemType &e) const
{
if(Empty())
{
return false;
}
else
{
e=top->data;
return true;
}
}
template<class ElemType>
bool LinkStack<ElemType>::Pop(ElemType &e)
{
if(Empty())
{
return false;
}
else
{
Node<ElemType> *old_top=top;
e=old_top->data;
top=old_top->next;
count--;
delete old_top;
return true;
}
}
template<class ElemType>
LinkStack<ElemType>::LinkStack(const LinkStack<ElemType>©)
{
if(copy.Empty())
{
top=NULL;
count=0;
}
else
{
top=new Node<ElemType>(copy.top->data);
count=copy.count;
Node<ElemType> *buttomPtr=top;
for(Node<ElemType> *tmpPtr=copy.top->next; tmpPtr!=NULL; tmpPtr=tmpPtr->next)
{
buttomPtr->next=new Node<ElemType>(tmpPtr->data);
buttomPtr=buttomPtr->next;
}
}
}
template<class ElemType>
LinkStack<ElemType>&LinkStack<ElemType>::operator=(const LinkStack<ElemType>©)
{
if(©.Empty())
{
top=NULL;
count=0;
}
else
{
Clear();
top=new Node<ElemType>(copy.top->data);
count=copy.count;
Node<ElemType> *buttomPtr=top;
for(Node<ElemType> *tmpPtr=copy.top->next; tmpPtr!=NULL; tmpPtr=tmpPtr->next)
{
buttomPtr->next=new Node<ElemType>(tmpPtr->data);
buttomPtr=buttomPtr->next;
}
}
}
int main()
{
int n,x,h;
LinkStack<int>s;
cout<<"输入数字的个数:"<<endl;
cin>>n;
s.Clear();
for(int i=0;i<n;i++)
{
cin>>x;
if(i==0)
{
s.Push(x);
h=x;
}
else
{
if(x>h)
{
s.Push(x);
h=x;
}
else
{
cout<<"输入错误!"<<endl;
break;
}
}
}
while (!s.Empty())
{
int f;
s.Pop(f);
cout<<f<<"";
}
cout<<endl;
return 0;
}
五、总结:
这一次的实验,我深刻的体会了栈和队列的区别和相同,栈(Stack)是限定只能在表的一端进行插入和删除操作的线性表。队列(Queue)是限定只能在表的一端进行插入和在另一端进行删除操作的线性表。从"数据结构"的角度看,它们都是线性结构,即数据元素之间的关系相同。但它们是完全不同的数据类型。除了它们各自的基本操作集不同外,主要区别是对插入和删除操作的"限定"。
栈和队列是在程序设计中被广泛使用的两种线性数据结构,它们的特点在于基本操作的特殊性,栈必须按"后进先出"的规则进行操作,而队列必须按"先进先出"的规则进行操作。和线性表相比,它们的插入和删除操作受更多的约束和限定,故又称为限定性的线性表结构。可将线性表和栈及队列的插入和删除操作,这一次的学习让我体会到学习数据结构的精髓,我们不仅需要各自掌握每个操作的要领,更需要进行对比和比较,让我们有更多的知识积累,更好的辨析各个块的知识,更好的学习数据结构
实验成绩: 指导教师: 年 月 日
实验名称 |
二叉树的遍历及应用 |
专 业 |
软件工程 |
||
姓 名 |
|
学 号 |
|
班 级 |
|
一、实验目的:
1. 熟练掌握二叉树的建立方法;
2. 熟练掌握二叉树的遍历算法;
3. 掌握二叉树的应用算法
二、实验内容:
1. 编写算法建立一棵二叉树的二叉链表;
2. 输出二叉树的三种遍历序列,包括递归 算法、非递归算法
3. 编写算法统计二叉树结点数、叶子数、深度。
三、实验设备及软件环境:
Microsoft Word
实验室电脑
CodeBlocks
四、实验过程及结果:
#include <iostream>
#include <string>
typedef int T;//树内节点的数据类型
using namespace std;
class BiTree
{
private:
struct BiNode
{
T data;
BiNode *lchild,*rchild,*f;
BiNode(T d)
{
data=d;
lchild=NULL;
rchild=NULL;
f = NULL;
}
};
BiNode *root;
public:
BiTree()
{
root = NULL; ///root=root->rchild=root->rchild=nullptr;
}
~BiTree()
{
}
BiNode *&getRoot() //返回根指针的引用
{
return root;
}
//使用递归创建二叉树
//以二叉排序树的规则建立
bool addBiNode(BiNode *&nodeRoot,T d) //再用函数传递指针的时候 并且要修改这个指针的地址时 要用引用
{
if(nodeRoot == NULL)
{
BiNode *p = new BiNode(d);
nodeRoot = p;
cout << p -> data << " insert success!" << endl;
return true;
}
else if(nodeRoot != NULL && d < nodeRoot -> data)
{
addBiNode(nodeRoot->lchild,d); //往左子树递归
nodeRoot -> lchild -> f = nodeRoot;
}
else if(nodeRoot!=NULL&&d > nodeRoot -> data)
{
addBiNode(nodeRoot->rchild,d); //往右子树递归
nodeRoot -> rchild -> f = nodeRoot;
}
else
{
cout<<"树中已有该数据"<<endl;
return false;
}
}
BiNode *getPtrToRoot()const
{
return root;
}
bool Traverse(const BiNode *b,string type)const
{
if(type=="PreOrderTraverse")
{
cout<<"\n先序遍历的结果为:"<<endl;
PreOrderTraverse(b);
return true;
}
else if(type=="InOrderTraverse")
{
cout<<"\n中序遍历的结果为:"<<endl;
InOrderTraverse(b);
return true;
}
else if(type=="PostOrderTraverse")
{
cout<<"\n后序遍历的结果为:"<<endl;
PostOrderTraverse(b);
return true;
}
else
{
cout<<"遍历类型无效!"<<endl;
return false;
}
}
BiNode * tree_searth(BiNode * x, T k) //用递归查找元素的方法
{
if(x == NULL || k == x->data)
return x;
if(k < x->data)
return tree_searth(x->lchild,k);
else
return tree_searth(x->rchild,k);
}
void f(T k) // 测试父指针
{
BiNode * w;
w = tree_searth(getPtrToRoot(),k);
cout << w -> f -> data << endl;
}
BiNode * minimum(BiNode * x) //找到最小元素
{
while(x->lchild != NULL)
x = x->lchild;
return x;
}
BiNode * manimum(BiNode * x) //找到最大元素
{
while(x->rchild != NULL)
x = x->rchild;
return x;
}
void Insert(T d)
{
addBiNode(getRoot(),d);
}
///还有什么后继和前驱
void Visit2(BiNode * x)
{
cout << x->data << endl;
}
void Visit1(BiNode * x)
{
cout << x << " ";
}
void transplant(BiNode *& x,BiNode * u,BiNode * v) /// 这里面必须用指针的引用
{
if(u -> f == NULL)
x = v;
else if(u == u -> f -> lchild)
u -> f -> lchild = v;
else
u -> f -> rchild = v;
if(v != NULL)
v -> f = u -> f;
}
tree_delete(BiNode *& x, T k)
{
BiNode *z , *y;
z = tree_searth(x,k);
if(z -> lchild == NULL)
transplant(x,z,z -> rchild);
else if(z -> rchild == NULL)
transplant(x,z,z -> lchild);
else
{
y = minimum(z -> rchild);
if (y -> f != z)
{
transplant(x,y,y -> rchild);
y -> rchild = z -> rchild;
y -> rchild -> f = y;
}
transplant(x,z,y);
y -> lchild = z -> lchild;
y -> lchild -> f = y;
}
}
protected:
void Visit(const BiNode *r)const
{
cout<<r->data<<" ";
}
void PreOrderTraverse(const BiNode *nodeRoot)const
{
if(nodeRoot!=NULL)
Visit(nodeRoot);
if(nodeRoot->lchild!=NULL)
PreOrderTraverse(nodeRoot->lchild);
if(nodeRoot->rchild!=NULL)
PreOrderTraverse(nodeRoot->rchild);
}
void InOrderTraverse(const BiNode *nodeRoot)const
{
if(nodeRoot!=NULL)
{
InOrderTraverse(nodeRoot->lchild);
Visit(nodeRoot);
InOrderTraverse(nodeRoot->rchild);
}
}
void PostOrderTraverse(const BiNode *nodeRoot)const
{
if(nodeRoot->lchild!=NULL)
PostOrderTraverse(nodeRoot->lchild);
if(nodeRoot->rchild!=NULL)
PostOrderTraverse(nodeRoot->rchild);
if(nodeRoot!=NULL)
Visit(nodeRoot);
}
};
int main()
{
BiTree b;
b.addBiNode(b.getRoot(),50);
int i;
int arr[9]= {30,40,35,27,100,90,110,95,-999};
bool flag=true;
while(flag)
{
flag=!flag;
for(int j=0; j<9; j++)
{
i=arr[j];
if(i==-999)
break;
b.addBiNode(b.getRoot(),i);
}
}
b.Traverse(b.getPtrToRoot(),"PreOrderTraverse");
b.Traverse(b.getPtrToRoot(),"InOrderTraverse");
b.Traverse(b.getPtrToRoot(),"PostOrderTraverse");
cout << endl;
b.Visit1(b.tree_searth(b.getPtrToRoot(),30));
b.Visit2(b.tree_searth(b.getPtrToRoot(),30));
b.Visit1(b.minimum(b.getPtrToRoot()));
b.Visit2(b.minimum(b.getPtrToRoot()));
b.Visit1(b.manimum(b.getPtrToRoot()));
b.Visit2(b.manimum(b.getPtrToRoot()));
b.f(110);
b.Insert(78) ;
b.Insert(77) ;
b.Traverse(b.getPtrToRoot(),"InOrderTraverse");
b.tree_delete(b.getRoot(),50);
b.Traverse(b.getPtrToRoot(),"InOrderTraverse");
cin.get();
return 0;
}
五、总结:
这次实验主要是通过先序序列建立二叉树,和二叉树的先序、中序、后续遍历算法。通过这次实验,我巩固了二叉树这部分知识,从中体会理论知识的重要性。 在做实验之前,要充分的理解本次实验的理论依据,这样才能达到事半功倍的效果。如果在没有真正理解实验原理之盲目的开始实验,只会浪费时间和精力。例如进行二叉树的遍历的时候,要先理解各种遍历的特点。先序遍历是先遍历根节点,再依次先序遍历左右子树。中序遍历是先中序遍历左子树,再访问根节点,最后中序遍历右子树。而后序遍历则是先依次后续遍历左右子树,再访问根节点。 掌握了这些,在实验中我们就可以融会贯通,举一反三。
所以,这次实验让我懂得了理论知识的重要性,只有领悟了最基本的知识,在实验过程中我们才能够独立的思考,大胆的推断,不断的创新,进而提高动手能力。
实验成绩: 指导教师: 年 月 日
实验名称 |
查找算法的实现和应用 |
专 业 |
软件工程 |
||
姓 名 |
|
学 号 |
|
班 级 |
|
一、实验目的:
1. 熟练掌握顺序查找方法;
2. 熟练掌握二分查找方法即BinSearch();
二、实验内容:
1. 用顺序查找法对表进行查找;
2.用二分查找法对查找表进行查找
3.建立二叉排序树并对该树进行查找
三、实验设备及软件环境:
Microsoft Word
实验室电脑
CodeBlocks
四、实验过程及结果:
#include<iostream>
using namespace std;
template<class ElemType>
struct BinTreeNode
{
ElemType data;
BinTreeNode<ElemType> *leftChild;
BinTreeNode<ElemType> *rightChild;
BinTreeNode()
{
leftChild=rightChild=NULL;
}
BinTreeNode(ElemType &item, BinTreeNode<ElemType> *lChild, BinTreeNode<ElemType> *rChild)
{
data=item;
leftChild=lChild;
rightChild=rChild;
}
};
template<class ElemType,class KeyType>
class BinarySortTree
{
protected:
BinTreeNode<ElemType> *root;
void DestroyHelp(BinTreeNode<ElemType> *&r); ///销毁以r为根二叉排序树
void PreOrderHelp(const BinTreeNode<ElemType> *r)const;///先序
void InOrderHelp(const BinTreeNode<ElemType>*r)const;///中序
void PostOrderHelp(const BinTreeNode<ElemType>*r)const;///后序
int HeightHelp(const BinTreeNode<ElemType> *r) const;///高
int NodeCountHelp(const BinTreeNode<ElemType>*r)const;///结点
int leafCountHelp(const BinTreeNode<ElemType>*r)const;///叶子
BinTreeNode<ElemType>*SearchHelp(const KeyType &key,BinTreeNode<ElemType> *&f)const;///查找关键字为key的数据元素
void DeleteHelp(BinTreeNode<ElemType> *&p);///删除p指向的结点
public:
BinarySortTree();
BinTreeNode<ElemType> *GetRoot()const; ///返回二叉树的根
bool Empty() const;
bool GetElem(const BinTreeNode<ElemType>*cur, ElemType &e)const;///用E返回节点数据元素值
void InOrder()const;///先
void PreOrder()const;///中
void PostOrder()const;///后
int NodeCount()const;///结点个数
int Height()const;///高度
BinTreeNode<ElemType> *Search(const KeyType &key) const;///查找关键字为key的数据元素
bool Insert(const ElemType &e); ///插入数据元素e
bool Delete(const KeyType &key); ///删除关键字为e的数据元素
};
template<class ElemType,class KeyType>
BinarySortTree<ElemType,KeyType>::BinarySortTree()
{
root=NULL;
}
template<class ElemType,class KeyType>
void BinarySortTree<ElemType,KeyType>::DestroyHelp(BinTreeNode<ElemType> *&r)///销毁
{
if(r!=NULL)
{
DestoryHelp(r->leftChild);
DestoryHelp(r->rightChild);
delete r;
r=NULL;
}
}
template<class ElemType,class KeyType>
void BinarySortTree<ElemType,KeyType>::DeleteHelp(BinTreeNode<ElemType> *&p)///删除
{
BinTreeNode<ElemType> *tmpPtr,*tmpF;
if(p->leftChild==NULL && p->rightChild==NULL)
{
delete p;
p=NULL;
}
else if(p->leftChild==NULL)
{
tmpPtr=p;
p=p->rightChild;
delete tmpPtr;
}
else
{
tmpF=p;
tmpPtr=p->leftChild;
while(tmpPtr->rightChild!=NULL)
{
tmpF=tmpPtr;
tmpPtr=tmpPtr->rightChild;
}
p->data=tmpPtr->data;
if(tmpF->rightChild==tmpPtr)
{
DeleteHelp(tmpF->rightChild);
}
else
{
DeleteHelp(tmpF->leftChild);
}
}
}
template<class ElemType,class KeyType>
void BinarySortTree<ElemType,KeyType>::PreOrderHelp(const BinTreeNode<ElemType>*r)const///先序
{
if(r!=NULL)
{
cout<<r->data;
PreOrderHelp(r->leftChild);
PreOrderHelp(r->rightChild);
}
}
template<class ElemType,class KeyType>
void BinarySortTree<ElemType,KeyType>::InOrderHelp(const BinTreeNode<ElemType>*r)const///中序
{
if(r!=NULL)
{
InOrderHelp(r->leftChild);
cout<<r->data;
InOrderHelp(r->rightChild);
}
}
template<class ElemType,class KeyType>
void BinarySortTree<ElemType,KeyType>::PostOrderHelp(const BinTreeNode<ElemType>*r)const///后序
{
if(r!=NULL)
{
PostOrderHelp(r->leftChild);
PostOrderHelp(r->rightChild);
cout<<(r->data);
}
}
template<class ElemType,class KeyType>
int BinarySortTree<ElemType,KeyType>::HeightHelp(const BinTreeNode<ElemType> *r) const///高度
{
int h1=0,h2=0;
if(r==NULL) return 0;
else
{
h1=HeightHelp(r->leftChild);
h2=HeightHelp(r->rightChild);
if(h1>h2) return(h1+1);
else return(h2+1);
}
}
template<class ElemType,class KeyType>
int BinarySortTree<ElemType,KeyType>::NodeCountHelp(const BinTreeNode<ElemType>*r)const///节点个数
{
if(r==NULL) return 0;
else return(NodeCountHelp(r->leftChild)+NodeCountHelp(r->rightChild)+1);
}
template<class ElemType,class KeyType>
int BinarySortTree<ElemType,KeyType>::leafCountHelp(const BinTreeNode<ElemType>*r)const///叶子数
{
if(r==NULL) return 0;
else if(r->leftChild==NULL&&r->rightChild==NULL)
return 1;
else return(leafCountHelp(r->leftChild)+leafCountHelp(r->rightChild));
}
template<class ElemType,class KeyType>
BinTreeNode<ElemType> *BinarySortTree<ElemType,KeyType>::SearchHelp(const KeyType &key,BinTreeNode<ElemType> *&f)const///查找
{
BinTreeNode<ElemType> *p=GetRoot();
f=NULL;
while(p!=NULL && p->data!=key)
{
if(key<p->data)
{
f=p;
p=p->leftChild;
}
else
{
f=p;
p=p->rightChild;
}
}
return p;
}
template<class ElemType,class KeyType>
BinTreeNode<ElemType> *BinarySortTree<ElemType,KeyType>::GetRoot()const///获取根节点
{
return root;
}
template<class ElemType, class KeyType>
bool BinarySortTree<ElemType,KeyType>::Empty()const///判断是否为空
{
return root==NULL;
}
template<class ElemType, class KeyType>
bool BinarySortTree<ElemType,KeyType>::GetElem(const BinTreeNode<ElemType>*cur, ElemType &e)const ///返回某节点数据
{
if(cur==NULL)
return false;
else
{
e=cur->data;
return true;
}
}
template<class ElemType, class KeyType>
void BinarySortTree<ElemType,KeyType>::InOrder()const///先
{
InOrderHelp(root);
}
template<class ElemType, class KeyType>
void BinarySortTree<ElemType,KeyType>::PreOrder()const///中
{
PreOrderHelp(root);
}
template<class ElemType, class KeyType>
void BinarySortTree<ElemType,KeyType>::PostOrder()const///后
{
PostOrderHelp(root);
}
template<class ElemType, class KeyType>
int BinarySortTree<ElemType,KeyType>::NodeCount()const///结点个数
{
return NodeCountHelp(root);
}
template<class ElemType, class KeyType>
int BinarySortTree<ElemType,KeyType>::Height()const///高度
{
return HeightHelp(root);
}
template<class ElemType, class KeyType>
BinTreeNode<ElemType> *BinarySortTree<ElemType,KeyType>::Search(const KeyType &key) const///查找
{
BinTreeNode<ElemType> *f;
return SearchHelp(key,f);
}
template<class ElemType, class KeyType>
bool BinarySortTree<ElemType,KeyType>::Insert(const ElemType &e)///插入
{
BinTreeNode<ElemType>*f; ///指向被查找结点的双亲
if(SearchHelp(e,f)==NULL)
{
BinTreeNode<ElemType> *p=new BinTreeNode<ElemType>;
p->data=e;
if(Empty())
{
root=p;
}
else if(e<f->data)
{
f->leftChild=p;
}
else
{
f->rightChild=p;
}
return true;
}
else return false;
}
template<class ElemType, class KeyType>
bool BinarySortTree<ElemType,KeyType>::Delete(const KeyType &key)///删除
{
BinTreeNode<ElemType>*p,*f;
p=SearchHelp(key,f);
if(p==NULL)
{
return false;
}
else
{
if(f==NULL)///被删除节点为根节点
{
DeleteHelp(root);
}
else if(key<f->data)
{
DeleteHelp(f->leftChild);
}
else
{
DeleteHelp(f->rightChild);
}
return true;
}
}
template<class ElemType,class KeyType>
int SqSerach(ElemType elem[], int n, KeyType key)///顺序查找
{
int i;
for(i=0; i<n&&elem[i]!=key; i++);
if(i<n)
{
return i+1;
}
else
{
return -1;
}
}
template<class ElemType,class KeyType>
int BinSerach(ElemType elem[], int n, KeyType key)///二分查找
{
int count=0;
int low=0,high=n-1;
while(low<=high)
{
int mid=(low+high)/2;
count++;
if(key==elem[mid])
{
return count;
}
else if(key<elem[mid])
{
high=mid-1;
}
else
{
low=mid+1;
}
}
return -1;
}
int main()
{
int arr1[100];
int num, num2,num3,key;
cout<<"输入顺序查找或二分查找的个数"<<endl;
cin>>num;
cout<<"请输入数据"<<endl;
for(int i=0; i<num; i++)
{
cin>>arr1[i];
}
cout<<"要查找的数为: ";
cin>>num2;
cout<<"顺序查找的次数为: ";
cout<<SqSerach(arr1, num, num2);
cout<<" 二分查找的次数为: ";
cout<<BinSerach(arr1, num, num2)<<endl;
BinarySortTree<int,int> ff;
int arr2[100];
cout<<"输入二叉排序树查找个数"<<endl;
cin>>num3;
cout<<"输入元素"<<endl;
for(int i=0;i<num3;i++)
{
cin>>arr2[i];
ff.Insert(arr2[i]);
}
cout<<"输入查找元素:"<<endl;
cin>>key;
cout<<ff.Search(key);
return 0;
}
五、总结:
本次试验是有关查找和排序的一些操作,要求理解二叉排序树的基本概念并实现二叉树的建立、
查找、插入和删除算法。理解有关排序的基本概念;掌握各种排序方法的算法实现思想和存储表示方法;并编写实现快速排序的算法。书上的程序功能还是很全的,具体实现还需要将这些功能连接在一起,添加一些界面。
实验成绩: 指导教师: 年 月 日
实验名称 |
排序方法的比较 |
专 业 |
软件工程 |
||
姓 名 |
|
学 号 |
|
班 级 |
|
一、实验目的:
1.熟练掌握常用的排序方法;
2.对排序方法加以比较。
二、实验内容:
设一组数据,可分别采用直接插入排序法、快速排序法、shell排序、选择排序法、堆排序法、归并排序法进行排序。(至少实现一种)
三、实验设备及软件环境:
Microsoft Word
实验室电脑
CodeBlocks
四、实验过程及结果:
#include<iostream>
using namespace std;
int qk(int a[],int low,int high)
{
int x=a[low];
while(low<high)
{
while(low<high&&a[high]>=x)
high--;
if(low<high)
{
a[low]=a[high];
low++;
}
while(low<high&&a[low]<=x)
low++;
if(low<high)
{
a[high]=a[low];
high--;
}
}
a[low]=x;
return low;
}
void qsort(int a[],int low,int high)
{
if(low<high)
{
int pos=qk(a,low,high);
qsort(a,low,pos-1);
qsort(a,pos+1,high);
}
}
int main()
{ const int len=7;
int a[len]={11,1,478,15,5,6,7};
cout<<"快速排序后的结果为:"<<endl;
qsort(a,0,len-1);
for(int j=0;j<len;j++)
{
cout<<a[j]<<' ';
}
cout<<endl;
}
五、总结:
实验结果表明,选择排序用时普遍比其它算法大,自顶向上合并排序时间普遍较少,尤其是当数据量变得很大的时候,选择排序的速度变得远远不及自顶向上合并排序算法,大出好几百倍.另外,插入排序在当数据量变大时花费的时间也变得很长.快速排序和堆排序处于不确定的情况,不稳定性比较明显.但是是一种比较快的算法。通过本实验,我发现以前经常使用的冒泡排序,选择排序等排序方法在遇到大量的数据的时候显示出来的严重的不足,而自底向上合并排序却显示出了其优越性,尽管合并排序的算法比较难,但它在时间上节省让人发现一切都是值得的.
实验成绩: 指导教师: 年 月 日