二叉树c++

原创、转载请注明出处

二叉树特点

对于完全二叉树,第n层结点的结点个数是2的n次方个,对于第k个结点,它的左子节点是2k,右子节点是2k+1。

前序遍历

中序遍历:

后序遍历:

 

一、结构

二叉树有2类表示方法:链式和数组模拟。

 

其中数组模拟有2种:1.一个数组,数组下标代表完全二叉树的编号,对于普通二叉树,没有结点的为空,有节点的地方数组值为二叉树权值。

                                2.2个数组l[id]、r[id],二叉树结点的权值是编号,数组下标是编号,r[i]的数组值是结点i的右结点编号。(权值各不相同且都为正整数才能用这种方式表示)

 

二、构造二叉树

1.最基础的输入方式(数组的只写了一种):

<1>根据层次遍历构造二叉树,例如:

●链表结构代码:

#include "stdafx.h"
#include <iostream>
#include<sstream>
using namespace std;

struct BinaryTree
{
    char data;
    BinaryTree *lch;
    BinaryTree *rch;
};

char a[1000];

void createTree(BinaryTree* &p, int pos)
{
    if (a[pos] == '#')
    {
        p = nullptr;
        return;
    }
    p = new BinaryTree;
    p->data = a[pos];
    createTree(p->lch, pos * 2);
    createTree(p->rch, pos * 2 + 1);
}

void preOrder(BinaryTree* p)
{
    if (p == nullptr)
    {
        return;
    }
    //cout << p->data;
    preOrder(p->lch);
    cout << p->data;
    preOrder(p->rch);
    //cout << p->data;
}

int main()
{
    string str;
    getline(cin, str);
    stringstream s(str);
    int i = 1;
    while (s >> a[i])
    {
        i++;
    }

    BinaryTree* root = new BinaryTree;

    createTree(root, 1);

    preOrder(root);
    cout << endl;
}
View Code

          注意构建函数,一定是指针引用。如果是指针会发生如下情况:实参赋给形参,形参又指向了另一个块新开辟的地址,最后导致,我想创建树,但是创建函数并没有改变传入的根节点。

●链表结构代码(智能指针):

#include<iostream>
#include<string>
#include<sstream>
#include<memory>
using std::cin;
using std::cout;
using std::endl;
using std::make_shared;
using std::shared_ptr;
using std::string;
using std::stringstream;

char a[1000];

struct tree
{
    char ele;
    shared_ptr<tree> left;
    shared_ptr<tree> right;
};

void build(shared_ptr<tree> &p,int pos)
{
    if(a[pos] == '#')
    {
        p = nullptr;
        return;
    }
    p = make_shared<tree>();
    p->ele = a[pos];
    build(p->left,pos*2);
    build(p->right,pos*2 + 1);
}

void preOrder(shared_ptr<tree> p)
{
    if(p == nullptr)
    {
        return;
    }
    cout << p->ele << ' ';
    preOrder(p->left);
    preOrder(p->right);
}

void inOrder(shared_ptr<tree> p)
{
    if(p == nullptr)
    {
        return;
    }
    inOrder(p->left);
    cout << p->ele << ' ';
    inOrder(p->right);
}

int main()
{
    string str;
    getline(cin,str);
    stringstream s(str);
    int leng = 1;
    while(s >> a[leng])
    {
        leng++;
    }

    shared_ptr<tree> root;

    build(root,1);
    cout << endl;

    preOrder(root);
    cout << endl;

    inOrder(root);
    cout << endl;
    return 0;
}
View Code

●数组结构代码:

#include<iostream>
#include<string>
#include<sstream>
using std::stringstream;
using std::string;
using std::cin;
using std::cout;
using std::endl;

char a[1000];

void read_list(char *arr)
{
    string str;
    getline(cin,str);
    stringstream s(str);
    int leng = 1;
    while(s >> arr[leng])
    {
        leng++;
    }
}

void preOrder(int pos)
{
    if(a[pos] == '#')
        return ;
    cout << a[pos] << ' ';
    preOrder(pos * 2);
    preOrder(pos * 2 + 1);
}

void inOrder(int pos)
{
    if(a[pos] == '#')
        return ;
    inOrder(pos * 2);
    cout << a[pos] << ' ';
    inOrder(pos * 2 + 1);
}

