zoukankan      html  css  js  c++  java
  • 数据结构实验报告(三)

    实验报告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;
    }
  • 相关阅读:
    多线程---同步函数的锁是this(转载)
    函数
    流程控制
    基本语句和运算
    基本数据库类型
    迷宫问题
    Dungeon Master(逃脱大师)-BFS
    HTML元素常用属性整理
    Java_hutool 发起请求
    jQuery Autocomplete
  • 原文地址:https://www.cnblogs.com/twomeng/p/9476688.html
Copyright © 2011-2022 走看看