This commit is contained in:
weiyuqing committed 2023-07-28 22:53:00 +08:00
1 parent 16d694ffe3
commit 35e5484d7c
183 files changed
+362 -7145

No files matched your search

+40
View File
@@ -0,0 +1,40 @@
//算法5.1 中序遍历的递归算法
#include<iostream>
using namespace std;
typedef struct BiNode{ //二叉链表定义
char data;
struct BiNode *lchild,*rchild;
}BiTNode,*BiTree;
//用算法5.3 先序遍历的顺序建立二叉链表
void CreateBiTree(BiTree &T){
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin >> ch;
if(ch=='#') T=NULL; //递归结束,建空树
else{
T=new BiTNode;
T->data=ch; //生成根结点
CreateBiTree(T->lchild); //递归创建左子树
CreateBiTree(T->rchild); //递归创建右子树
} //else
} //CreateBiTree
void InOrderTraverse(BiTree T){
//中序遍历二叉树T的递归算法
if(T){
InOrderTraverse(T->lchild);
cout << T->data;
InOrderTraverse(T->rchild);
}
}
void main(){
BiTree tree;
cout<<"请输入建立二叉链表的序列:\n";
CreateBiTree(tree);
cout<<"中序遍历的结果为:\n";
InOrderTraverse(tree);
cout<<endl;
}
+69
View File
@@ -0,0 +1,69 @@
//算法5.10 构造赫夫曼树
#include<iostream>
using namespace std;
typedef struct
{
int weight;
int parent,lchild,rchild;
}HTNode,*HuffmanTree;
void Select(HuffmanTree HT,int len,int &s1,int &s2)
{
int i,min1=0x3f3f3f3f,min2=0x3f3f3f3f;//先赋予最大值
for(i=1;i<=len;i++)
{
if(HT[i].weight<min1&&HT[i].parent==0)
{
min1=HT[i].weight;
s1=i;
}
}
int temp=HT[s1].weight;//将原值存放起来,然后先赋予最大值,防止s1被重复选择
HT[s1].weight=0x3f3f3f3f;
for(i=1;i<=len;i++)
{
if(HT[i].weight<min2&&HT[i].parent==0)
{
min2=HT[i].weight;
s2=i;
}
}
HT[s1].weight=temp;//恢复原来的值
}
void CreatHuffmanTree(HuffmanTree &HT,int n)
{
//构造赫夫曼树HT
int m,s1,s2,i;
if(n<=1) return;
m=2*n-1;
HT=new HTNode[m+1]; //0号单元未用,所以需要动态分配m+1个单元,HT[m]表示根结点
for(i=1;i<=m;++i) //将1~m号单元中的双亲、左孩子,右孩子的下标都初始化为0
{ HT[i].parent=0; HT[i].lchild=0; HT[i].rchild=0; }
cout<<"请输入叶子结点的权值:\n";
for(i=1;i<=n;++i) //输入前n个单元中叶子结点的权值
cin>>HT[i].weight;
/*――――――――――初始化工作结束,下面开始创建赫夫曼树――――――――――*/
for(i=n+1;i<=m;++i)
{ //通过n-1次的选择、删除、合并来创建赫夫曼树
Select(HT,i-1,s1,s2);
//在HT[k](1≤k≤i-1)中选择两个其双亲域为0且权值最小的结点,
// 并返回它们在HT中的序号s1和s2
HT[s1].parent=i;
HT[s2].parent=i;
//得到新结点i,从森林中删除s1,s2,将s1和s2的双亲域由0改为i
HT[i].lchild=s1;
HT[i].rchild=s2 ; //s1,s2分别作为i的左右孩子
HT[i].weight=HT[s1].weight+HT[s2].weight; //i 的权值为左右孩子权值之和
} //for
} // CreatHuffmanTree
void main()
{
HuffmanTree HT;
int n;
cout<<"请输入叶子结点的个数:\n";
cin>>n;
CreatHuffmanTree(HT,n);
cout<<"哈夫曼树建立完毕!\n";
}
+105
View File
@@ -0,0 +1,105 @@
//算法5.11 根据赫夫曼树求赫夫曼编码
#include<iostream>
using namespace std;
typedef struct
{
int weight;
int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char **HuffmanCode;
void Select(HuffmanTree HT,int len,int &s1,int &s2)
{
int i,min1=0x3f3f3f3f,min2=0x3f3f3f3f;//先赋予最大值
for(i=1;i<=len;i++)
{
if(HT[i].weight<min1&&HT[i].parent==0)
{
min1=HT[i].weight;
s1=i;
}
}
int temp=HT[s1].weight;//将原值存放起来,然后先赋予最大值,防止s1被重复选择
HT[s1].weight=0x3f3f3f3f;
for(i=1;i<=len;i++)
{
if(HT[i].weight<min2&&HT[i].parent==0)
{
min2=HT[i].weight;
s2=i;
}
}
HT[s1].weight=temp;//恢复原来的值
}
//用算法5.10构造赫夫曼树
void CreatHuffmanTree(HuffmanTree &HT,int n)
{
//构造赫夫曼树HT
int m,s1,s2,i;
if(n<=1) return;
m=2*n-1;
HT=new HTNode[m+1]; //0号单元未用,所以需要动态分配m+1个单元,HT[m]表示根结点
for(i=1;i<=m;++i) //将1~m号单元中的双亲、左孩子,右孩子的下标都初始化为0
{ HT[i].parent=0; HT[i].lchild=0; HT[i].rchild=0; }
cout<<"请输入叶子结点的权值:\n";
for(i=1;i<=n;++i) //输入前n个单元中叶子结点的权值
cin>>HT[i].weight;
/*――――――――――初始化工作结束,下面开始创建赫夫曼树――――――――――*/
for(i=n+1;i<=m;++i)
{ //通过n-1次的选择、删除、合并来创建赫夫曼树
Select(HT,i-1,s1,s2);
//在HT[k](1≤k≤i-1)中选择两个其双亲域为0且权值最小的结点,
// 并返回它们在HT中的序号s1和s2
HT[s1].parent=i;
HT[s2].parent=i;
//得到新结点i,从森林中删除s1,s2,将s1和s2的双亲域由0改为i
HT[i].lchild=s1;
HT[i].rchild=s2 ; //s1,s2分别作为i的左右孩子
HT[i].weight=HT[s1].weight+HT[s2].weight; //i 的权值为左右孩子权值之和
} //for
}
// CreatHuffmanTree
void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)
{
//从叶子到根逆向求每个字符的赫夫曼编码,存储在编码表HC中
int i,start,c,f;
HC=new char*[n+1]; //分配n个字符编码的头指针矢量
char *cd=new char[n]; //分配临时存放编码的动态数组空间
cd[n-1]='\0'; //编码结束符
for(i=1;i<=n;++i)
{ //逐个字符求赫夫曼编码
start=n-1; //start开始时指向最后,即编码结束符位置
c=i;
f=HT[i].parent; //f指向结点c的双亲结点
while(f!=0)
{ //从叶子结点开始向上回溯,直到根结点
--start; //回溯一次start向前指一个位置
if(HT[f].lchild==c)
cd[start]='0'; //结点c是f的左孩子,则生成代码0
else
cd[start]='1'; //结点c是f的右孩子,则生成代码1
c=f;
f=HT[f].parent; //继续向上回溯
} //求出第i个字符的编码
HC[i]=new char[n-start]; // 为第i 个字符编码分配空间
strcpy(HC[i], &cd[start]); //将求得的编码从临时空间cd复制到HC的当前行中
}
delete cd; //释放临时空间
} // CreatHuffanCode
void show(HuffmanTree HT,HuffmanCode HC)
{
for(int i=1;i<=sizeof(HC)+1;i++)
cout<<HT[i].weight<<"编码为"<<HC[i]<<endl;
}
void main()
{
HuffmanTree HT;
HuffmanCode HC;
int n;
cout<<"请输入叶子结点的个数:\n";
cin>>n; //输入赫夫曼树的叶子结点个数
CreatHuffmanTree(HT,n);
CreatHuffmanCode(HT,HC,n);
show(HT,HC);
}
+201
View File
@@ -0,0 +1,201 @@
#include<iostream>
#include<string>
#define ERROR -1
#define MAXSIZE 100
using namespace std;
typedef struct BiTNode{ //二叉树的二叉链表存储表示
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
typedef struct{ // 字符栈定义
char *base;
char *top;
int stacksize;
}SqStack;
typedef struct{ //树栈定义
BiTree *base;
BiTree *top;
int stacksize;
}BiTreeStack;
void InitStack(SqStack &S){ //字符栈初始化
S.base=new char[MAXSIZE];
if(!S.base) exit(-1);
S.top=S.base;
S.stacksize=MAXSIZE;
}
void InitBiTreeStack(BiTreeStack &S){ //树栈初始化
S.base=new BiTree[MAXSIZE];
if(!S.base) exit(-1);
S.top=S.base;
S.stacksize=MAXSIZE;
}
void Push(SqStack &S,char e) //字符栈入栈
{
if(S.top-S.base==S.stacksize) return ;
*S.top=e;
S.top++;
}
void PushBiTree(BiTreeStack &S,BiTree e) //树栈入栈
{
if(S.top-S.base==S.stacksize) return ;
*S.top=e;
S.top++;
}
void Pop(SqStack &S,char &e) //字符栈出栈
{
if(S.top==S.base) return;
e=*--S.top;
}
void PopBiTree(BiTreeStack &S,BiTree &e) //树栈出栈
{
if(S.top==S.base) return;
e=*--S.top;
}
char GetTop(SqStack &S) //字符栈得到栈顶函数
{
if(S.top==S.base) exit(1);
return *(S.top-1);
}
char Precede(char t1,char t2)
{ /* 根据教科书表3.1,判断两符号的优先关系 */
char f;
switch(t2)
{
case '+':if(t1=='('||t1=='#')
f='<';
else
f='>';
break;
case '-':if(t1=='('||t1=='#')
f='<';
else
f='>';
break;
case '*':if(t1=='*'||t1=='/'||t1==')')
f='>';
else
f='<';
break;
case '/':if(t1=='*'||t1=='/'||t1==')')
f='>';
else
f='<';
break;
case '(':if(t1!=')')
f='<';
break;
case')':if(t1=='(')
f='=';
else
f='>';
break;
case'#':if(t1=='#')
f='=';
else
f='>';
}
return f;
}
int In(char c)
{ /* 判断c是否为运算符 */
switch(c)
{
case '+':
case'-':
case'*':
case '/':
case'#':
case '(':
case')':return 1;break;
default:return 0;
}
}
int GetValue(char theta,int a,int b) //进行运算的函数
{
int c;
switch(theta)
{
case '+':c=a+b;break;
case'-':c=a-b;break;
case'*':c=a*b;break;
case'/':c=a/b;break;
default:
break;
}
return c;
}
void CreateExpTree(BiTree &T,BiTree a,BiTree b,char ch){ //简单二叉树的创建
T=new BiTNode;
T->data=ch;
T->lchild=a;
T->rchild=b;
}
void InitExpTree(BiTree &T) //算法5.12 表达式树的创建
{
SqStack OPTR;
BiTreeStack EXPT;
char ch,theta,x;
BiTree a,b;
InitStack(OPTR);Push(OPTR,'#');
InitBiTreeStack(EXPT);cin>>ch;
while(ch!='#'||GetTop(OPTR)!='#'){
if(!In(ch)){CreateExpTree(T,NULL,NULL,ch);PushBiTree(EXPT,T);cin>>ch;}//*q
else
switch(Precede(GetTop(OPTR),ch)){
case'<':
Push(OPTR,ch);cin>>ch;
break;
case'>':
Pop(OPTR,theta);
PopBiTree(EXPT,b);PopBiTree(EXPT,a);
CreateExpTree(T,a,b,theta); //*
PushBiTree(EXPT,T);
break;
case'=':
Pop(OPTR,x);cin>>ch;
break;
}
}
}
int EvaluateExTree(BiTree T){ //算法5.13 表达式树的求值
int lvalue,rvalue;
lvalue=rvalue=0;
if(T->lchild==NULL&&T->rchild==NULL)
return T->data-'0';
else{
lvalue=EvaluateExTree(T->lchild);
rvalue=EvaluateExTree(T->rchild);
return GetValue(T->data,lvalue,rvalue); //运算函数
}
}
void main()
{
cout<<"请输入算术表达式,并以#结束,中间计算过程要是个位数."<<endl;
BiTree T;
InitExpTree(T); //创建表达式树
cout<<EvaluateExTree(T)<<endl; //输出值
}
+97
View File
@@ -0,0 +1,97 @@
//算法5.2 中序遍历的非递归算法
#include<iostream>
using namespace std;
//二叉树的二叉链表存储表示
typedef struct BiNode
{
char data; //结点数据域
struct BiNode *lchild,*rchild; //左右孩子指针
}BiTNode,*BiTree;
//链栈的定义
typedef struct StackNode
{
BiTNode data;
struct StackNode *next;
}StackNode,*LinkStack;
//用算法5.3 先序遍历的顺序建立二叉链表
void CreateBiTree(BiTree &T)
{
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin >> ch;
if(ch=='#') T=NULL; //递归结束,建空树
else{
T=new BiTNode;
T->data=ch; //生成根结点
CreateBiTree(T->lchild); //递归创建左子树
CreateBiTree(T->rchild); //递归创建右子树
} //else
} //CreateBiTree
void InitStack(LinkStack &S)
{
//构造一个空栈S,栈顶指针置空
S=NULL;
}
bool StackEmpty(LinkStack S)
{
if(!S)
return true;
return false;
}
void Push(LinkStack &S,BiTree e)
{
//在栈顶插入元素*e
StackNode *p=new StackNode;
p->data=*e;
p->next=S;
S=p;
}
void Pop(LinkStack &S,BiTree e)
{
if(S!=NULL)//原书上写的是if(S==NULL)return ERROR;
{
*e=S->data;
StackNode *p=S;
S=S->next;
delete p;
}
}
void InOrderTraverse1(BiTree T)
{
// 中序遍历二叉树T的非递归算法
LinkStack S; BiTree p;
BiTree q=new BiTNode;
InitStack(S); p=T;
while(p||!StackEmpty(S))
{
if(p)
{
Push(S,p); //p非空根指针进栈,遍历左子树
p=p->lchild;
}
else
{
Pop(S,q); //p为空根指针退栈,访问根结点,遍历右子树
cout<<q->data;
p=q->rchild;
}
} // while
} // InOrderTraverse
void main()
{
BiTree tree;
cout<<"请输入建立二叉链表的序列:\n";
CreateBiTree(tree);
cout<<"中序遍历的结果为:\n";
InOrderTraverse1(tree);
cout<<endl;
}
+44
View File
@@ -0,0 +1,44 @@
//算法5.3 先序遍历的的顺序建立二叉链表
#include<iostream>
using namespace std;
//二叉树的二叉链表存储表示
typedef struct BiNode
{
char data; //结点数据域
struct BiNode *lchild,*rchild; //左右孩子指针
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T)
{
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin >> ch;
if(ch=='#') T=NULL; //递归结束,建空树
else{
T=new BiTNode;
T->data=ch; //生成根结点
CreateBiTree(T->lchild); //递归创建左子树
CreateBiTree(T->rchild); //递归创建右子树
} //else
} //CreateBiTree
//用算法5.1 中序遍历的递归算法
void InOrderTraverse(BiTree T)
{
//中序遍历二叉树T的递归算法
if(T){
InOrderTraverse(T->lchild);
cout << T->data;
InOrderTraverse(T->rchild);
}
}
void main()
{
BiTree tree;
cout<<"请输入建立二叉链表的序列:\n";
CreateBiTree(tree);
cout<<"所建立的二叉链表中序序列:\n";
InOrderTraverse(tree);
cout<<endl;
}
+62
View File
@@ -0,0 +1,62 @@
//算法5.4 复制二叉树
#include<iostream>
using namespace std;
//二叉树的二叉链表存储表示
typedef struct BiNode
{
char data; //结点数据域
struct BiNode *lchild,*rchild; //左右孩子指针
}BiTNode,*BiTree;
//用算法5.3建立二叉链表
void CreateBiTree(BiTree &T)
{
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin >> ch;
if(ch=='#') T=NULL; //递归结束,建空树
else{
T=new BiTNode;
T->data=ch; //生成根结点
CreateBiTree(T->lchild); //递归创建左子树
CreateBiTree(T->rchild); //递归创建右子树
} //else
} //CreateBiTree
void Copy(BiTree T, BiTree &NewT)
{
if(T==NULL )
{ //如果是空树,递归结束
NewT=NULL;
return;
}
else
{
NewT=new BiTNode;
NewT->data= T->data; //复制根结点
Copy(T->lchild, NewT->lchild); //递归复制左子树
Copy(T->rchild, NewT->rchild); //递归复制右子树
} //else
} //CopyBiTree
//用算法5.1 中序遍历的递归算法
void InOrderTraverse(BiTree T)
{
//中序遍历二叉树T的递归算法
if(T){
InOrderTraverse(T->lchild);
cout << T->data;
InOrderTraverse(T->rchild);
}
}
void main()
{
BiTree tree,new_tree;
cout<<"请输入建立二叉树的序列:\n";
CreateBiTree(tree);
Copy(tree,new_tree);
cout<<"复制得到的新树的中序序列:\n";
InOrderTraverse(new_tree);
cout<<endl;
}
+47
View File
@@ -0,0 +1,47 @@
//算法5.5 计算二叉树的深度
#include<iostream>
using namespace std;
//二叉树的二叉链表存储表示
typedef struct BiNode
{
char data; //结点数据域
struct BiNode *lchild,*rchild; //左右孩子指针
}BiTNode,*BiTree;
//用算法5.3建立二叉链表
void CreateBiTree(BiTree &T)
{
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin >> ch;
if(ch=='#') T=NULL; //递归结束,建空树
else{
T=new BiTNode;
T->data=ch; //生成根结点
CreateBiTree(T->lchild); //递归创建左子树
CreateBiTree(T->rchild); //递归创建右子树
} //else
} //CreateBiTree
int Depth(BiTree T)
{
int m,n;
if(T == NULL ) return 0; //如果是空树,深度为0,递归结束
else
{
m=Depth(T->lchild); //递归计算左子树的深度记为m
n=Depth(T->rchild); //递归计算右子树的深度记为n
if(m>n) return(m+1); //二叉树的深度为m 与n的较大者加1
else return (n+1);
}
}
void main()
{
BiTree tree;
cout<<"请输入建立二叉链表的序列:\n";
CreateBiTree(tree);
cout<<"数的深度为:"<<Depth(tree)<<endl;
}
+41
View File
@@ -0,0 +1,41 @@
//算法5.6 统计二叉树中结点的个数
#include<iostream>
using namespace std;
//二叉树的二叉链表存储表示
typedef struct BiNode
{
char data; //结点数据域
struct BiNode *lchild,*rchild; //左右孩子指针
}BiTNode,*BiTree;
//用算法5.3建立二叉链表
void CreateBiTree(BiTree &T)
{
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin >> ch;
if(ch=='#') T=NULL; //递归结束,建空树
else{
T=new BiTNode;
T->data=ch; //生成根结点
CreateBiTree(T->lchild); //递归创建左子树
CreateBiTree(T->rchild); //递归创建右子树
} //else
} //CreateBiTree
int NodeCount(BiTree T)
{
if(T==NULL) return 0; // 如果是空树,则结点个数为0,递归结束
else return NodeCount(T->lchild)+ NodeCount(T->rchild) +1;
//否则结点个数为左子树的结点个数+右子树的结点个数+1
}
void main()
{
BiTree tree;
cout<<"请输入建立二叉链表的序列:\n";
CreateBiTree(tree);
cout<<"结点个数为:"<<NodeCount(tree)<<endl;
}
+66
View File
@@ -0,0 +1,66 @@
//算法5.7 以结点P为根的子树中序线索化
#include<iostream>
using namespace std;
//二叉树的二叉线索类型存储表示
typedef struct BiThrNode
{
char data; //结点数据域
struct BiThrNode *lchild,*rchild; //左右孩子指针
int LTag,RTag;
}BiThrNode,*BiThrTree;
//全局变量pre
BiThrNode *pre=new BiThrNode;
//用算法5.3建立二叉链表
void CreateBiTree(BiThrTree &T)
{
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin >> ch;
if(ch=='#') T=NULL; //递归结束,建空树
else
{
T=new BiThrNode;
T->data=ch; //生成根结点
CreateBiTree(T->lchild); //递归创建左子树
CreateBiTree(T->rchild); //递归创建右子树
} //else
} //CreateBiTree
void InThreading(BiThrTree p)
{
//pre是全局变量,初始化时其右孩子指针为空,便于在树的最左点开始建线索
if(p)
{
InThreading(p->lchild); //左子树递归线索化
if(!p->lchild)
{ //p的左孩子为空
p->LTag=1; //给p加上左线索
p->lchild=pre; //p的左孩子指针指向pre(前驱)
}
else
p->LTag=0;
if(!pre->rchild)
{ //pre的右孩子为空
pre->RTag=1; //给pre加上右线索
pre->rchild=p; //pre的右孩子指针指向p(后继)
}
else
pre->RTag=0;
pre=p; //保持pre指向p的前驱
InThreading(p->rchild); //右子树递归线索化
}
}//InThreading
void main()
{
pre->RTag=1;
pre->rchild=NULL;
BiThrTree tree;
cout<<"请输入建立二叉链表的序列:\n";
CreateBiTree(tree);
InThreading(tree);
cout<<"线索化完毕!\n";
}
+85
View File
@@ -0,0 +1,85 @@
//算法5.8 带头结点的中序线索化
#include<iostream>
using namespace std;
//二叉树的二叉线索类型存储表示
typedef struct BiThrNode
{
char data; //结点数据域
struct BiThrNode *lchild,*rchild; //左右孩子指针
int LTag,RTag;
}BiThrNode,*BiThrTree;
//全局变量pre
BiThrNode *pre=new BiThrNode;
//用算法5.3建立二叉链表
void CreateBiTree(BiThrTree &T)
{
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin >> ch;
if(ch=='#') T=NULL; //递归结束,建空树
else
{
T=new BiThrNode;
T->data=ch; //生成根结点
CreateBiTree(T->lchild); //递归创建左子树
CreateBiTree(T->rchild); //递归创建右子树
} //else
} //CreateBiTree
//用算法5.7 以结点P为根的子树中序线索化
void InThreading(BiThrTree p)
{
//pre是全局变量,初始化时其右孩子指针为空,便于在树的最左点开始建线索
if(p)
{
InThreading(p->lchild); //左子树递归线索化
if(!p->lchild)
{ //p的左孩子为空
p->LTag=1; //给p加上左线索
p->lchild=pre; //p的左孩子指针指向pre(前驱)
}
else
p->LTag=0;
if(!pre->rchild)
{ //pre的右孩子为空
pre->RTag=1; //给pre加上右线索
pre->rchild=p; //pre的右孩子指针指向p(后继)
}
else
pre->RTag=0;
pre=p; //保持pre指向p的前驱
InThreading(p->rchild); //右子树递归线索化
}
}//InThreading
void InOrderThreading (BiThrTree &Thrt,BiThrTree T)
{
//中序遍历二叉树T,并将其中序线索化,Thrt指向头结点
Thrt=new BiThrNode; //建头结点
Thrt->LTag=0; //头结点有左孩子,若树非空,则其左孩子为树根
Thrt->RTag=1; //头结点的右孩子指针为右线索
Thrt->rchild=Thrt; //初始化时右指针指向自己
if(!T) Thrt->lchild=Thrt; //若树为空,则左指针也指向自己
else
{
Thrt->lchild=T; pre=Thrt; //头结点的左孩子指向根,pre初值指向头结点
InThreading(T); //调用算法5.7,对以T为根的二叉树进行中序线索化
pre->rchild=Thrt; //算法5.7结束后,pre为最右结点,pre的右线索指向头结点
pre->RTag=1;
Thrt->rchild=pre; //头结点的右线索指向pre
}
} //InOrderThreading
void main()
{
pre->RTag=1;
pre->rchild=NULL;
BiThrTree tree,Thrt;
cout<<"请输入建立二叉链表的序列:\n";
CreateBiTree(tree);
InOrderThreading(Thrt,tree);
cout<<"线索化完毕!\n";
}
+108
View File
@@ -0,0 +1,108 @@
//算法5.9 遍历中序线索二叉树
#include<iostream>
using namespace std;
//二叉树的二叉线索类型存储表示
typedef struct BiThrNode
{
char data; //结点数据域
struct BiThrNode *lchild,*rchild; //左右孩子指针
int LTag,RTag;
}BiThrNode,*BiThrTree;
//全局变量pre
BiThrNode *pre=new BiThrNode;
//用算法5.3建立二叉链表
void CreateBiTree(BiThrTree &T)
{
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin >> ch;
if(ch=='#') T=NULL; //递归结束,建空树
else
{
T=new BiThrNode;
T->data=ch; //生成根结点
CreateBiTree(T->lchild); //递归创建左子树
CreateBiTree(T->rchild); //递归创建右子树
} //else
} //CreateBiTree
//用算法5.7以结点P为根的子树中序线索化
void InThreading(BiThrTree p)
{
//pre是全局变量,初始化时其右孩子指针为空,便于在树的最左点开始建线索
if(p)
{
InThreading(p->lchild); //左子树递归线索化
if(!p->lchild)
{ //p的左孩子为空
p->LTag=1; //给p加上左线索
p->lchild=pre; //p的左孩子指针指向pre(前驱)
}
else
p->LTag=0;
if(!pre->rchild)
{ //pre的右孩子为空
pre->RTag=1; //给pre加上右线索
pre->rchild=p; //pre的右孩子指针指向p(后继)
}
else
pre->RTag=0;
pre=p; //保持pre指向p的前驱
InThreading(p->rchild); //右子树递归线索化
}
}//InThreading
//用算法5.8带头结点的中序线索化
void InOrderThreading (BiThrTree &Thrt,BiThrTree T)
{
//中序遍历二叉树T,并将其中序线索化,Thrt指向头结点
Thrt=new BiThrNode; //建头结点
Thrt->LTag=0; //头结点有左孩子,若树非空,则其左孩子为树根
Thrt->RTag=1; //头结点的右孩子指针为右线索
Thrt->rchild=Thrt; //初始化时右指针指向自己
if(!T) Thrt->lchild=Thrt; //若树为空,则左指针也指向自己
else
{
Thrt->lchild=T; pre=Thrt; //头结点的左孩子指向根,pre初值指向头结点
InThreading(T); //调用算法5.7,对以T为根的二叉树进行中序线索化
pre->rchild=Thrt; //算法5.7结束后,pre为最右结点,pre的右线索指向头结点
pre->RTag=1;
Thrt->rchild=pre; //头结点的右线索指向pre
}
} //InOrderThreading
void InOrderTraverse_Thr(BiThrTree T)
{
//T指向头结点,头结点的左链lchild指向根结点,可参见线索化算法5.8。
//中序遍历二叉线索树T的非递归算法,对每个数据元素直接输出
BiThrTree p;
p=T->lchild; //p指向根结点
while(p!=T) //空树或遍历结束时,p==T
{
while(p->LTag==0) //沿左孩子向下
p=p->lchild; //访问其左子树为空的结点
cout<<p->data;
while(p->RTag==1&&p->rchild!=T)
{
p=p->rchild; //沿右线索访问后继结点
cout<<p->data;
}
p=p->rchild;
}
} //InOrderTraverse_Thr
void main()
{
pre->RTag=1;
pre->rchild=NULL;
BiThrTree tree,Thrt;
cout<<"请输入建立二叉链表的序列:\n";
CreateBiTree(tree);
InOrderThreading(Thrt,tree);
cout<<"中序遍历线索二叉树的结果为:\n";
InOrderTraverse_Thr(Thrt);
cout<<endl;
}