数据结构实验报告(三)

实验报告3 树
1)顺序二叉树

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <string.h>
#include <math.h>
#define MAXSIZE 20
//顺序二叉树
using namespace std;
typedef int Elemtype;
typedef struct SqBinode
{
    Elemtype data[MAXSIZE];
} SqBinode,SqBiTree;
typedef struct
{
    int level;//第几层
    int order;//本层序号,(level,order)类似于(i,j)
} position;
void initBiTree(SqBiTree &bt)
{
    for (int i=0; i<MAXSIZE; i++)
    {
        bt.data[i]=NULL;
    }
}
int createBiTree(SqBiTree &bt)
{
    cout<<"无节点处请输入0,输入完毕请输入-999"<<endl;
    int i=0,n;
    cin>>n;
    while (n!=-999&&i<=MAXSIZE)
    {
        bt.data[i]=n;
        i++;
        if (i!=0&&bt.data[(i+1)/2-1]==NULL&&bt.data[i]!=NULL)
        {
            cout<<"存在双亲为空且自身为空且不为根节点的点!"<<endl;
            return 0;
        }
        cin>>n;

    }

    if (i>MAXSIZE)
        return 0;
    return 1;
}
int BiTreeEmpty(SqBiTree bt)
{
    if (bt.data[0]==NULL)
        return 1;
    else
        return 0;
}
int BiTreeDepth(SqBiTree bt)
{
    int n=0,i=0;//N为节点个数
   for (i=0;i<MAXSIZE-1;i++)
    {
        if (bt.data[i]!=NULL)
            n++;

    }
    int k=0;
    do
    {
        k++;
    }
    while (pow(2,k-1)<=n);
    return k-1;
}

Elemtype Root(SqBiTree bt)
{
    if (bt.data[0])
        return bt.data[0];
    else
        return 0;
}
void initPosition(position &p,int a,int b)
{
    p.level=a;
    p.order=b;
}
void Value(SqBiTree bt,Elemtype &e,position p)
{
    //根据E的位置P找到它
    int n=pow(2,p.level-1)+p.order-2;
    e=bt.data[n];
}

void Assign(SqBiTree &bt,position &p,Elemtype e)
{
    int x=pow(2,p.level-1)+p.order-2;
    bt.data[x]=e;
}

void print(SqBiTree bt)
{
    int i,j,k=0;
    for (i=1;i<=BiTreeDepth(bt); i++)
    {
        cout<<""<<i<<"";
        for (j=1; j<=pow(2,i-1); j++)
        {
            if (bt.data[k]!=NULL)
                cout<<"("<<j<<","<<bt.data[k]<<") ";
            k++;
        }
        cout<<endl;
    }
}
void valueP(int i,int j,position &p)
{
    p.level=i;
    p.order=j;
}

int Parent(SqBiTree &bt,Elemtype e)
{
    if (bt.data[0]==e)
        return NULL;
    int i=1;
    while (bt.data[i]!=e && i<=MAXSIZE-1) i++;
    return bt.data[(i+1)/2-1];
}
int LeftChild(SqBiTree &bt,Elemtype e)
{
//1.叶子结点无左孩子 2.非叶子结点的左孩子是2*i
    int i=0;
    while (bt.data[i]!=e && i<=MAXSIZE-1) i++;
//循环停止时应当是找到了值为E的结点,但不知道是叶子节点还是非叶子
    if (bt.data[2*i+1]!=NULL)
        return bt.data[2*i+1];
    else
        return NULL;
}
int RightChild(SqBiTree &bt,Elemtype e)
{
//1.叶子结点无左孩子 2.非叶子结点的左孩子是2*i
    int i=0;
    while (bt.data[i]!=e && i<=MAXSIZE-1) i++;
//循环停止时应当是找到了值为E的结点,但不知道是叶子节点还是非叶子
    if (bt.data[2*i+2]!=NULL)
        return bt.data[2*i+2];
    else
        return NULL;
}

int LeftSibling(SqBiTree &bt,Elemtype e)
{
    int i=0;
    if (!bt.data[0]) return NULL;//空树不用查找
    if (bt.data[0]==e) return NULL;//根节点没有左兄弟
    while (bt.data[i]!=e && i<=MAXSIZE-1) i++;
//1.左兄弟为-1 2. 为最左侧的一列,没有左兄弟
    if (i%2==0) return bt.data[i-1];//序号为偶节点才有左兄弟
    else return NULL;
}
int RightSibling(SqBiTree &bt,Elemtype e)
{
    int i=0;
    if (!bt.data[0]) return NULL;//空树不用查找
    if (bt.data[0]==e) return NULL;//根节点没有左兄弟
    while (bt.data[i]!=e && i<=MAXSIZE-1) i++;
//1.左兄弟为-1 2. 为最左侧的一列,没有左兄弟
    if (i%2!=0) return bt.data[i+1];//序号为偶节点才有左兄弟
    else return NULL;
}

