精华内容
下载资源
问答
  • void InsNode(BiTNode *p,BiTNode *r) {  if(P->Rtag==1)//p无右孩子  {  r->RChild=p->RChild;//p的后继变为r的后继  r->Rtag=1;  r->RChild=r;//r成为p的右孩子  r->Rtag=0;  r->LChild=p;... else 

    void InsNode(BiTNode *p,BiTNode *r)
    {
     if(P->Rtag==1)//p无右孩子
     {
      r->RChild=p->RChild;//p的后继变为r的后继
      r->Rtag=1;
      r->RChild=r;//r成为p的右孩子
      r->Rtag=0;
      r->LChild=p;//p变为r的前驱
      r->Ltag=1;
     }
     else     //p有右孩子
     {
      s=p->RChild;
      while(s->Ltag==0)
       s=s->LChild;//查找p结点的右子树的最左下端结点
      r->RChild=p->RChild;//p的右孩子变为r的右孩子
      r->Rtag=0;
      r->LChild=p; //p变为r的前驱
      r->Ltag=1;
      p->RChild=r;//r变为p的右孩子
      s->LChild=r;//r变为p原来右子树的最左下端结点的前驱
     }
    }

    展开全文
  • 其实线索二叉树相当于把一棵二叉树变成一个双向链表,这有利于方便插入删除结点和查找某个结点的操作。 线索化:对二叉树以某种次序遍历使其变为线索二叉树的过程。 线索二叉树的结点结构:lchild - ltag - data -...

    线索二叉树将指向前驱和后继的指针称为线索,加上线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树

    其实线索二叉树相当于把一棵二叉树变成一个双向链表,这有利于方便插入删除结点和查找某个结点的操作。

    线索化对二叉树以某种次序遍历使其变为线索二叉树的过程

    线索二叉树的结点结构:
    lchild - ltag - data - rtag - rchild
    其中:
    1、ltag为0使指向该结点的左孩子,为1时指向该结点的前驱。
    2、rtag为0使指向该结点的右孩子,为1时指向该结点的后继。
    3、在每个结点增设两个标志域ltag和rtag,这两个标志域只存放0和1数字的布尔型变量,其占用内存空间小于指针变量。

    实现线索二叉树结构程序:

    typedef enum {Link,Thread} PointerTag;		
    //link == 0表示指向左右孩子指针,Thread == 1表示指向前驱或后继的线索
    
    typedef struct BiThrNode		                //二叉树线索存储结点结构
    {
    	TElemType data;			                    //结点数据
    	struct BiThrNode *lchild, *rchild;	        //左右孩子指针
    	pointerTag LTag;		                    //左标志
    	pointerTag RTag;		                    //右标志
    } BiThrNode, *BiThrTree;
    

    其中线索化的实质就是将二叉链表中的空指针改为指向前去或后继的线索,由于前驱和后继的信息只有在遍历该二叉树时才能得到,所以线索化的过程就是在遍历的过程中修改空指针的过程。

    举个例子:中序遍历进行中序线索化

    void InThreading(BiThrTree p)
    {
    	if(p)
    	{
    		InThreading(p->lchild);			//递归左子树线索化
    
    		if (!p->lchild)			    //没有左子树
    		{    
    			p->LTag = Thread;		    //前驱线索
    			p->lchild = pre;		    //左孩子指针指向前驱
    		}
    
    		if(!pre->rchild)			    //前驱没有右孩子
    		{
    			p->RTag = Thread;		    //后继线索
    			p->rchild = p;			    //前驱右孩子指针指向后继
    		}
    		pre = p;
    		InThreading(P->rchild);			//递归右子树线索化
    	}
    }

    创建线索二叉树后,进行遍历,相当于操作一个双向链表结构,和    双向链表结构一样,在二叉树线索链表上添加一个头结点。

    程序:

    Status InOederTraverse_Thr (BiTheTree T)
    {
    	BiThrTree p;
    	p = T->lchild;			        //p指向根结点
    	while (p != T)			        //空树或者遍历结束时, p == T
    	{
    		while (p->LTag == Link)    	//当LTag == 0时循环到中序序列第一个结点
    		p = p->lchild;
    		printf("%c",p->data)	    //显示结点数据,可以更改为其他对结点操作
    		while (p->RTag == Thread && p->rchild = T)
    		{
    		p = p->rchild;
    		printf("%c",p->data);
    		}
    		p = p->rchild;		        //p进至其右子树根
    	}
    	return OK;
    }
    

    注意:
    1、充分利用了空指针域的空间,节省空间,保证创建时的一次遍历就可以终生受用前驱后继的信息,节省时间。
    2、如果所用二叉树需经常遍历或查找结点时需要某种遍历序列中的前驱和后继,建议采用线索二叉链表的存储结构。

    展开全文
  • 中序线索二叉树插入

    千次阅读 2020-05-08 14:43:08
    中序全线索二叉树插入 原题要求:试写一个算法,在中序全线索二叉树的结点*p之下,插入一棵以结点*x为根、只有左子树的中序全线索二叉树,使*x为根的二叉树称为*p的左子树。若*p原来有左子树,则令它为*x的右子树...

    中序线索二叉树的插入

    原题要求:试写一个算法,在中序线索二叉树的结点*p之下,插入一棵以结点*x为根、只有左子树的中序线索二叉树,使*x为根的二叉树称为*p的左子树。若*p原来有左子树,则令它为*x的右子树。完成插入之后的二叉树应保持线索化特性。

    #include <iostream>
    #define ERROR 0
    #define OK 1
    #include"stdlib.h"
    #include <cstddef>
    using namespace std;
    
    typedef struct BiThrNode{
        char data;
        struct BiThrNode *lchild,*rchild;
        int ltag,rtag;
        BiThrNode(char dt) : data(dt), lchild(NULL), rchild(NULL),ltag(0),rtag(0) {}
    }BiThrNode,*BiThrTree;
    BiThrTree pre=NULL;
    void Inthreading(BiThrTree p)
    {
        if(p)
        {
            Inthreading(p->lchild);
            if(pre != NULL &&p->lchild==NULL)
            {
                p->ltag=1;
                p->lchild=pre;
            }
            if(pre->rchild==NULL)
            {
                pre->rtag=1;
                pre->rchild=p;
            }
            pre=p;
            Inthreading(p->rchild);
        }
    }
    BiThrTree InOrderThread(BiThrTree h, BiThrTree t)
    {
        if(!(h=(BiThrTree)malloc(sizeof(BiThrNode))))
            {cout<<"错误"<<endl;
                return false;}
        h->ltag=0;h->rtag=1;
        h->rchild=h;
        if(!t)h->lchild=h;
        else{h->lchild=t;pre=h;
        Inthreading(t);
        pre->rchild=h;
        pre->rtag=1;
        h->rchild=pre;}
        return h;
    }
    BiThrTree last(BiThrTree t)
    {
        BiThrTree p;
        p = t->lchild;           //p指向根结点
        while(p != t&&p->lchild!=t)
        {
            while(p->ltag == 0)   //当ltag = 0时循环到中序序列的第一个结点
            {
                p = p->lchild;
            }
            while(p->rtag ==1 && p->rchild != t&&p->lchild!=t)
            {
                p = p->rchild;
            }
            if(p->lchild!=t)
            {p = p->rchild; }          //p进入其右子树
        }
    
        return p;
    }
    BiThrTree find(BiThrTree t,char dt)
    {
        BiThrTree p;
        p = t->lchild;           //p指向根结点
        while(p != t&&p->data!=dt)
        {
            while(p->ltag == 0)   //当ltag = 0时循环到中序序列的第一个结点
            {
                p = p->lchild;
            }
            while(p->rtag ==1 && p->rchild != t&&p->data!=dt)
            {
                p = p->rchild;
            }
            if(p->data!=dt)
            {p = p->rchild;  }         //p进入其右子树
        }
        return p;
    }
    int InOrderThraverse(BiThrTree t)
    {
        BiThrTree p;
        p = t->lchild;           //p指向根结点
        while(p != t)
        {
            while(p->ltag == 0)   //当ltag = 0时循环到中序序列的第一个结点
            {
                p = p->lchild;
            }
            cout<<p->data;  //显示结点数据,可以更改为其他对结点的操作
            while(p->rtag ==1 && p->rchild != t)
            {
                p = p->rchild;
                cout<<p->data;
            }
    
            p = p->rchild;           //p进入其右子树
        }
    
        return OK;
    }
    int check(BiThrTree t)
    {
        if(t==NULL){cout<<"t空"<<endl;return 1;}
        else cout<<"t不空,头结点:"<<t->lchild->data<<' '<<"next:"<<t->lchild->rchild->data<<endl;return 0;
    }
    BiThrTree insert(BiThrTree t1,BiThrTree t2,BiThrTree fn,BiThrTree last) //t2插入t1
    {
        if(fn->ltag==0){ //fn有左子树
            fn->rtag=0;
            fn->rchild=t2->lchild;
            last->lchild=fn;
            t2->lchild->rchild=t1->lchild;
            delete(t2);
        }
        else if(fn->ltag==1&&fn->lchild==t1)
        {
            fn->ltag=0;
            fn->lchild=t2->lchild;
            t2->lchild->rchild=fn;
            last->lchild=t1;
            delete(t2);
        }
        else{
            fn->ltag=0;
            fn->lchild=t2->lchild;
            t2->lchild->rchild=fn;
            last->lchild=t1;
            delete(t2);
        }
        return t1;
    }
    
    int main()
    {
        char dt;
        BiThrTree t1,t2,init1,init2,findnode,last2;
        t1=(BiThrTree)malloc(sizeof(BiThrNode));
        t2=(BiThrTree)malloc(sizeof(BiThrNode));
        init1=(BiThrTree)malloc(sizeof(BiThrNode));
        init2=(BiThrTree)malloc(sizeof(BiThrNode));
        last2=(BiThrTree)malloc(sizeof(BiThrNode));
        findnode=(BiThrTree)malloc(sizeof(BiThrNode));
        BiThrNode root1('a'),node1('b'), node2('c'), node3('d'), node4('e');
        BiThrNode root2('f'),node5('g'),node6('h');
        root1.lchild=&node1;
        root1.rchild=&node2;
        node1.lchild=&node3;
        node2.rchild=&node4;
        root2.lchild=&node5;
        node5.lchild=&node6;
        init1=&root1;init2=&root2;
        cout<<"二叉树创建完成"<<endl;    //建立二叉树
        t1=InOrderThread(t1, init1);  //加入头结点,并线索化
        t2=InOrderThread(t2,init2);
        cout<<"线索二叉树创建完成"<<endl;
        //二叉树图示: 原树:   a           插入树:   f
        //                   / \                   /
        //                 b    c                g
        //                /      \              /
        //              d         e           h
        cout<<"请输入被插入节点:"<<endl;
        cin>>dt;
        findnode=find(t1,dt);last2=last(t2);
        t1=insert(t1,t2,findnode,last2);
        cout<<"输出插入后中序线索二叉树的内容:"<<endl;
        InOrderThraverse(t1);
        return 0;
    }
    
    
    展开全文
  • 线索二叉树插入,删除

    热门讨论 2010-05-26 23:16:21
    一、内容 线索二叉树的应用。实现线索二叉树的建立、插入、删除、恢复线索的实现。
  • 线索二叉树

    2019-04-10 21:19:27
    通过前序序列创建线索二叉树 1:中序遍历 2:查找节点前驱后继 3:插入节点 4:删除节点 0:退出
  • 线索二叉树的建立 删除 插入 恢复线索
  • 以下是对称序线索二叉树插入代码,用于插入的二叉树如下图所示: (其中X、Y结点用于插入插入位置如图) #include #define MaxSize 13 using namespace std;//变量定义与声明 typedef char datatype; typedef ...

    以下是对称序线索二叉树的插入代码,用于插入的二叉树如下图所示:
    (其中X、Y结点用于插入,插入位置如图)
    这里写图片描述

    #include<iostream>
    #define MaxSize 13
    using namespace std;
    
    //变量定义与声明
    typedef char datatype;
    typedef struct node
    {
        datatype data;
        struct node *lchild,*rchild;
        int ltag,rtag;
    }ThrBTnode,*ThrBinTree;
    typedef struct
    {
        ThrBTnode* S[MaxSize];
        int top;
    }SeqStack;
    SeqStack ST;
    ThrBinTree root;
    ThrBTnode* nodes[13];
    
    //置空栈
    void ClearStack(SeqStack &ST)
    {
        ST.top=-1;
    }
    
    //栈的推入
    void push(SeqStack &ST,ThrBTnode *p)
    {
        if(ST.top>=MaxSize-1)
            cout<<"overflow!"<<endl;
        else
            ST.S[++ST.top]=p;
    }
    
    //栈的弹出
    ThrBTnode* pop(SeqStack &ST,ThrBTnode *p)
    {
        if(ST.top==-1)
            cout<<"underflow!"<<endl;
        else
            p=ST.S[ST.top--];
        return p;
    }
    
    //判栈空否
    int StackEmpty(SeqStack ST)
    {
        if(ST.top==-1)
            return 1;
        else
            return 0;
    }
    
    //构建一棵二叉树
    ThrBinTree Create(ThrBinTree root)
    {
        ThrBTnode *A=new ThrBTnode;
        ThrBTnode *B=new ThrBTnode;
        ThrBTnode *C=new ThrBTnode;
        ThrBTnode *D=new ThrBTnode;
        ThrBTnode *E=new ThrBTnode;
        ThrBTnode *F=new ThrBTnode;
        ThrBTnode *G=new ThrBTnode;
        ThrBTnode *H=new ThrBTnode;
        ThrBTnode *I=new ThrBTnode;
        ThrBTnode *J=new ThrBTnode;
        ThrBTnode *K=new ThrBTnode;
        ThrBTnode *X=new ThrBTnode;
        ThrBTnode *Y=new ThrBTnode;
    
        A->data='A';
        B->data='B';
        C->data='C';
        D->data='D';
        E->data='E';
        F->data='F';
        G->data='G';
        H->data='H';
        I->data='I';
        J->data='J';
        K->data='K';
        X->data='X';
        Y->data='Y';
    
        A->lchild=B;
        A->rchild=C;
        A->ltag=A->rtag=0;
    
        B->lchild=D;
        B->rchild=E;
        B->ltag=B->rtag=0;
    
        C->lchild=F;
        C->rchild=G;
        C->ltag=C->rtag=0;
    
        D->lchild=D->rchild=NULL;
        D->ltag=D->rtag=0;
    
        E->lchild=H;
        E->rchild=NULL;
        E->ltag=E->rtag=0;
    
        F->lchild=NULL;
        F->rchild=I;
        F->ltag=F->rtag=0;
    
        G->lchild=G->rchild=NULL;
        G->ltag=G->rtag=0;
    
        H->lchild=H->rchild=NULL;
        H->ltag=H->rtag=0;
    
        I->lchild=J;
        I->rchild=K;
        I->ltag=I->rtag=0;
    
        J->lchild=J->rchild=NULL;
        J->ltag=J->rtag=0;
    
        K->lchild=K->rchild=NULL;
        K->ltag=K->rtag=0;
    
        X->lchild=X->rchild=NULL;
        X->ltag=X->rtag=0;
    
        Y->lchild=Y->rchild=NULL;
        Y->ltag=Y->rtag=0;
    
        root=A;
    
        nodes[0]=A;
        nodes[1]=B;
        nodes[2]=C;
        nodes[3]=D;
        nodes[4]=E;
        nodes[5]=F;
        nodes[6]=G;
        nodes[7]=H;
        nodes[8]=I;
        nodes[9]=J;
        nodes[10]=K;
        nodes[11]=X;
        nodes[12]=Y;
    
        return root;
    }
    
    //线索化二叉树
    void inOrderThreadTree(ThrBinTree root)
    {
        ThrBTnode *pre,*p;
        ClearStack(ST);
        p=root;
        pre=NULL;
        while(p!=NULL||!StackEmpty(ST))
        {
            if(p!=NULL)
            {
                push(ST,p);
                p=p->lchild;
            }
            else
            {
                p=pop(ST,p);
                if(p->lchild==NULL)
                {
                    p->lchild=pre;
                    p->ltag=1;
                }
                if(pre!=NULL&&pre->rchild==NULL)
                {
                    pre->rchild=p;
                    pre->rtag=1;
                }
                pre=p;
                p=p->rchild;
            }
        }
        if(pre!=NULL)
                pre->rtag=1;
    }
    
    //对称序遍历对称序线索树
    void inOrderTraThrTree(ThrBinTree root)
    {
        ThrBTnode *p=root;
        while(p!=NULL)
        {
            while(p->ltag==0)
                p=p->lchild;
            cout<<p->data<<" ";
            while(p->rtag==1&&p->rchild!=NULL)
            {
                p=p->rchild;
                cout<<p->data<<" ";
            }
            p=p->rchild;
        }
        cout<<endl;
    }
    
    //线索二叉树的插入
    void InsertRight(ThrBTnode *p,ThrBTnode *r)
    {
        ThrBTnode *q;
        r->rchild=p->rchild;
        r->rtag=p->rtag;
        r->lchild=p;
        r->ltag=1;
        p->rchild=r;
        p->rtag=0;
        if(r->rtag==0)
        {
            q=r->rchild;
            while(q->ltag==0)
                q=q->lchild;
            q->lchild=r;
        }
    }
    
    //逐个结点打印线索关系
    void Print(ThrBinTree root)
    {
        for(int i=0;i<13;i++)
        {
            cout<<"对于结点"<<nodes[i]->data<<"有:"<<endl;
            if((nodes[i]->lchild==NULL)||(nodes[i]->rchild==NULL))
            {
                if(nodes[i]->lchild==NULL&&nodes[i]->rchild==NULL)
                {
                    cout<<"lchild为:  NULL"<<endl;
                    cout<<"rchild为:  NULL"<<endl;
                }
                else if(nodes[i]->rchild==NULL&&nodes[i]->lchild!=NULL)
                {
                    cout<<"lchild为:  "<<nodes[i]->lchild->data<<endl;
                    cout<<"rchild为:  NULL"<<endl;
                }
                else if(nodes[i]->lchild==NULL&&nodes[i]->rchild!=NULL)
                {
                    cout<<"lchild为:  NULL"<<endl;
                    cout<<"rchild为:  "<<nodes[i]->rchild->data<<endl;
                }
                cout<<"ltag为:  "<<nodes[i]->ltag<<endl;
                cout<<"rtag为:  "<<nodes[i]->rtag<<endl;
                continue;
            }
            cout<<"lchild为:  "<<nodes[i]->lchild->data<<endl;
            cout<<"rchild为:  "<<nodes[i]->rchild->data<<endl;
            cout<<"ltag为:  "<<nodes[i]->ltag<<endl;
            cout<<"rtag为:  "<<nodes[i]->rtag<<endl;
        }
    }
    
    //测试函数
    int main()
    {
        root=Create(root);
        cout<<"对称序线索化二叉树结果为:"<<endl;
        inOrderThreadTree(root);
        Print(root);
        cout<<"对称序遍历对称序线索树结果为:"<<endl;
        inOrderTraThrTree(root);
        cout<<"插入X结点后,对称序线索化结果为:"<<endl;
        InsertRight(nodes[4],nodes[11]);
        Print(root);
        cout<<"对称序遍历对称序线索树结果为:"<<endl;
        inOrderTraThrTree(root);
         cout<<"插入Y结点后,对称序线索化结果为:"<<endl;
        InsertRight(nodes[5],nodes[12]);
        Print(root);
        cout<<"对称序遍历对称序线索树结果为:"<<endl;
        inOrderTraThrTree(root);
        return 0;
    }
    
    展开全文
  • 线索二叉树插入与删除

    千次阅读 2019-11-18 23:15:09
    #pragma once namespace Y{ template <class T> class TreeNode { T m_data; TreeNode<T> * m_left; TreeNode<T> * m_right; public: TreeNode(const T &... m_d...
  • 中序线索二叉树

    2021-08-01 23:45:38
    线索二叉树线索二叉树的基本概念中序线索二叉树的构造中序线索二叉树的遍历 线索二叉树的基本概念 中序线索二叉树的构造 中序线索二叉树的遍历
  • #include&lt;iostream&gt; using namespace std;...//二叉树定义 typedef struct BiTreeNode{ char data; BiTreeNode *lChild; BiTreeNode *rChild; int lTag,rTag; }BiTreeNode; ...
  • 1、线索二叉树 规律:在有n个节点的链式二叉树中必定存在n+1个指针域 正因为链式二叉树中有很多的空指针,可以让这些指针这向下一个节点,这样在遍历时可以不用递归,二使用循环,可以提高遍历速度。 #include <...
  • 线索二叉树JS

    2019-09-25 11:53:06
    线索二叉树 当用二叉链表来存储二叉树时,每次只能找到左右孩子的信息,不能直接找到其前驱和后继结点的信息。线索二叉树就解决了这个问题。 结点结构图: LChild Ltag Data Rtag RChild A.如果有左孩子,则LChild...
  • 中序线索二叉树(建立二叉树,线索化,输出二叉树)
  • 此程序需要完成如下要求:建立线索二叉树,并实现线索二叉树插入、删除和恢复线索的实现。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,233
精华内容 1,693
关键字:

线索二叉树插入