数据结构实习题目
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
n( n>20)的阶乘
【问题描述】
大数运算——计算 n 的阶乘( n>=20)。
【基本要求】
(1)数据的表示和存储;
(1.1)累积运算的中间结果和最终的计算结果的数据类型要求是整型——这是问题本身的要求;
( 1.2)试设计合适的存储结构,要求每个元素或结点最多存储数据的 3 位数值。
(2)数据的操作及其实现:
基于设计的存储结构实现乘法操作,要求从键盘上输入 n 值,在屏幕上显示最终计算结果。
【测试数据】
(1) n= 20, n!= 2432902008176640000
(2) n= 30, n!= 265252859812191058636308480000000
#include "stdafx.h"
#include <iostream>
#include<iomanip>
using namespace std;
template <class T>
class Chain;
template <class T>
class ChainNode
{
friend Chain<T>;
private:
T data;
ChainNode<T> *link;
};
template<class T>
class Chain
{
public:
Chain() {first = 0;}// 构造函数
~Chain();// 析构函数
bool IsEmpty() const {return first == 0;} int Length() const;
bool Find(int k, T& x) const;
int Search(const T& x) const;
Chain<T>& Delete(int k, T& x);
Chain<T>& Insert(int k, const T& x);// 判断链表是否为空
// 求链表的长度
// 查找第 k 个元素
// 查找元素x
// 删除第 k 个元素
// 在第 k 个元素之后插入x
void Output(ostream& out) const;// 单链表的输出Chain<T>& Fac(long n);
//求大数阶乘
private:
ChainNode<T> *first;//指向第一个节点};
template<class T>
Chain<T>::~Chain()
{// 删除所有的节点
ChainNode<T> *next;
while (first)
{
next = first->link;
delete first;
first = next;
}
}
template<class T>
bool Chain<T>::Find(int k, T& x) const
{//查找第k个元素,并赋值给x
if (k < 1) return false;
ChainNode<T> *current = first;
int index = 1;
while (index < k && current)
{
current = current->link;
index++;
}
if (current)
{
x = current->data;
return true;
}
return false;
}
template<class T>
int Chain<T>::Search(const T& x) const
{// 查找元素x,返回该元素的下标
ChainNode<T> *current = first;
int index = 1;
while (current && current->data != x)
{
current = current->link;
index++;
}
if (current) return index;
return 0;
}
template<class T>
Chain<T>& Chain<T>::Delete(int k, T& x)
{//删除第k个元素,并赋值给x,返回改变后的链表
ChainNode<T> *p = first;
if (k == 1)
first = first->link;
else
{
ChainNode<T> *q = first;
for (int index = 1; index < k - 1 && q;index++)
q = q->link;
p = q->link;
q->link = p->link;
}
x = p->data;
delete p;
return *this;
}
template<class T>
int Chain<T>::Length() const//返回链表的长度
{
ChainNode<T> *current = first;
int len = 0;
while (current)
{
len++;
current = current->link;
}
return len;
}
template<class T>
Chain<T>& Chain<T>::Insert(int k, const T& x)// 在第k 个元素之后插入x,返回插入后的链表
{
ChainNode<T> *p = first;
for (int index = 1; index < k && p;index++)
p = p->link;
ChainNode<T> *y = new ChainNode<T>;
y->data = x;
if (k)
{
y->link = p->link;
p->link = y;
}
else
{
y->link = first;
first = y;
}
return *this;
}
template<class T>
void Chain<T>::Output(ostream& out) const//输出链表元素
{
ChainNode<T> *current;
int i=0,j=Length();
for (current = first; current;current = current->link)
{
i++;
if(i==j&&j>=1)
{
if(current->link)
out <<setw(3)<<setfill('0')<< current->data << "";
else
out<< current->data << "
";
i=1;
j--;
current=first;
}
}
out<<setw(3)<<setfill('0')<<first->data<<" ";
}
template <class T> // 重载运算符 <<
ostream& operator<<(ostream& out, const Chain<T>& x)
{x.Output(out); return out;}
template <class T>
Chain<T>& Chain<T>::Fac(long n)// 初始化
{
int i=0;
long j=n;
while(j>999)
{
Insert(i,j%1000);
i++;
j=j/1000;
}
Insert(i,j);// 通过插入来建立链表(0,20) //计算
long m=0, k=0;
ChainNode<T> *current;
for(;n>2;n--)
{
for (current = first;current;current = current->link)//?
{
m=k;
k=(current->data*(n-1)+k)/1000;// 向前进位
current->data=(current->data*(n-1)+m)%1000;
if(!current->link&&k>0)//?
{
while(k>999)
{
Insert(Length(),k%1000);
k=k/1000;
}
Insert(Length(),k);
// 链表长度加一
k=0;
break;
}
}
}
return *this;
}
int main()
{
long n;
char ch;
do
{
n: ";
cout<<" 请输入需要阶乘的数字
cin>>n;
Chain<long> a;
a.Fac(n);
cout<<n<<" 的阶乘为 :"<<endl;
cout<<a;
cout<<endl;
cout<<" 是否进行计算:";
cout<<endl;
cin>>ch;
}while(ch=='Y');
return 0;
}
2:
题目:表达式求值
要求:实现关键
栈的使用
两位数以上、负数、小数点?
实现方式
控制台程序
MFC 对话框
#include "stdafx.h"
#include <iostream>
using namespace std;
#include<assert.h>
#include <cstdlib>
#include <math.h>
template<class T>
class Stack
{
public:
Stack(int sz=50);
~Stack()
{
delete[]elements;
}
void Push(const T &x); //压入栈
bool Pop(T&x);// 弹出栈
T GetTop(void)const; // 取栈顶元素
bool IsEmpty()const
{
return(top==-1)?true:false;
}
bool IsFull()// 判断栈是否满
{
return (top==MaxSize-1)?true:false;
}
int GetSize()const//?
{
return top+1;
}
void MakeEmpty()
{
top=-1;
}
private:
T*elements;
int top;
int MaxSize;
void overflowProcess();//栈溢出处理
};
template<class T>
Stack<T>::Stack(int sz)
{
top=-1;
MaxSize=sz;
elements=new T[MaxSize];// 创建栈的数组空间
assert(elements!=NULL);//判断动态内存是否分配成功是否}
template<class T>
void Stack<T>::Push(const T&x)
{
if(IsFull()==true)
{
overflowProcess();
}
top++;
elements[top]=x;
}
template<class T>
bool Stack<T>::Pop(T&x)
{
if(IsEmpty()==true)
{
return false;
}
x=elements[top--];
return true;
}
template<class T>
T Stack<T>::GetTop(void)const//返回栈顶元素
{
if(IsEmpty()==true)
{
cerr<<"栈为空 !"<<endl;
exit(1);
}
return elements[top];
}
template<class T>
void Stack<T>::overflowProcess() //溢出处理
{
T *newArray=new T[2*MaxSize]; // 扩充栈的空间
for(int i=0;i<=top;i++)
{
MaxSize=2*MaxSize;
newArray[i]=elements[i];
}
delete[]elements;// 释放原来旧的空间
}
class Calculater//计算的声明
{
public:
Calculater(){}
void Run();// 执行表达式计算
void Clear();// 清空处理
private:
Stack<double>s;// 声明double 型的栈对象
void AddOperand(double value);// 把数值压入栈中
bool GetOperand(double &left,double& right);// 判断取操作数操作是否成功void DoOperator(char ch);// 进行操作
};
void Calculater::AddOperand(double value)
{
s.Push(value);
}
bool Calculater::GetOperand(double&left,double&right)
{
if(s.IsEmpty()==true){
cerr<<"缺少右操作数"<<endl;
return false;
}
s.Pop(right);
if(s.IsEmpty()==true){
cerr<<"缺少左操作数"<<endl;
return false;
}
s.Pop(left);
return true;
}
void Calculater::Clear()
{
s.MakeEmpty();
}
void Calculater::DoOperator(char ch){
double left,right,value;
bool result;
result=GetOperand(left,right);
if(result==true)
{
switch(ch)
{
case'+':
value=left+right;
s.Push(value);
break;
case'-':
value=left-right;
s.Push(value);
break;
case'*':
value=left*right;
s.Push(value);
break;
case'/':
if(right==0.0)
{
cerr<<"Divide by 0!"<<endl;
Clear();
}
else
{
value=left/right;
s.Push(value);
}
break;
}
cout<<"="<<s.GetTop()<<" ";
}
else
Clear();
}
void Calculater::Run()
{
char ch;
double newOperand;
while(cin>>ch,ch!='#')
{
switch(ch)
{
case '+':case'-':case'*':case'/'://是操作数,执行计算
DoOperator(ch);
break;
default:// 其实也是一种case,只不过就是指“除了指定的几个case以外的其他
情况”,不是操作符
cin.putback(ch);// 字符放回输入流
cin>>newOperand;// 重新读取操作数,一个操作数的第一个字
符 AddOperand(newOperand);// 将操作数放入栈中
}
}
}
int main()
{
Calculater call;
cout<<"输入计算表达式:";
call.Run();
return 0;
}
3.题目 :
题目:二叉树基本算法的实现
功能要求:
键盘输入二叉树结点序列,创建一棵二叉树
实现SwapTree 方法,以根结点为参数,交换每个结点的左子树和右子树(提示:
前序递归)
实现 Find 方法,查找值为 key 的结点,并输出该结点的所有祖先结点你可以选择:
对BinaryTree 模板进行功能扩充;
自己定义并实现二叉树类
要求键盘输入二叉树结点序列
结点序列可以是前序,也可以是层次
空结点以 #表示
//binarytree.h
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include<iostream.h>
template<class T>
class BinaryTreeNode//二叉树结点
{
//friend BinaryTree<T>;
public:
BinaryTreeNode(){LeftChild=RightChild=0;}
BinaryTreeNode(const T&e)
{
data=e;
LeftChild=RightChild=0;
}
BinaryTreeNode(const T&e,BinaryTreeNode *l,BinaryTreeNode *r) {
data=e;
LeftChild=l;
RightChild=r;
}
public:
T data;
BinaryTreeNode<T>*LeftChild,*RightChild;
};
template<class T>
class BinaryTree
{
friend BinaryTreeNode<T>;
public:
BinaryTree()
{
root=0;
}
~BinaryTree(){}
bool IsEmpty()const
{
return ((root)?false:true);
}
void Creat();
void PreOrder(void (*Visit)(BinaryTreeNode<T>*u))// 前序遍历
{
PreOrder(Visit,root);
}
void InOrder(void (*Visit)(BinaryTreeNode<T>*u))// 中序遍历
{
InOrder(Visit,root);
}
void PostOrder(void (*Visit)(BinaryTreeNode<T>*u))// 后序遍历{
PostOrder(Visit,root);
}
void LevelOrder(void(*Visit)(BinaryTreeNode<T>*u))// 层次遍历{
PreOrder(Output,root);
cout<<endl;
}
void InOutput()// 中序输出
{
InOrder(Output,root);
cout<<endl;
}
void Postput()// 后序输出
{
PostOrder(Output,root);
cout<<endl;
}
void LevelOutPut()// 层次输出
{
LevelOrder(Output);
cout<<endl;
}
int Height()const// 计算树的高度
{
return Height(root);
}
int Size()const// 计算树的大小
{
return Size(root);
}
BinaryTreeNode<T>*iCreat();
void swap()// 交换左右节点
{
swap(root);
}
int leave()// 计算叶子节点个数
{
return leave(root);
}
int noleave()////计算非叶子节点个数
{
return noleave(root);
}
private:
BinaryTreeNode<T>*root;
void PreOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t); void InOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t); void PostOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t); //void LevelOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t); static void Output(BinaryTreeNode<T>* t)// 输出树的所有节点 {
cout<<t->data <<" ";
}
int Height(BinaryTreeNode<T>*t)const;
int Size(BinaryTreeNode<T>*t)const;
void swap(BinaryTreeNode<T>*t);
int leave(BinaryTreeNode<T>*t);
int noleave(BinaryTreeNode<T>*t);
};
template<class T>
int BinaryTree<T>::Height(BinaryTreeNode<T>*t)const
{
if(!t) return 0;
int hl=Height(t->LeftChild);
int hr=Height(t->RightChild);
if(hl>hr) return ++hl;
else return ++hr;
}
template<class T>
int BinaryTree<T>::Size(BinaryTreeNode<T>*t)const
{
if(!t) return0;
int sl=Size(t->LeftChild);
int sr=Size(t->RightChild);
return (1+sl+sr);
}
template<class T>
BinaryTreeNode<T>*BinaryTree<T>::iCreat( )
T ch;
cin>>ch;
BinaryTreeNode<T> * root;
if(ch=='#')
{
root=NULL;
}
else
{
root=new BinaryTreeNode<T>;
root->data=ch;
root->LeftChild=this->iCreat();
root->RightChild=this->iCreat();
}
return root;
}
template<class T>
void BinaryTree<T>::Creat()
{
this->root = iCreat();
}
template<class T>
void BinaryTree<T>::PreOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t) {
if(t)
{
Visit(t);
PreOrder(Visit,t->LeftChild);
PreOrder(Visit,t->RightChild);
}
}
template<class T>
void BinaryTree<T>::InOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t) {
if(t)
InOrder(Visit,t->LeftChild);
Visit(t);
InOrder(Visit,t->RightChild);
}
}
template<class T>
void BinaryTree<T>::PostOrder(void(*Visit)(BinaryTreeNode<T>*u),BinaryTreeNode<T>*t) {
if(t)
{
PostOrder(Visit,t->LeftChild);
PostOrder(Visit,t->RightChild);
Visit(t);
}
}
template<class T>
void BinaryTree<T>::swap(BinaryTreeNode<T> *t)
{
BinaryTreeNode<T> *temp;
if(!t) return;
else
{
temp=t->LeftChild;
t->LeftChild=t->RightChild;
t->RightChild=temp;
swap(t->LeftChild);
swap(t->RightChild);
}
}
template<class T>
int BinaryTree<T>::leave(BinaryTreeNode<T>*t)
{
if(!t) return 0;
if(t->LeftChild==0&&t->RightChild==0)
return 1;
int leafl=leave(t->LeftChild);
int leafr=leave(t->RightChild);
return leafl+leafr;
}
template<class T>
int BinaryTree<T>::noleave(BinaryTreeNode<T> *t)
if(!t) return 0;
if(!t->LeftChild&&!t->RightChild)
return 1;
int leafl=noleave(t->LeftChild);
int leafr=noleave(t->RightChild);
return leafl+leafr+1;
}
#endif
#include "stdafx.h"
#include"binarytree.h"
#include <iostream.h>
void main()
{
cout<<"输入二叉树 :"<<endl;
BinaryTree<char> Tree;
Tree.Creat();
//cout<<" 前序遍历 :";
//Tree.PreOutput();
cout<<"中序遍历 :";
Tree.InOutput();
cout<<"后序遍历 :";
Tree.Postput();
cout<<"二叉树的叶节点数目为:";
cout<<Tree.leave()<<endl;
Tree.swap();
cout<<"交换前序遍历:";
//Tree.PreOutput();
}
实习题目 4.
任务:输入一棵二叉树的前序遍历序列和中序遍历序列,重构这棵二叉
树功能要求:
在题目三的基础之上,增加一个方法,重构这棵二叉树
要求以图示效果,层次输出这棵二叉树
//bintree.h
#ifndef BINTREE_H
#define BINTREE_H
#include<iostream.h>
#include"queue.h"
template<class T>
class BinaryTree;
template<class T>// 二叉树的二叉链表
class BinaryTreeNode
{
friend BinaryTree<T>;
public:
BinaryTreeNode(){LeftChild=RightChild=0;}//构造函数
BinaryTreeNode(const T&e)
{
data=e;
LeftChild=RightChild=0;
}
BinaryTreeNode(const T&e,BinaryTreeNode *l,BinaryTreeNode *r)
{
data=e;
LeftChild=l;
RightChild=r;
}
private:
T data;
BinaryTreeNode<T>*LeftChild,*RightChild;
};
template<class T>
class BinaryTree
{
public:
BinaryTree()// 构造函数空树
{
root=0;
}
~BinaryTree(){}
bool IsEmpty()const
{
return ((root)?false:true);
}
//void BinaryTree<T>::LevelOrder(void(* Visit)(BinaryTreeNode<T>*u));
void LevelOrder(void(BinaryTree<T>::* Visit)(BinaryTreeNode<T>*u));// 层次访问 ,在访问某一层结点时把下一层结点记忆在队列(尾)中,然后在访问在队头的结点
void LevelOutPut()
{
if(!root)// 空树
{
return;
}
cout<<root->data;
LevelOrder(Output);
cout<<endl;
}
BinaryTreeNode<T>*createBinaryTree(T *VLR,T*LVR,int n)// 构造二叉树前中 n 为元素个数
{
if(n==0)
return NULL;
int k=0;
while(VLR[0]!=LVR[k])// 在中序前序结合找根
{
k++;
}
BinaryTreeNode<T>*t=new BinaryTreeNode<T>(VLR[0]);//根结点为t
t->LeftChild=createBinaryTree(VLR+1,LVR,k);//从前序VLR+1 开始对中序0~k-1 左子序列的k 个元素递归建立左子树
t->RightChild=createBinaryTree(VLR+k+1,LVR+k+1,n-k-1);//从前序V LR+k+1开始对中序k+1~n-1 左子序列的 n-k-1 个元素递归建立右子树
return t;
}
BinaryTreeNode<T>*root;
void Output(BinaryTreeNode<T>* t)
{
if(t->LeftChild||t->RightChild)// 左或又子树不为空
{
if(t->LeftChild)
cout<<t->LeftChild->data;
else
cout<<"#";
if(t->RightChild)
cout<<t->RightChild->data;
else
cout<<"#";
}
}
};
template<class T>
void BinaryTree<T>::LevelOrder(void (BinaryTree<T>::*Visit)(BinaryTreeNode<T> *u))
//void BinaryTree<T>::LevelOrder(void(* Visit)(BinaryTreeNode<T>*u))
{
LinkedQueue<BinaryTreeNode<T>*>Q;
BinaryTreeNode<T> *p=root;
Q.EnQueue(p);// 根节点进队
while(!Q.IsEmpty ())
{
Q.DeQueue(p);// 根节点出队
(this->*Visit)(p);// 访问根结点
if(p->LeftChild!=NULL)
Q.EnQueue(p->LeftChild);// 左子女进队
if(p->RightChild!=NULL)
Q.EnQueue(p->RightChild); //右子女进队
}
}
#endif
//queqe.h
#ifndef QUEQE_H
#define QUEQE_H// 单链表的链式队列
template<class T>
class LinkedQueue;
template<class T>
class Node
{
friend LinkedQueue<T>;
private:
T data;
Node<T>*link;
};
template<class T>
class LinkedQueue
{
public:
LinkedQueue()// 构造函数
{
front=rear=0;// 建立空队列
}
~LinkedQueue();// 析构函数
bool IsEmpty()const
{
return ((front)?false:true);
}
LinkedQueue<T>&EnQueue(const T &x);//往队尾队列中插入元素 LinkedQueue<T>&DeQueue(T&x);// 从队头删除元素
private:
Node<T>*front;
Node<T>*rear;
};
template<class T>
LinkedQueue<T>::~LinkedQueue()//析构函数的实现
{
Node<T>*next;
while(front)
{
next=front->link;
delete front;
front=next;
}
}
template<class T>
LinkedQueue<T>&LinkedQueue<T>::EnQueue(const T &x)
{
Node<T>*p=new Node<T>;
p->data=x;
p->link=0;
if (front)
{
rear->link=p;// 在列尾添加新的结点
}
else// 队列为空,新结点成为第一个结点
{
front=p;
}
rear=p;
return *this;
}
template<class T>
LinkedQueue<T>&LinkedQueue<T>::DeQueue( T&x)//队头结点删去{
Node<T>*p=front;// 暂存队头结点
x=front->data;
front=front->link;// 队头修改
delete p;
return*this;
}
#endif
#include "stdafx.h"
#include"binarytree.h"
#include <iostream.h>
void main()
{
BinaryTree<char> Tree;//char 类型的
int n;
cout<<"二叉树中元素个数:";
cin>>n;
char *L=new char[n];
char *R=new char[n];
cout<<"前序序列为 :";
int i=0,j=0;
while(i<n)
{
cin>>L[i];
i++;
}
cout<<"中序序列为 :";
while(j<n)
{
cin>>R[j];
j++;
}
Tree.root=Tree.createBinaryTree(L,R,n);
cout<<"层次遍历 :";
Tree.LevelOutPut();
delete[]L;
delete[]R;
}
实习题目 5.
最优二叉树
基本要求:对Huffman 树的方法进行扩充,实现如下功能:1)
键盘输入一个字符串,统计每个字符出现的频率;2)输出每
个字符的 Huffman 编码
3)计算并输出WPL
提高要求:改键盘输入为读文件(任何类型)
//huffmantree.h
#ifndef HUFFMANTREE_H
#define HUFFMANTREE_H
#include <iostream.h>
#include "minheap.h"
#include <stdlib.h>//
const int MaxN = 100;
template <class Type>
class HuffmanTree;
template <class Type>
class HuffmanTreeNode// 树结点的类定义
{
//friend class HuffmanTree;
public:
int arrkey;
Type data;// 结点数据
HuffmanTreeNode <Type>*leftChild, *rightChild, *parent;
};
template <class Type>
class HuffmanCodeNode
{
//friend class HuffmanTree;
public:
HuffmanTreeNode <Type> *dataptr;
int bit[MaxN];
int start;
};
template <class Type>
class HuffmanTree
{
//friend class HuffmanTreeNode;
//friend class HuffmanCodeNode;
public:
HuffmanTree(){};
HuffmanTree(Type weight[], int n);
HuffmanCode();// 求 huffman 编码
protected:
HuffmanTreeNode <Type> *hfTree;
HuffmanCodeNode <Type> *hfCode;
int currentSize;
void MergeTree(HuffmanTreeNode <Type> &bt1, HuffmanTreeNode <Type>&bt2, HuffmanTreeNode <Type> *pt)// 合并二叉树
{
pt->leftChild = &bt1;
pt->rightChild = &bt2;
pt->data = bt1.data + bt2.data;
pt->parent = NULL;
bt1.parent = pt; bt2.parent = pt;
}
};
template <class Type>
HuffmanTree <Type> :: HuffmanTree(Type weight[], int n)//n个权值为W[1]....
{
HuffmanTreeNode <Type> *firstchild, *secondchild, *parent;
HuffmanTreeNode <Type> *TNode;
if(n > MaxN)
{
cout<<"Error!"<<endl;exit(-1);
}
currentSize = n;
hfCode = new HuffmanCodeNode <Type> [n];
TNode = new HuffmanTreeNode <Type> [n];
for(int i = 0;i < n;i++)// 森林各颗树初始化
{
hfCode[i].dataptr = &TNode[i];
TNode[i].data = weight[i];
TNode[i].arrkey = i;
TNode[i].parent = TNode[i].leftChild = TNode[i].rightChild = NULL;
}
MinHeap <HuffmanTreeNode <Type> > hp(TNode,n);
for(i = 0;i < n-1;i++)
{
parent = new HuffmanTreeNode <Type>;
firstchild = hp.RemoveMin();
secondchild = hp.RemoveMin();
MergeTree(*firstchild, *secondchild, parent);
hp.Insert(*parent);
}
hfTree = parent;
}
template <class Type>
HuffmanTree <Type> :: HuffmanCode()
{
HuffmanCodeNode <Type> *cd = new HuffmanCodeNode<Type>;
HuffmanTreeNode <Type> *child, *parent;
for(int i=0;i < currentSize;i++)
{
cd->start = currentSize -1;
child = hfCode[i].dataptr;
parent = child->parent;
while(parent != NULL)
{
if(parent->leftChild == child)//向左标记为0
cd->bit[cd->start] = 0;
else
cd->bit[cd->start] = 1; // 向右标记为0
child = parent;
parent = parent->parent;
cd->start--;
}
for(int k=0;k < currentSize;k++)
{
hfCode[i].bit[k] = cd->bit[k];
hfCode[i].start = cd->start+1;
}
}
cout<<endl<<" 输出: "<<endl;
for(i=0;i<currentSize;i++)
{cout<<hfCode[i].dataptr->data<<":";
for(int j=hfCode[i].start;j<currentSize;j++)
cout<<hfCode[i].bit[j];
cout<<endl;
}
}
#endif
//minheap.h
#ifndef MINHEAP_H
#define MINHEAP_H
template <class Type>
class MinHeap
{
//friend class Type;
public:
MinHeap(int maxSize);
MinHeap(Type a[], int n);// 构造函数
~MinHeap(){delete []heapArr;}//析构函数
int Insert(Type &d);// 把数据元素插入最小堆中
Type * RemoveMin();// 删除堆顶上最小元素private:
Type * heapArr;// 存放堆中元素的数组
Type * Arr;
Type * saveNode[100];
int saveNodeCount;
int heapCurrentSize;// 堆中当前元素个数
int heapMaxSize;// 最多元素个数
void siftDown(int p);//从p下滑调整为最小堆
void siftUp(int p);// 从 p 上滑调整为最小堆
};
template <class Type>
MinHeap <Type> :: MinHeap(int maxSize)
heapMaxSize = maxSize;
heapArr = new Type [heapMaxSize];// 创建堆存储空间
heapCurrentSize = 0;// 当前元素个数为0
}
template<class Type>
MinHeap<Type>::MinHeap(Type a[],int n)
{
heapMaxSize = n;
heapArr = new Type[heapMaxSize];
saveNodeCount=n;
for(int j=0;j<n;j++)
{
heapArr[j]=a[j];
}
Arr=a;
heapCurrentSize=n;// 复制堆数组,建立当前大小
int i=(heapCurrentSize-2)/ 2;// 找最初调整位置,即最后分支节点
while(i>=0)
{
siftDown(i);// 再向前换一个分支结点
i--;
}
/*if (heapMaxSize%2==0)
{
for(int k=0;k<n;k++)
{
heapArr[k]=heapArr[k+1];
}
}*/
}//?
template <class Type>
void MinHeap<Type>::siftDown(const int start)//堆下滑,从开始结点开始
{
int i=start,j;
Type temp=heapArr[i];
j=2*i+1;// 左子女位置
while(j<=heapCurrentSize-1)
{
if(j<=heapCurrentSize-1 && heapArr[j].data > heapArr[j+1].data) j++;
if(temp.data <=heapArr[j].data) break;// else {heapArr[i]=heapArr[j];i=j;j=2*j+1;}//小不作调整小上移
}
heapArr[i]=temp;
template<class Type>
int MinHeap<Type>::Insert(Type&d)
{
heapArr[heapCurrentSize]=d;
heapArr[heapCurrentSize].arrkey=saveNodeCount;
siftUp(heapCurrentSize);
heapCurrentSize++;
saveNode[saveNodeCount++]=&d;
return 1;
}
template <class Type>
void MinHeap<Type>::siftUp(int p)
{
int j=p,i;
Type temp = heapArr[j];
i=(j-1)/ 2;
while(j>0)
{
if(heapArr[i].data<=temp.data)
break;
else
{
heapArr[j]=heapArr[i];
j=i;
i=(j-1)/ 2;
}
}
heapArr[j]=temp;
}
template<class Type>
Type * MinHeap<Type>::RemoveMin()
{
Type * temp=new HuffmanTreeNode<char>;
(*temp)=heapArr[0];
heapArr[0]= heapArr[heapCurrentSize-1];
heapCurrentSize--;
siftDown(0);
if(temp->arrkey>-1 && temp->arrkey<heapMaxSize)
return &Arr[temp->arrkey];
else if(temp->arrkey>=heapMaxSize && temp->arrkey<100) return saveNode[temp->arrkey];
}
#endif
#include "stdafx.h"
#include "huffmantree.h"
#include <iostream.h>
int main(int argc, char* argv[])
{
char weight[MaxN];
int n;
cout<<" 字符个数 :";
cin >> n;
cout<<" 输入一串字符:";
for(int i=0;i<n;i++)
cin>>weight[i];
HuffmanTree <char> a (weight,n);
a.HuffmanCode();
return 0;
}
实习题目 6.
要求:自己设计图并编码进行存储,同时输出图的两种遍历方式的结果。
实现关键
图的存储方式的选择
图的遍历算法
实现方式
控制台程序
输出图的两种遍历方式的结果
//graph.h
#ifndef GRAPH_H
#define GRAPH_H
#include <iostream.h>
const int defaultVertices=20;// 默认最大顶点数
const int maxweight=100000000000000;
#include "queue.h"
template<class T,class E>
class Graph// 图的类定义
{
public:
Graph(){}
~Graph(){}
bool GraphIsempty()const// 判断图空否
{
if(numEdges==0)
return true;
else
return false;
}
bool GraphIsfull()const// 判断图满否
{
if(numVertices==maxVertices||numEdges==maxVertices*(maxVertices-1)/2)//?
return true;
else
return false;
}
int NumberOfVertices()// 返回当前的点顶数
{
return numVertices;
}
int NumberOfEdges()// 返回当前边数
{
return numEdges;
}
int maxVertices;// 最大顶点数
int numEdges;// 当前边数
int numVertices;
};
template<class T,class E>
class Graphmtx:public Graph<T,E>// 图的邻接矩阵类定义
{
public:
Graphmtx(int sz=defaultVertices);//构造函数
~Graphmtx()// 析构函数
{
delete[]Vertices;
for(int i=0; i< maxVertices; i++)
delete[]Edge[i];
}
T getValue(int i)// 取定点 i 的值, i 不合理返回0
{
return(i>=0&&i<= numVertices)?Vertices[i]:NULL;
}
E getWeight(int v1,int v2)// 取边( v1,v2)上的权值
{
return(v1!=-1&&v2!=-1)?Edge[v1][v2]:0;
}
int getfirstNeighbor(int v);//取顶点的v 的第一个邻接顶点
int getnextNeighbor(int v,int w);// 取 v 的邻接顶点 w 的下一个邻接顶点 bool insertVertex(const T&vertex);
bool insertEdge(int v1,int v2,E cost);// 插入边的权值为 cost
bool removeVertex(int v);
bool removeEdege(int v1,int v2);
int getVertexPos(T vertex)// 给出顶点vertex 在图中的位置
{
for(int i=0;i<numVertices;i++)
{
if(Vertices[i]==vertex)
return i;
}
return -1;
}
friend istream& operator>>(istream&in,Graphmtx<T,E>&G);
friend ostream& operator<<(ostream&out,Graphmtx<T,E>&G);
void DFS(Graphmtx<T,E>&G,const T&v);// 从图顶点v 出发,对图G 进行深度优先遍历的主过程深度优先生成树
void DFS(Graphmtx<T,E>&G,int v,bool visited[]);// 从顶点位置 v 出发,以深度优先的次序访问所有可读入的尚未访问过的顶点。
子过程
// 算法中用到辅助数
组 visited ,对已访问过的顶点做访问标记
void BFS(Graphmtx<T,E>&G,const T&v);//从图顶点v 出发,对图 G 进行广度优先遍历的过程
private:
T * Vertices;// 顶点表
E **Edge;// 邻接矩阵
};
template<class T,class E>//// 图的邻接矩阵构造函数
Graphmtx<T,E>::Graphmtx(int sz)
{
maxVertices=sz;
numVertices=0;
numEdges=0;
int i,j;
Vertices=new T [maxVertices];// 顶点表数组
Edge=(E**)new E*[maxVertices];//邻接矩阵数组
for(i=0;i<maxVertices;i++)
{
Edge[i]=new E[maxVertices];
}
for(i=0;i<maxVertices;i++)// 邻接矩阵初始化
{。