void Move(SqBiTree &bt,int k,SqBiTree &q,int g)
{
    if (bt.data[2*k+1]!=NULL) //左孩子不空
        Move(bt,2*k+1,q,2*g+1);
    if (bt.data[2*k+2]!=NULL)//右孩子不空
        Move(bt,2*k+2,q,2*g+2);
    q.data[g]=bt.data[k];
    bt.data[k]=NULL;
}

int InsertChild(SqBiTree &bt,Elemtype e,int LR,SqBiTree &c)
{
//1.找到E所在结点的序号
    int i =0;
    while (bt.data[i]!=e &&i<=MAXSIZE-1 ) i++;
    int k=2*i+LR+1;//得到E结点的LR孩子的序号
    if (bt.data[k])//如果LR结点存在,需要转移到C的右子树,也就是K结点的右子树
        Move(bt,k,bt,2*k+2);
    Move(c,0,bt,k);
    return 1;
}
void del(SqBiTree &bt ,int k)
{
    //删除bt的k结点作为根结点的非空树
    if (!bt.data[2*k+1])//左子树非空
        del(bt,2*k+1);
    if (!bt.data[2*k+2])
        del(bt,2*k+2);
    bt.data[k]=NULL;

}
int DeleteChild(SqBiTree &bt,Elemtype e,int lr)
{
    //删除e元素对应的左或右子树
    //1 find the number of e
    int i=0;
    while (bt.data[i]!=e &&i<=MAXSIZE-1) i++;
    //2 找到要删除的左或右子树
    int k =2*i+1+lr;
    if (bt.data[k]!=NULL) //非空则删除
    del(bt,k);
    else
    {
        cout<<"不存在左或右子树,无法删除"<<endl;
        return 0;
    }
}
void PreOrder(SqBiTree &bt ,int i)
{
    cout<<bt.data[i]<<" ";
    if (bt.data[2*i+1])//左子树非空
    PreOrder(bt,2*i+1);
    if (bt.data[2*i+2])//右子树非空
    PreOrder(bt,2*i+2);

}
int PreOrderTraverse(SqBiTree &bt)
{
    int i=0;
    if (bt.data[i])
    PreOrder(bt,i);//遍历左子树
    else
    {
        cout<<"此树为空,不能遍历"<<endl;
        return 0;
    }
    return 1;
}
void InOrder(SqBiTree &bt ,int i)
{

    if (bt.data[2*i+1])//左子树非空
    PreOrder(bt,2*i+1);
    cout<<bt.data[i]<<" ";
    if (bt.data[2*i+2])//右子树非空
    PreOrder(bt,2*i+2);

}
int InOrderTraverse(SqBiTree &bt)
{
    int i=0;
    if (bt.data[i])
    InOrder(bt,i);//遍历左子树
    else
    {
        cout<<"此树为空,不能遍历"<<endl;
        return 0;
    }
    return 1;
}
void PostOrder(SqBiTree &bt ,int i)
{

    if (bt.data[2*i+1])//左子树非空
    PostOrder(bt,2*i+1);
    if (bt.data[2*i+2])//右子树非空
    PostOrder(bt,2*i+2);
     cout<<bt.data[i]<<" ";

}
int PostOrderTraverse(SqBiTree &bt)
{
    int i=0;
    if (bt.data[i])
    PostOrder(bt,i);//遍历左子树
    else
    {
        cout<<"此树为空,不能遍历"<<endl;
        return 0;
    }
    return 1;
}
int main()
{
    cout<<"---顺序二叉树的基本操作实现 twomeng---"<<endl;
    cout<<"--------------------------------------"<<endl;
    cout<<"1 InsertChild()"<<endl;
    cout<<"2 DeleteChild()"<<endl;
    cout<<"3 PreOrderTraverse()"<<endl;
    cout<<"4 InOrderTraverse()"<<endl;
    cout<<"5 PostOrderTraverse()"<<endl;
    cout<<"6 Parent()"<<endl;
    cout<<"7 LeftChild()"<<endl;
    cout<<"8 RightChild()"<<endl;
    cout<<"9 leftSibling()"<<endl;
    cout<<"10 RightSibling()"<<endl;
    cout<<"11 Root()"<<endl;
    cout<<"12 Value()"<<endl;
    cout<<"13 Assign()"<<endl;
    cout<<"--------------------------------------"<<endl;
ll1:cout<<"请输入您选择的函数序号:)"<<endl;
    int number;
    cin>>number;
    SqBiTree bt;
    initBiTree(bt);
    createBiTree(bt);//创建一个可以公用的二叉树bt
    Elemtype e;position p;
    switch(number){
case 1:
    SqBiTree c;
    initBiTree(c);
    createBiTree(c);
    InsertChild(bt,3,1,c);
    print(bt);
    break;
case 2:
    DeleteChild(bt,3,1);
    print(bt);
    break;
case 3:
    PreOrderTraverse(bt);
    break;
case 4:
    InOrderTraverse(bt);
    break;
case 5:
    PostOrderTraverse(bt);
    break;
case 6:
    cout<<"输入E的值"<<endl;
    cin>>e;
    cout<<Parent(bt,e);
    break;
case 7:
    cout<<"输入E的值"<<endl;
    cin>>e;
    cout<<LeftChild(bt,e);
    break;
case 8:
    cout<<"输入E的值"<<endl;
    cin>>e;
    cout<<RightChild(bt,e);
    break;
case 9:
    cout<<"输入E的值"<<endl;
    cin>>e;
    cout<<LeftSibling(bt,e);
    break;
case 10:
    cout<<"输入E的值"<<endl;
    cin>>e;
    cout<<RightSibling(bt,e);
    break;
case 11:
    cout<<Root(bt);
    break;
case 12:
    cout<<"请输入P的位置(level,order)"<<endl;
    int a,b;
    cin>>a>>b;
    initPosition(p,a,b);
    Value(bt,e,p);
    cout<<e<<endl;
    break;
case 13:
    cout<<"请输入P的位置(level,order)和E的值"<<endl;
    cin>>a>>b>>e;
    initPosition(p,a,b);
    Assign(bt,p,e);
    print(bt);
    break;
    }

    cout<<"您是否想要继续调用函数?yes/no"<<endl;
    string s;cin>>s;
    if (!s.compare("yes"))
    goto ll1;
    else
    return 0;
}

