数据结构笔记3---树

导读

1.树的简介及性质
2.树的创建,递归遍历(创建,层序插入元素,递归先中后序遍历)
3.树的非递归遍历(前中后序),层序遍历

树的简介及性质

完全二叉树的例子

完全二叉树反例

二叉树的性质

N0:叶节点数
N1:度数为1的节点数,以此类推

二叉树:N0=N2+1
m叉树:N0=1+N2+2N3+3N4+….+(m-1)Nm

树的创建,递归遍历

#include <iostream>
using namespace std;

typedef struct TreeNode *BinTree;
struct TreeNode{
    int data;
    BinTree Left;
    BinTree Right;
};

//树的节点类型要写在队列节点之前

typedef struct Node *node;
struct Node{
    BinTree data;//队列的数据类型应为BinTree
    node next;
};


typedef struct QNode *queue;
struct QNode{
    node front;
    node rear;
};


queue init(){
    node head=new Node;
    queue queue=new QNode;
    queue->front=queue->rear=head;
    head->next=NULL;
    return queue;
}


void Push(queue &queue,BinTree data){
    node node=new Node;
    node->data=data;
    node->next=queue->rear->next;
    queue->rear->next=node;
    queue->rear=queue->rear->next;
}


bool Isempty1(queue queue){
    bool flag;
    if(queue->front->next==NULL)
        flag=true;
    else flag=false;
    return flag;
}


BinTree Pop(queue &queue){
    BinTree result;
    if(Isempty1(queue)){
        cout<<"It's empty!"<<endl;
        return NULL;
    }
    else{
        node node;
        node=queue->front->next;
        queue->front->next=queue->front->next->next;
        result=node->data;
        delete(node);
        if(Isempty1(queue))
            queue->rear=queue->front;
        //此处if判断非常重要,目的是在空栈时让rear回到原位
        return result;
    }
}

//+++++++++++++++下边是针对树进行的操作++++++++++++++++++++++++++
//判空
bool Isempty(BinTree bintree){
    bool flag;
    if(bintree==NULL)
        flag=true;
    else flag=false;
    return flag;
}

//借助队列层序插入元素
void Insert(BinTree &bintree,int data){
    //如果还没有根节点,就创一个
    if(bintree==NULL){
        bintree=new TreeNode;
        bintree->data=data;
        bintree->Left=NULL;
        bintree->Right=NULL;
    }
    else{
        BinTree s=new TreeNode;
        //s是用来接收data的
        s->data=data;
        s->Left=NULL;
        s->Right=NULL;
        //创建一个队列并将树根入队
        queue queue;
        queue=init();
        Push(queue,bintree);
        while(!Isempty1(queue)){
            BinTree p=Pop(queue);
            if(p->Left==NULL){
                p->Left=s;
                break;
            }
            else if(p->Right==NULL){
                p->Right=s;
                break;
            }
            else{
                Push(queue,p->Left);
                Push(queue,p->Right);
            }
        }
    }
}

//递归先序遍历输出
void PreOrderTraversal(BinTree bintree){
    //有递归时,不要随便加语句(比如下边),这是递归的特殊性
    //if(Isempty(bintree))
    //cout<<"It's empty"<<endl;
    if(!Isempty(bintree)){
        cout<<bintree->data<<" ";
        PreOrderTraversal(bintree->Left);
        PreOrderTraversal(bintree->Right);
    }
}

//递归中序遍历输出
void InOrderTraversal(BinTree bintree){
    if(!Isempty(bintree)){
        InOrderTraversal(bintree->Left);
        cout<<bintree->data<<" ";
        InOrderTraversal(bintree->Right);
    }
}

//递归后序遍历输出
void PostOrderTraversal(BinTree bintree){
    if(!Isempty(bintree)){
        PostOrderTraversal(bintree->Left);
        PostOrderTraversal(bintree->Right);
        cout<<bintree->data<<" ";
    }
}



int main(){
    BinTree bintree=NULL;
    for(int i=1;i<=7;i++)
     Insert(bintree,i);
    PreOrderTraversal(bintree);
    cout<<endl;
    InOrderTraversal(bintree);
    cout<<endl;
    PostOrderTraversal(bintree);
    cout<<endl;
    return 0;
}


输出结果
1 2 4 5 3 6 7
4 2 5 1 6 3 7
4 5 2 6 7 3 1
Program ended with exit code: 0

树的非递归遍历,层序遍历

#include <iostream>
using namespace std;

typedef struct TreeNode *BinTree;
struct TreeNode{
    int data;
    BinTree Left;
    BinTree Right;
};

//树的节点类型要写在队列节点之前

//++++++++++++++++以下是队列的创建过程+++++++++++++++++
typedef struct Node *node;
struct Node{
    BinTree data;//队列的数据类型应为BinTree
    node next;
};


typedef struct QNode *queue;
struct QNode{
    node front;
    node rear;
};


queue init(){
    node head=new Node;
    queue queue=new QNode;
    queue->front=queue->rear=head;
    head->next=NULL;
    return queue;
}


void Push(queue &queue,BinTree data){
    node node=new Node;
    node->data=data;
    node->next=queue->rear->next;
    queue->rear->next=node;
    queue->rear=queue->rear->next;
}


bool Isempty1(queue queue){
    bool flag;
    if(queue->front->next==NULL)
        flag=true;
    else flag=false;
    return flag;
}