int main()
{
    read_list(a);
    preOrder(1);
    cout << endl;
    inOrder(1);
    cout << endl;
    return 0;
}
View Code

 

<2>根据前序(没有中序和后序)遍历构造二叉树,例如:

●链表结构代码:

#include "stdafx.h"
#include <iostream>
using namespace std;

struct Binarytree
{
    char data;
    Binarytree* lch;
    Binarytree* rch;
};

void createTree(Binarytree* &p)
{
    char c;
    cin >> c;
    if (c == '#')
    {
        p = nullptr;
        return;
    }
    p = new Binarytree;
    p->data = c;
    createTree(p->lch);
    createTree(p->rch);
}

void preOrder(Binarytree *p)
{
    if (p == nullptr)
    {
        return;
    }
    cout << p->data << ' ';
    preOrder(p->lch);
    preOrder(p->rch);
}

void inOrder(Binarytree *p)
{
    if (p == nullptr)
    {
        return;
    }
    inOrder(p->lch);
    cout << p->data << ' ';
    inOrder(p->rch);
}

void postOrder(Binarytree *p)
{
    if (p == nullptr)
    {
        return;
    }
    postOrder(p->lch);
    postOrder(p->rch);
    cout << p->data << ' ';
}

int main()
{
    Binarytree* root = new Binarytree;
    createTree(root);
    preOrder(root);
    cout << endl;
    inOrder(root);
    cout << endl;
    postOrder(root);
    cout << endl;
}
View Code

          注意构建函数,一定是指针引用。如果是指针会发生如下情况:实参赋给形参,形参又指向了另一个块新开辟的地址,最后导致,我想创建树,但是创建函数并没有改变传入的根节点。  

●链表结构代码(智能指针):

#include<iostream>
#include<memory>
using std::cin;
using std::cout;
using std::endl;
using std::make_shared;
using std::shared_ptr;

struct tree
{
    char ele;
    shared_ptr<tree> left;
    shared_ptr<tree> right;
};

void build(shared_ptr<tree> &p)//输入前序遍历顺序确定结构
{
    char a;
    cin >> a;
    if(a == '#')
    {
        p = nullptr;
        return;
    }
    p = make_shared<tree>();
    p->ele = a;
    build(p->left);
    build(p->right);
}

void preOrder(shared_ptr<tree> p)
{
    if(p == nullptr)
    {
        return;
    }
    cout << p->ele << ' ';
    preOrder(p->left);
    preOrder(p->right);
}

void inOrder(shared_ptr<tree> p)
{
    if(p == nullptr)
    {
        return;
    }
    inOrder(p->left);
    cout << p->ele << ' ';
    inOrder(p->right);
}

int main()
{
    shared_ptr<tree> root;

    build(root);
    cout << endl;

    preOrder(root);
    cout << endl;

    inOrder(root);
    cout << endl;
    return 0;
}
View Code

●数组结构代码:

#include<iostream>
using std::cin;
using std::cout;
using std::endl;

char a[1000];

void build(int pos)
{
    cin >> a[pos];
    if(a[pos] == '#')
    {
        return;
    }
    build(pos * 2);
    build(pos * 2 + 1);
}

void preOrder(int pos)
{
    if(a[pos] == '#')
        return ;
    cout << a[pos] << ' ';
    preOrder(pos * 2);
    preOrder(pos * 2 + 1);
}

void inOrder(int pos)
{
    if(a[pos] == '#')
        return ;
    inOrder(pos * 2);
    cout << a[pos] << ' ';
    inOrder(pos * 2 + 1);
}

int main()
{
    build(1);

    preOrder(1);
    cout << endl;

    inOrder(1);
    cout << endl;
    return 0;
}
View Code

 三、扩展

大概意思:

1.搜索树:节点权值从左到右递增,和用数组二分搜索的区别是,这种结构便于插入和删除(类似链表和数组的区别)

2.平衡树:每个节点的左右子树高度相差不超过1

3.红黑树:树的节点不是红色就是黑色,根和外部节点是黑色,没有2个相连的红节点

 

posted @ 2017-10-09 18:06  哲贤  阅读(277)  评论(0编辑  收藏  举报