链式二叉树
1.实验内容
1.输入字符序列,建立二叉链表。 1
2.中序遍历二叉树:递归算法。3
3.中序遍历二叉树:非递归算法。(最好也能实现先序,后序非递归算法)4
4.求二叉树的高度 。1
5.求二叉树的叶子个数。1
*6.将二叉链表视为森林的孩子兄弟链表,计算森林中叶子个数。1
*7.建立中序线索二叉树,并实现中序遍历。1
8.借助队列实现二叉树的层次遍历。1
9.在主函数中设计一个简单的菜单,分别调试上述算法。1
*10.综合训练:为N个权值设计哈夫曼编码。

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <string.h>
#include <math.h>
#define MAXSIZE 10
//链式二叉树
using namespace std;
typedef char Elemtype;
typedef struct BiTNode{
Elemtype data;
struct BiTNode *left,*right;
}BiTNode,*BiTree;

void InitBiTree(BiTree &bt)
{
    bt=NULL;//构造空的二叉树
}
void CreateBiTree(BiTree &bt)
{
    Elemtype e;
    scanf("%c",&e);
    if (e==' ')
    {
        bt=NULL;//如果输入空格则将该结点置空
    }
    else
    {
        bt=(BiTree)malloc(sizeof(BiTNode));
        bt->data=e;
        CreateBiTree(bt->left);
        CreateBiTree(bt->right);
    }
}
void PreOrderTraverse(BiTree &bt)
{
    if (bt!=NULL)
    {
    printf("%c",bt->data);
    PreOrderTraverse(bt->left);
    PreOrderTraverse(bt->right);
    }

}