BinTree Pop(queue &queue){
    BinTree result;
    if(Isempty1(queue)){
        cout<<"It's empty!"<<endl;
        return NULL;
    }
    else{
        node node;
        node=queue->front->next;
        queue->front->next=queue->front->next->next;
        result=node->data;
        delete(node);
        if(Isempty1(queue))
            queue->rear=queue->front;
        //此处if判断非常重要,目的是在空栈时让rear回到原位
        return result;
    }
}
//+++++++++++++++下边是堆栈的创建过程++++++++++++++++++++++++++++
typedef struct SNode *snode;
struct SNode{
    BinTree data;//栈的数据类型应为BinTree
    snode next;
};

//创建
snode init2(){
    snode Stack=new SNode;
    Stack->next=NULL;
    return Stack;
}

//入栈
void Push(snode &Stack,BinTree data){
    snode s=new SNode;
    s->data=data;
    s->next=Stack->next;
    Stack->next=s;
}

//出栈
BinTree Pop(snode &Stack){
    snode s;
    BinTree result;
    if(Stack->next==NULL){
        cout<<"It's empty!"<<endl;
        return NULL;
    }
    else{
        s=Stack->next;
        Stack->next=Stack->next->next;
        result=s->data;
        delete(s);
        return result;
    }

}

//判空
bool Isempty2(snode Stack){
    bool flag;
    if(Stack->next==NULL)
        flag=true;
    else flag=false;
    return flag;
}
//+++++++++++++++下边是针对树进行的操作++++++++++++++++++++++++++
//判空
bool Isempty(BinTree bintree){
    bool flag;
    if(bintree==NULL)
        flag=true;
    else flag=false;
    return flag;
}

//借助队列层序插入元素
void Insert(BinTree &bintree,int data){
    //如果还没有根节点,就创一个
    if(bintree==NULL){
        bintree=new TreeNode;
        bintree->data=data;
        bintree->Left=NULL;
        bintree->Right=NULL;
    }
    else{
        BinTree s=new TreeNode;
        //s是用来接收data的
        s->data=data;
        s->Left=NULL;
        s->Right=NULL;
        //创建一个队列并将树根入队
        queue queue;
        queue=init();
        Push(queue,bintree);
        while(!Isempty1(queue)){
            BinTree p=Pop(queue);
            if(p->Left==NULL){
                p->Left=s;
                break;
            }
            else if(p->Right==NULL){
                p->Right=s;
                break;
            }
            else{
                Push(queue,p->Left);
                Push(queue,p->Right);
            }
        }
    }
}

//借助堆栈非递归先序遍历输出

void PreOrderTraversal(BinTree bintree){
    BinTree T=bintree;
    snode Stack=init2();
    while(T||!Isempty2(Stack)){
    //一直走到树的左边,输出后入栈
        while(T){
            cout<<T->data<<" ";
            Push(Stack,T);
            T=T->Left;
        }
    //下边语句的作用是转向树的右边分支
        if(!Isempty2(Stack)){
            T=Pop(Stack);
            T=T->Right;
        }
    }
}

//借助堆栈非递归中序遍历输出

void InOrderTraversal(BinTree bintree){
    BinTree T=bintree;
    snode Stack =init2();
    while(T||!Isempty2(Stack)){
        //一直走到树的最左边
        while(T){
            Push(Stack,T);
            T=T->Left;
        }
        //出栈并输出
        if(!Isempty2(Stack)){
            T=Pop(Stack);
            cout<<T->data<<" ";
            T=T->Right;
        }
    }
}

//借助堆栈非递归后序遍历输出
void PostOrderTraversal(BinTree bintree){
    BinTree T=bintree;
    snode Stack1=init2();
    snode Stack2=init2();
    if(T==NULL) return;
    else Push(Stack1,T);
//后序遍历三步走
//1:将栈Stack1的Top压入栈Stack2
//2:检查栈Stack1的Top有没有左子,有的话压入栈Stack1
//3:检查栈Stack2的Top有没有右子,有的话压入栈Stack2
//当栈Stack1空时,输出栈Stack2

    while(!Isempty2(Stack1)){
        T=Pop(Stack1);
        Push(Stack2,T);
        if(T->Left!=NULL)
            Push(Stack1,T->Left);
        if(T->Right!=NULL)
            Push(Stack1,T->Right);
    }
    while(!Isempty2(Stack2))
        cout<<Pop(Stack2)->data<<" ";
}

//借助队列层序遍历输出
void LevelOrderTraversal(BinTree bintree){
    BinTree T=bintree;
    queue queue=init();
    if(Isempty(T)) return;
    else Push(queue,T);
//层序遍历三步走:
//1 如果队列不空出队
//2 如果出队元素左子不空,将左子入队
//3 如果出队元素右子不空,将右子入队
    while(!Isempty1(queue)){
        T=Pop(queue);
        cout<<T->data<<" ";
        if(T->Left!=NULL)
            Push(queue,T->Left);
        if(T->Right!=NULL)
            Push(queue,T->Right);
    }
}

int main(){
    BinTree bintree=NULL;
    for(int i=1;i<=7;i++)
     Insert(bintree,i);
    PreOrderTraversal(bintree);
    cout<<endl;
    InOrderTraversal(bintree);
    cout<<endl;
    PostOrderTraversal(bintree);
    cout<<endl;
    LevelOrderTraversal(bintree);
    cout<<endl;
    return 0;
}


输出结果

1 2 4 5 3 6 7
4 2 5 1 6 3 7
4 5 2 6 7 3 1
1 2 3 4 5 6 7
Program ended with exit code: 0

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值