c++数据结构11Word文档格式.docx
《c++数据结构11Word文档格式.docx》由会员分享,可在线阅读,更多相关《c++数据结构11Word文档格式.docx(34页珍藏版)》请在冰豆网上搜索。
leftChild);
}
2.可以用缩格(或移行)的文本形式(IndentedText)来表示一棵树的结点数据。
例如下面图1所示的树的缩格文本形式如图2所示。
试设计一个算法,将用左子女-右兄弟链表表示的树用缩格文本形式输出。
图1
A
BC
D
E
F
G
H
I
J
K
图2
template<
classType>
classTree;
classTreeNode{//树的结点类
friendclass<
Tree;
private:
Typedata;
//数据
TreeNode<
*firstChild,*nextSibling;
//子女及兄弟指针
public:
TreeNode(Typevalue=0,TreeNode<
*fc=NULL,TreeNode<
*ns=NULL)
:
data(value),firstChild(fc),nextSibling(ns){}//构造函数
TypegetData(){returndata;
}//取得结点数据
*getFirstChild(){returnfirstChild;
}//取得第一个子女地址
*getNextSibling(){returnnextSibling;
}//取得下一个兄弟地址
voidsetData(Typex){data=x;
}//修改结点数据
voidsetFirstChild(TreeNode<
*fc){firstChild=fc;
}//修改第一个子女地址
voidsetNextSibling(TreeNode<
*ns){nextSibling=ns;
}//修改下一个兄弟地址
};
template<
classTree{//树类
*root,*current;
//根指针及当前指针
voidPreOrder(ostream&
out,TreeNode<
*p);
intFind(TreeNode<
*p,Typetarget);
voidRemovesubTree(TreeNode<
intFindParent(TreeNode<
*t,TreeNode<
public:
Tree(){root=current=NULL;
}//构造函数,建立空树
voidBuildRoot(TyperootVal);
intRoot();
//寻找根,使之成为当前结点
intFirstChild();
//寻找当前结点的第一个子女
intNextSibling();
//寻找当前结点的下一个兄弟
intParent();
//寻找当前结点的双亲结点
//树的其他公共操作
……
2.2
将以左子女-右兄弟链表表示的树用缩格文本形式打印出来的算法如下:
#include<
iostream.h>
#include“Tree.h”
voidindentedText(TreeNode<
*t,intk){
if(t!
=NULL){
for(inti=0;
i<
k;
i++)cout<
<
“”;
cout<
t->
getData();
t=t->
getFirstChild();
while(t!
indentedText(t,k+1);
getNextSibling();
}
3.ChunShu
Description
Thegenealogyofafamilycanberepresentedasarootedtree,inwhicheachnodecorrespondstoamemberofthefamily,andeachedgeconnectsamembertohis/herparent.Therootisthefounderofthefamilyandhasnoparentinthegenealogy;
leafnodescorrespondtothosewithnochild.ThedistancebetweentwomembersinagenealogyiscalledaChunShuinKorea,whichisdefinedasthenumberofedgesonthepathbetweenthem.Forexample,inthegenealogyshownbelow,theChunShubetweenpersons1and3is3whiletheChunShubetweenpersons1and5is5.Fromnowon,theChunShubetweenpersoniandpersonjwillbedenotedbyChunShu(i,j).
Arootedtreeinwhicheachnode,unlessitisaleafnode,hasexactlytwochildrenisa2-tree.Inotherwords,a2-treeisabinarytreeinwhicheachnodehaseithertwochildrenornone.Forexample,thetreeshownaboveisa2-tree.
Considerafamilywhosecompletegenealogyisunknown.Whatisknownaboutthegenealogyofthefamilyisthatitisa2-treeandithasnleafnodes.Assumethattheleafnodesarenumberedfrom1,2,...,nintheleft-to-rightorderasshowninthefigureabove.AlsoknownaboutthegenealogyistheChunShubetweeneverypairofleafnodeswhosenumbersareconsecutive;
i.e.,ChunShu(i,i+1)foreveryi(1<
=i<
=n-1)isknown.
Itiswellknownthatonlyfromtheinformationaboutthefamilygivenabove,theChunShubetweenanytwoleafnodescanbecomputed.
YouaretowriteaprogramtocomputetheChunShubetweentwoleafmembersx,y(1<
=x<
y<
=n)givenasaninput.
Fortheexampleabove,youaregivenasinput,n=6,ChunShu(1,2)=3,ChunShu(2,3)=2,ChunShu(3,4)=5,ChunShu(4,5)=3,andChunShu(5,6)=2.Fromthisinformation,youcancomputeChunShu(1,6),thatis,theChunShubetweenx=1andy=6.
Input
TheinputconsistsofTtestcases.Thenumberoftestcases(T)isgivenonthefirstlineoftheinputfile.Thefirstlineofeachtestcasecontainsanintegern(3<
=n<
=1000),thenumberofleafnodes.Thenextlinecontainsasequenceofn?
1integerswhichareChunShu(1,2),ChunShu(2,3),...,ChunShu(n-1,n).Thelastlineofeachtestcasecontainstwodistinctintegersx,y(1<
=n)whicharethenumbersofthetwoleafmembersbetweenwhomtheChunShuistobecomputed.
Output
Printexactlyonelineforeachtestcase.ThelineistocontainanintegerthatistheChunShubetweentwoleafnodes.Thefollowingshowssampleinputandoutputfortwotestcases.
SampleInput
2
6
32532
16
42425
26
SampleOutput
5
#include<
iostream>
fstream>
usingnamespacestd;
intChonSu_count(intChonSu[],intn,intPos_p,intPos_q){
//CountChonSubetweenfamilymemberpandq
intnew_index,old_index;
//theindexoffoldedandoriginalfamilytree
intnew_length=n;
//thenumberoffamilymembersinfoldedfamilytree
intnewPos_p=Pos_p,newPos_q=Pos_q;
//IndicatetheancestorsofPos_pandPos_qinfoldedfamilytree
intdistance=0;
//distancebetweentwomembers
while(Pos_q!
=Pos_p){
new_index=0,old_index=0;
//InitilizetheindextoscantheChonSusequencefrombeginning
while(old_index<
=n-2){
//goovertheunfoldedfamilytreeandfindwheretheChonSuequals2
if(ChonSu[old_index]!
=2)ChonSu[new_index]=ChonSu[old_index],new_index++,old_index++;
else{
//foldthefamilytreebyunitethememberwiththesameparents
if(new_index>
0)ChonSu[new_index-1]--;
if(old_index<
n-2)ChonSu[old_index+1]--;
//forthemembersaside,ChonSushouldminus2
if(Pos_p==old_index+1||Pos_p==old_index+2)newPos_p=new_index+1,distance++;
if(Pos_p>
old_index+2)newPos_p--;
if(Pos_q==old_index+1||Pos_q==old_index+2)newPos_q=new_index+1,distance++;
//whenporqgoesuponelevel,increasethecounteroftheirdistance
if(Pos_q>
old_index+2)newPos_q--;
//findoutthenewpositionoffamilymemberpandqinthefoldedfamilytree
old_index++;
//checkupnextChonSu
new_length--;
//foldthefamilytree
}
Pos_p=newPos_p;
//initializationforanewtimeofscanning
Pos_q=newPos_q;
n=new_length;
returndistance;
//whenpandqmeets,returnthedistancebetweenthem
voidmain(){
ifstreamtestopen("
sample_input.txt"
ios:
in);
if(!
testopen){
cerr<
"
文件不存在"
endl;
exit
(1);
ofstreamoutput("
output.txt"
out);
intnoc;
//numberofcases
testopen>
>
noc;
intn;
//numberoffamilymembers
intk;
//indexofchonsu
intp,q;
//positionoffamilymembers
intdistance;
//distancebetweenfamilymembers
while(noc>
0){
testopen>
n;
int*chonsu=newint[n-1];
for(k=0;
k<
n-1;
k++)
testopen>
chonsu[k];
p>
q;
distance=ChonSu_count(chonsu,n,p,q);
output<
distance<
noc--;
第六章:
集合与字典
1.设有1000个值在1~10000的整数,试设计一个利用散列方法的算法,以最少的数据比较次数和移动次数对它们进行排序。
1.
【解答1】
建立TableSize=10000的散列表,散列函数定义为
intHashTable:
FindPos(constintx){returnx-1;
相应排序算法基于散列表类
#defineDefaultSize10000
#definen1000
classHashTable{//散列表类的定义
enumKindOfEntry{Active,Empty,Deleted};
//表项分类(活动/空/删)
HashTable():
TableSize(DefaultSize){ht=newHashEntry[TableSize];
}//构造函数
~HashTable(){delete[]ht;
}//析构函数
voidHashSort(intA[],intn);
//散列法排序
structHashEntry{//散列表的表项定义
intElement;
//表项的数据,整数
KindOfEntryinfo;
//三种状态:
Active,Empty,Deleted
HashEntry():
info(Empty){}//表项构造函数
HashEntry*ht;
//散列表存储数组
intTableSize;
//数组长度
intFindPos(intx);
//散列函数
voidHashTable<
:
HashSort(intA[],intn){//散列法排序
for(inti=0;
n;
i++){
intposition=FindPos(A[i]);
ht[position].info=Active;
ht[position].Element=A[i];
intpos=0;
TableSize;
i++)
if(ht[i].info==Active)
{cout<
ht[i].Element<
endl;
A[pos]=ht[i].Element;
pos++;
【解答2】
利用开散列的方法进行排序。
其散列表类及散列表链结点类的定义如下:
#defineDefaultSize3334
classHashTable;
//散列表类的前视声明
classListNode{//各桶中同义词子表的链结点(表项)定义
friendclassHashTable;
intkey;
//整数数据
ListNode*link;
//链指针
ListNode(intx):
key(x),link(NULL){}//构造函数
typedefListNode*ListPtr;
//链表指针
classHashTable{//散列表(表头指针向量)定义
HashTable(intsize=DefaultSize)//散列表的构造函数
{TableSize=size;
ht=newListPtr[size];
}//确定容量及创建指针数组
voidHashSort(intA[];
intn)
private:
//容量(桶的个数)
ListPtr*ht;
//散列表定义
intFindPos(intx){returnx/3;
HashSort(intA[];
intn){
ListPtr*p,*q;
inti,bucket,k=0;
for(i=0;
i++){//对所有数据散列,同义词子表是有序链表
bucket=FindPos(A[i]);
//通过一个散列函数计算桶号
p=ht[bucket];
q=newListNode(A[i]);
if(p==NULL||p->
key>
A[i])//空同义词子表或*q的数据最小
{q->
link=ht[bucked];
ht[bucked]=q;
}
elseif(p->
link==NULL||p->
link->
A[i])
{q->
link=p->
link;
p->
link=q;
elsep->
//同义词子表最多3个结点
i++){//按有序次序输出
p=ht[i];
while(p!
=NULL){
cout<
key<
A[k]=p->
key;
k++;
p=p->
lin