void InOrderTraverse(BiTree &bt)
{
    if (bt)//如果是空则不用遍历左右子树,如果不空则遍历
    {
        InOrderTraverse(bt->left);
        printf("%c",bt->data);
        InOrderTraverse(bt->right);
    }
}
void PostOrderTraverse(BiTree &bt )
{
    if (bt)
    {
        PostOrderTraverse(bt->left);
        PostOrderTraverse(bt->right);
        printf("%c",bt->data);
    }
}
void LevelOrderTraverse(BiTree &bt)
{
    BiTree q[MAXSIZE];//指针数组
    int front,rear;
    //初始化队列
    front=rear=-1;
    if (bt)
    {
        rear=(rear+1)%MAXSIZE;
        q[rear]=bt;//安置根节点
        //不断循环,直到队空为止
        while (front!=rear)
        {
            //如果队不空,队头出队
            front=(front+1)%MAXSIZE;
            printf("%c",q[front]->data);
            //左右孩子不空则入队
            if (q[front]->left)
            {
                rear=(rear+1)%MAXSIZE;
                q[rear]=q[front]->left;//安置根节点
            }
             if (q[front]->right)
            {
                rear=(rear+1)%MAXSIZE;
                q[rear]=q[front]->right;//安置根节点
            }
        }


    }
}
int BiTreeEmpty(BiTree &bt)
{
    if (!bt)
    return 1;
}

int BiTreeDepth(BiTree &bt)
{
    int depth=0;
    int depthL,depthR;
    if (!bt)
    depth=0;
    else
    {
        depthL=BiTreeDepth(bt->left);
        depthR=BiTreeDepth(bt->right);
        depth=1+(depthL>depthR?depthL:depthR);

    }
    return depth;
}
Elemtype Root (BiTree &bt)
{
    if (bt)
    {
        return bt->data;
    }
    else
    return 0;
}
Elemtype Value(BiTree &p)
{
    //P是二叉树中某个节点
    return p->data;
}
void Assign(BiTree &bt,Elemtype e)
{
    bt->data=e;
}
Elemtype Parent(BiTree &bt,Elemtype e)
{
    //e为二叉树bt中的某个节点,输出他的双亲
    BiTree q[MAXSIZE],p;
    int rear,front;
    rear=front =-1 ;

    if (bt)
    {
        rear=(rear+1)%MAXSIZE;
        q[rear]=bt;//根节点入队

        while (rear!=front)
        {
            //如果队不空则队头出队
            front=(front+1)%MAXSIZE;
            p=q[front];
            if (p && p->left->data ==e || p && p->right->data == e )
            {
                //如果P本身不空并且有一个孩子等于E,则返回该双亲节点的值
                return p->data;
            }
            //说明这次没有找到和E相等的节点,则把左孩子和右孩子送入队列
            if (p->left)
            {
              rear=(rear+1)%MAXSIZE;
              q[rear]=p->left;
            }
            if (p->right)
            {
              rear=(rear+1)%MAXSIZE;
              q[rear]=p->right;
            }
        }
    }
}
BiTree findE(BiTree &bt,Elemtype e)
{
    BiTree q[MAXSIZE],p;
    int rear,front;
    rear=front=-1;
    if (bt)
    {
        rear=(rear+1)%MAXSIZE;
        q[rear]=bt;//根入队

        while (front!=rear)
        {
            front=(front+1)%MAXSIZE;
            p=q[front];//取出队头元素
            if (p->data == e)
            {
                return p;
            }
            if (p->left)
            {
               rear=(rear+1)%MAXSIZE;
               q[rear]=p->left;//left child enqueue
            }
            if (p->right)
            {
               rear=(rear+1)%MAXSIZE;
               q[rear]=p->right;//left child enqueue
            }
        }
    }
}
Elemtype LeftChild( BiTree &bt,Elemtype e)
{
    //找到指向E的指针
    BiTree p=findE(bt,e);
    if (p &&p->left )
    {//P不为空并且左孩子不为空
        return p->left->data;
    }
    else
    return 0;

}
Elemtype RightChild( BiTree &bt,Elemtype e)
{
    //找到指向E的指针
    BiTree p=findE(bt,e);
    if (p &&p->right )
    {//P不为空并且左孩子不为空
        return p->right->data;
    }
    else
    return 0;

}
BiTree findP(BiTree &bt,Elemtype e)
{
    //e为二叉树bt中的某个节点,输出他的双亲
    BiTree q[MAXSIZE],p;
    int rear,front;
    rear=front =-1 ;

    if (bt)
    {
        rear=(rear+1)%MAXSIZE;
        q[rear]=bt;//根节点入队

        while (rear!=front)
        {
            //如果队不空则队头出队
            front=(front+1)%MAXSIZE;
            p=q[front];
            if (p && p->left->data ==e || p && p->right->data == e )
            {
                //如果P本身不空并且有一个孩子等于E,则返回该双亲节点的值
                return p;
            }
            //说明这次没有找到和E相等的节点,则把左孩子和右孩子送入队列
            if (p->left)
            {
              rear=(rear+1)%MAXSIZE;
              q[rear]=p->left;
            }
            if (p->right)
            {
              rear=(rear+1)%MAXSIZE;
              q[rear]=p->right;
            }
        }
    }
}
Elemtype LeftSibling(BiTree &bt,Elemtype e)
{
    BiTree parent = findP(bt,e);//找到E元素的双亲指针

    if (parent->left)
    {
        return parent->left->data;
    }
}

