mirror of
https://github.com/This-weiyuqing/DSAndOS.git
synced 2026-10-18 03:03:58 +08:00
update
This commit is contained in:
1 parent
16d694ffe3
commit
35e5484d7c
183 files changed
+362
-7145
No files matched your search
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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; //输出值
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user