Elemtype RightSibling(BiTree &bt,Elemtype e)
{
    BiTree parent = findP(bt,e);//找到E元素的双亲指针
    if (parent->right)
    {
        return parent->right->data;
    }
}
int  InsertChild(BiTree &p ,int lr,BiTree &c)
{//插入更简单了!!
    if (p)
    {
        if (lr==0)//把C移到P的左子树上
        {
            c->right=p->left;
            p->left=c;
        }else
        {
          c->right=p->right;
          p->right=c;
        }
        return 1;
    }
    else
    return 0;//P为空
}
void clearBiTree(BiTree &bt)
{
    //同样用递归!
    if (bt)
    {
        if (bt->left)
            clearBiTree(bt->left);
        if (bt->right)
            clearBiTree(bt->right);
        free(bt);
        bt=NULL;
    }
}
void  DeleteChild(BiTree &p,int LR)
{
    // 初始条件: 二叉树T存在,p指向T中某个结点,LR为0或1
   // 操作结果: 根据LR为0或1,删除T中p所指结点的左或右子树
   if (p)
   {
     if (LR == 1)
   {
       clearBiTree(p->left);
   }else
   {
       clearBiTree(p->right);
   }
   }

}

//非递归实现pre/in/post 遍历二叉树
//使用栈实现中序遍历


typedef BiTree Elemtype1;
typedef struct {
Elemtype1 elem[MAXSIZE];
int top;
}SeqStack;
void initSeqStack(SeqStack &s){
s.top=-1;
}
int stackEmpty(SeqStack &s){
if (s.top==-1)
return 1;
return 0;//或者返回 表达式的真值return s.top==-1;
}
int push(SeqStack &s,Elemtype1 e){
if (s.top>=MAXSIZE-1)
return 0;
else {
s.top++;
s.elem[s.top]=e;
return 1;
}
}
int pop(SeqStack &s,Elemtype1 &e){
if (s.top==-1)
return 0;
else {
e=s.elem[s.top];
s.top--;
return 1;
}
}
int gettop(SeqStack &s,Elemtype1 &e){
if (s.top==-1)
return 0;
else {
e=s.elem[s.top];
return 1;
}
}
//中序遍历非递归算法
void InOrderTraverse2(BiTree &bt)
{
    //精髓是把每个结点的地址存入栈中,通过push & pop实现过程
    SeqStack s;
    initSeqStack(s);
    BiTree p=bt;
    while (p!=NULL || !stackEmpty(s))
    {
        //当且仅当两者都空时结束循环
        if (p)
        {
            push(s,p);
            p=p->left;
        }
        else
        {
            pop(s,p);//弹回根节点
            printf("%c ",p->data);//第二次回到根节点时才打印输出
            p=p->right;

        }
    }

}

//先序遍历非递归算法
void PreOrderTraverse2(BiTree p)
{
    //这里不加&即为形参,便不用定义新的变量作为移动的指针了
    SeqStack s;
    initSeqStack(s);
    do
    {
        if (p)
        {
          printf("%c ",p->data);
          push(s,p);
          p=p->left;
        }
        else
        {
        pop(s,p);
        p=p->right;
        }

    }while (p || !stackEmpty(s));

}

//后序遍历非递归算法
void PostOrderTraverse2(BiTree p)
{
    struct
    {
        BiTree pp;//pointer
        int tag;//标记位
    }s[MAXSIZE];//定义一个结构体数组,即为一个栈s
//这里struct之前不能加typedef ,因为s[]是结构体数组而不是别名

    int top=0;//栈顶指针

    while ( p || top>0)
    {
        while (p)//一直走到最左边
        {
            top++;
            s[top].pp=p;
            s[top].tag=0;
            p=p->left;
        }
        if (top>0)
        {
            if (s[top].tag == 0)
            {
                //如果栈顶元素标志位为0,即为第二次遇到该结点元素
                s[top].tag=1;
                p=s[top].pp;
                p=p->right;//继续向右孩子深入
            }
            else
            {
                p=s[top].pp;
                printf("%c ",p->data);//如果是第二次遇到该节点则输出
                top--;
                p=NULL;//不用往深处走了,直接退栈继续循环
            }
        }
    }
}
//找到叶子结点个数,左右孩子都空
int findleaf(BiTree p,int &count1)
{

    if (p)
    {
        if ( !p->left &&!p->right)
            count1++;
        findleaf(p->left,count1);
        findleaf(p->right,count1);
    }
}
int findrightleaf(BiTree p,int &count1)
{

    if (p)
    {
        if (!p->right)
            count1++;
        findleaf(p->left,count1);
        findleaf(p->right,count1);
    }
}
void PreOrderfindall(BiTree &bt,int &count2)
{
    if (bt!=NULL)
    {
    count2++;
    PreOrderfindall(bt->left,count2);
    PreOrderfindall(bt->right,count2);
    }

}

int findleafinforest(BiTree &bt)
{
    //假设bt代表一个森林,求森林中叶子的个数
    //利用理论:假设森林中有N个非终端结点,则二叉树中右指针域为空的结点个数为N+1
    if (bt)
    {
        int count1 = 0;
        findrightleaf(bt,count1);
        //count即为二叉树中右指针域为空的结点的个数
        int count2=0;
        PreOrderfindall(bt,count2);
        //count2即为二叉树中所有节点的个数,也就是森林总结点个数
        return (count2-count1+1);
    }
    else
        return 0;
}
//建立中序线索二叉树并遍历
typedef enum PointerTag {link=0,thread=1};//link=0 指针,thread=1 线索
typedef struct BithrNode{
Elemtype data;
struct BithrNode *left,*right;
PointerTag ltag,rtag;
}BithrNode,*BithrTree;

int InOrderThreading(BithrTree &thrt,BithrTree bt)
{
    void Inthreading(BithrTree &p,BithrTree &pre);
    //将普通二叉树线索化成thrt
    //1.建立头结点
    thrt = (BithrTree)malloc(sizeof(BithrNode));
    BithrTree pre;
    thrt->right=thrt;
    thrt->ltag=link;
    thrt->rtag=thread;
    if (!bt)
        thrt->left=thrt;
    else
    {
        thrt->left = bt;
        pre=thrt;//前驱指针指向头结点
        Inthreading(bt,pre);
        //线索化二叉树
        pre->right=thrt;
        pre->rtag=thread;
        thrt->right=pre;
        //线索化最后pre指向树中最后一个结点,进行最后的处理:连接树中最后一个结点与头结点,形成循环的线索树

    }
}
void Inthreading(BithrTree &p,BithrTree &pre)
{
    if (p)
    {
        Inthreading(p->left,pre);
        if (!p->left)//P的左孩子为空
        {
            p->ltag=thread;
            p->left=pre;
        }
        if (!pre->right)//Pre的右孩子为空
        {
           pre->rtag=thread;
           pre->right=p;
        }
        pre=p;
        Inthreading(p->right,pre);
    }
}
//遍历线索二叉树
int InOrderTraverseThrtree(BithrTree &thrt)
{
    BithrTree p=thrt->left;
    while (p != thrt)
    {
        //线索树不为空时
        while(p && p->ltag !=thread)
        {
            p=p->left;
        }
        printf("%c",p->data);
        while(p->rtag == thread && p->right != thrt)
        {
            //如果p->right==T,则不用继续往右走
            p=p->right;
            printf("%c",p->data);
        }
        p=p->right;//没有右线索,只有右孩子

    }
}
void CreateBithrTree(BithrTree &bt)
{
    Elemtype e;
    scanf("%c",&e);
    if (e==' ')
    {
        bt=NULL;//如果输入空格则将该结点置空
    }
    else
    {
        bt=(BithrTree)malloc(sizeof(BithrNode));
        bt->data=e;
        CreateBithrTree(bt->left);
        CreateBithrTree(bt->right);
    }
}
int main()
{

    cout<<"---二叉树的基本操作实现 twomeng---"<<endl;
    cout<<"--------------------------------------"<<endl;
    cout<<"1 InsertChild()"<<endl;
    cout<<"2 DeleteChild()"<<endl;
    cout<<"3 PreOrderTraverse()"<<endl;
    cout<<"4 InOrderTraverse()"<<endl;
    cout<<"5 PostOrderTraverse()"<<endl;
    cout<<"6 Parent()"<<endl;
    cout<<"7 LeftChild()"<<endl;
    cout<<"8 RightChild()"<<endl;
    cout<<"9 leftSibling()"<<endl;
    cout<<"10 RightSibling()"<<endl;
    cout<<"11 Root()"<<endl;
    cout<<"12 Value()"<<endl;
    cout<<"13 Assign()"<<endl;
    cout<<"14 LevelOrderTraverse()"<<endl;
    cout<<"15 BiTreeDepth()"<<endl;
    cout<<"16 findleaf()"<<endl;
    cout<<"17 PreOrderTraverse2()"<<endl;
    cout<<"18 InOrderTraverse2()"<<endl;
    cout<<"19 PostOrderTraverse2()"<<endl;
    cout<<"20 findleafinforest()"<<endl;
    cout<<"21 线索化二叉树并中序遍历输出"<<endl;
    cout<<"--------------------------------------"<<endl;

ll1:cout<<"请输入您选择的函数序号:)"<<endl;
    int number;
    cin>>number;


    BiTree bt,p;
    InitBiTree(bt);
    Elemtype e;int count3 = 0;
    cout<<"请按照先序顺序输入一棵树!没有结点的地方请输入空格"<<endl;
    fflush(stdin);
    CreateBiTree(bt);//创建一个可以公用的二叉树bt;
    switch(number)
{
case 1:
    PreOrderTraverse(bt);
    BiTree c;
    InitBiTree(c);
    cout<<"请按照先序顺序输入一棵Insert树!没有结点的地方请输入空格"<<endl;
    fflush(stdin);
    CreateBiTree(c);
    LevelOrderTraverse(c);
    cout<<"输入完毕!"<<endl;
    cout<<"如果您想插入到左子树,输入0;如果您想插入到右子树,输入1 "<<endl;
    int x;cin>>x;
    InsertChild(bt,x,c);
    PreOrderTraverse(bt);
    break;
case 2:
    PreOrderTraverse(bt);
    cout<<endl;
    cout<<"删除左子树,请输入1;删除右子树,请输入0"<<endl;
    cin>>x;
    DeleteChild(bt,x);
    PreOrderTraverse(bt);
    break;
case 3:
    PreOrderTraverse(bt);
    break;
case 4:
    InOrderTraverse(bt);
    break;
case 5:
    PostOrderTraverse(bt);
    break;
case 6:
    char ch;
    cout<<"请输入您要寻找的节点数值"<<endl;
    cin>>ch;
    cout<<Parent(bt,ch);
    break;
case 7:
    cout<<"输入E的值"<<endl;
    cin>>e;
    cout<<LeftChild(bt,e);
    break;
case 8:
    cout<<"输入E的值"<<endl;
    cin>>e;
    cout<<RightChild(bt,e);
    break;
case 9:
    cout<<"输入E的值"<<endl;
    cin>>e;
    cout<<LeftSibling(bt,e);
    break;
case 10:
    cout<<"输入E的值"<<endl;
    cin>>e;
    cout<<RightSibling(bt,e);
    break;
case 11:
    cout<<Root(bt);
    break;
case 12:
    p=bt->left;
    cout<<Value(p)<<endl;
    break;
case 13:
    p=bt->left;
    cout<<"请输入您要赋的值"<<endl;
    cin>>e;
    Assign(p,e);
    cout<<"assign函数调用成功!其中的值现在为:"<<endl;
    cout<<p->data<<endl;
    break;

case 14:
    LevelOrderTraverse(bt);
    break;
case 15:
    cout<<BiTreeDepth(bt)<<endl;
    break;
case 16:

    findleaf(bt,count3);
    cout<<count3<<endl;
    break;
case 17:
    PreOrderTraverse2(bt);
    break;
case 18:
    InOrderTraverse2(bt);
    break;
case 19:
    PostOrderTraverse2(bt);
    break;
case 20:
    cout<<findleafinforest(bt)<<endl;
    break;
case 21:
    BithrTree bt;
    CreateBithrTree(bt);
    BithrTree thrt;
    cout<<"线索化二叉树成功!"<<endl;
    InOrderThreading(thrt,bt);
    InOrderTraverseThrtree(thrt);
    cout<<"遍历线索二叉树成功!"<<endl;
   break;
}


   cout<<"您是否想要继续调用函数?yes/no"<<endl;
    string s;cin>>s;
    if (!s.compare("yes"))
    goto ll1;
    else



    return 0;
}

我这个哈夫曼树貌似有点问题,结果不太对啊。。有空再调一调

哈夫曼测试数据:
8
5 29 7 8 14 23 3 11

未调试出来的哈夫曼:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <string.h>
#include <math.h>
#define MAXSIZE 20

using namespace std;
//哈夫曼编码
typedef struct {
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;

typedef char* *Huffmancode;//定义一个指针数组存放编码

int min(HuffmanTree t,int i)
 { // 函数void select()调用
   int j,flag;
   unsigned int k=UINT_MAX; // 取k为不小于可能的值
   for(j=1;j<=i;j++)
     if(t[j].weight<k&&t[j].parent==0)
       k=t[j].weight,flag=j;
   t[flag].parent=1;
   return flag;
 }

 void select(HuffmanTree t,int i,int &s1,int &s2)
 { // s1为最小的两个值中序号小的那个
   int j;
   s1=min(t,i);
   s2=min(t,i);
   if(s1>s2)
   {
     j=s1;
     s1=s2;
     s2=j;
   }
 }

void HuffmanCoding(HuffmanTree &ht,Huffmancode &hc,int *w,int n)
{
    int i;
    if (n<=1)
        return;//判断N(字符个数)的输入是否合法
    int m;//哈夫曼树结点个数
    m = 2*n-1;
    //哈夫曼树是一个数组,我们要先定义出来, 再初始化数组
    ht = (HuffmanTree )malloc((m+1)*sizeof(HTNode));//0 单元未用
    //给初始字符赋权值
    HuffmanTree p;
    p=ht;
    p++;
    int *t;t=w;

    for (i=1,t++;i<=n;i++,p++,t++)
    {
        (*p).weight=*t;
        (*p).lchild=0;
        (*p).rchild=0;
        (*p).parent=0;
    }
    //给还没计算的结点赋值0
    for (p=&ht[n+1],i=n+1;i<=m;i++,p++)
    {
        (*p).weight=0;
        (*p).lchild=0;
        (*p).rchild=0;
        (*p).parent=0;
    }

    //建立哈夫曼树
    for(int i=n+1;i<=m;i++)
    {
        int s1,s2;
        select(ht,i-1,s1,s2);//最小的两个结点序号为s1,s2

        ht[s1].parent=i;
        ht[s2].parent=i;
        ht[i].lchild=s1;
        ht[i].rchild=s2;
        ht[i].weight=ht[s1].weight+ht[s2].weight;
    }
    //show()
//    for (i=1 ; i<=m ; i++)
//    {
//        cout<< ht[i].weight <<" " <<ht[i].parent <<" "<<ht[i].lchild <<" "<<ht[i].rchild<<endl;
//    }
    //进行哈夫曼编码
    int c,f;
    hc=(Huffmancode)malloc(sizeof(char *)*(n+1));//头指针向量
    char *cd = (char *)malloc(sizeof(char)*n);//一个字符编码的数组指针
    cd[n-1]='';
    for (int i=1;i<=n;i++)//循环N个字符
    {
        int start = n-1;//从叶节点开始往上编
        for (c=i,f=ht[i].parent;f!=0;c=f,f=ht[f].parent)
        {
            //定义C是为了不动I,顺次往上找双亲,判断自己是双亲的左子树还是右子树
            if (ht[f].lchild == c)
                cd[--start]='0';
            else
                cd[--start]='1';

        }

        for (int x = n-start;x<n;x++)
            cout<<cd[x];
        hc[i]=(char *)malloc((n-start)*sizeof(char));
        strcpy(hc[i],cd);
        //cout<<hc[i]<<endl;
    }

}

int main()
{
  int *w,*ww;

  int n;
  cout<<"请输入字符数N"<<endl;
  cin>>n;
  w=(int *)malloc(sizeof(int)*(n+1));//0号单元未用
  ww=w;
  int i;
  cout<<"请依次输入字符的权值"<<endl;
  for (ww++,i=1;i<=n;i++,ww++)
  {
     cin>> *ww;
  }

    HuffmanTree ht;
    Huffmancode hc;
    HuffmanCoding(ht,hc,w,n);
    Huffmancode q=hc;

    for (int k=1;k<=n;k++)
    puts(hc[k]);





    return 0;
}
原文地址:https://www.cnblogs.com/twomeng/p/9476688.html