二叉树的建立

刚开始接触图论这一模块是觉得什么二叉树啊,什么堆啊,什么优先队列啊这些东西很难搞,终于等到放假了,抱着本算法书,发现和教练说的一样,树是一种很神奇很简单的东西,很讨人喜欢。

二叉树的性质:

性质1:二叉树上结点数等于度为 2 的结点数加 1;

性质2:二叉树的第 i 层上至多有 2^( i-1 ) 个结点( i >= 1;

性质3:对于完全二叉树中编号为 i 的结点( 1 <= i <= N, N>= 1, N为结点数 ),有:

    (1)若 2*i <= N, 则编号为 i 的结点为分支结点, 否则为叶子结点。

    (2)若 N 为奇数, 则每个分支结点都既有左孩子,又有右孩子;若 N 为偶数, 则编号最大的分支结点(编号为 N/2 )只有左孩子没有右孩子,其余分支结                         点都既有左孩子,又有右孩子

建立二叉树结点数据的规则:

(1)以第一个建立的元素为根结点;

(2)依序将元素值与根结点进行比较

  ①若元素值大于根结点值,则将元素值往根结点的右子结点移动,若此右子结点为空,则将元素值存入,否则就重复比较直到找到合适的空结点;

  ②若元素值小于根结点值,则将元素值往根结点的左子结点移动,若此左子结点为空,则将元素值存入,否则就重复比较直到找到合适的空结点;

(上述的建立二叉树结点数据的规则满足了二叉排序树(二叉查找树)的条件)

这里包括三种建二叉树的简单方法:

一、一维数组表示法(优点简单粗暴,缺点维护这棵树不容易,牵一发而动全身)

二、结构数组表示法(同上)

///数组表示法
/*
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

const int MAXN = 32768; ///2^5
int tree[MAXN];         ///所有数组均从1开始

int create(int _tree[], int _node[], int len)
{
    int i, MAX = 1;
    _tree[1] = _node[1];
    int level = 1;
    for(int i = 2; i <= len; i++)
    {
        level = 1;
        while(_tree[level] != 0)   ///判断当前位置是否有值
        {
            if(_node[i] < _tree[level])   ///左子树
                level = level*2;
            else                          ///右子树
                level = level*2+1;
            if(MAX < level)        ///更新树数组的最大下标
                MAX = level;
        }
        _tree[level] = _node[i];         ///给结点赋值
    }
    return MAX;
}

int main()
{
    int N, num;
    scanf("%d", &N);
    int node[N+1];
    for(int i = 1; i <= N; i++)
        scanf("%d", &node[i]);
    num = create(tree, node, N);     ///建树

    for(int i = 1; i <= num-1; i++)
        printf("%d ", tree[i]);
    printf("%d
", tree[num]);

    return 0;
}
*/

///结构数组表示法

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

const int MAXN = 32768;

struct tree
{
    int left;
    int date;
    int right;

}b_tree[MAXN];

int N;
typedef struct tree treenode;

void create(int *node, int len)
{
    int i;
    int level;
    int position;                           ///左树-1, 右树1
    for(int i = 1; i <= len; i++)           ///依次建立其他结点
    {
        b_tree[i].date = node[i];           ///元素值存入结点
        level = 0;                          ///树根为0
        position = 0;
        while(position == 0)
        {
            if(node[i] > b_tree[level].date)    ///判断是否为右子树
            {
                if(b_tree[level].right != -1)
                    level = b_tree[level].right;
                else
                    position = -1;
            }
            else                                ///判断是否为左子树
            {
                if(b_tree[level].left != -1)
                    level = b_tree[level].left;
                else
                    position = 1;
            }
        }
        if(position == 1)                        ///连接左子树
            b_tree[level].left = i;
        else
            b_tree[level].right = i;             ///连接右子树
    }
}

void print()
{
    for(int i = 1; i <= N; i++)
    {
        printf("%d %d %d
", b_tree[i].left, b_tree[i].date, b_tree[i].right);
    }
}

int main()
{
    scanf("%d", &N);
    int node[N+1];
    for(int i = 1;i <= N; i++)
        scanf("%d", &node[i]);
    for(int i = 0; i < MAXN; i++)
    {
        b_tree[i].left = -1;
        b_tree[i].date = 0;
        b_tree[i].right = -1;
    }
    create(node, N);

    print();

    return 0;
}

三、链表表示法(按前序遍历输出)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 struct tree
 5 {
 6     struct tree *left;
 7     int date;
 8     struct tree *right;
 9 };
10 typedef struct tree treenode;
11 typedef struct tree * b_tree;
12 
13 b_tree add(b_tree root, int node)    ///插入结点+
14 {
15     b_tree newnode;
16     b_tree currentnode;
17     b_tree parentnode;
18 
19     newnode = (b_tree)malloc(sizeof(treenode));
20     newnode->date = node;
21     newnode->left = NULL;
22     newnode->right = NULL;
23 
24     if(root == NULL)         ///第一个结点建立
25         return newnode;
26     else
27     {
28         currentnode = root; ///储存当前结点
29         while(currentnode != NULL)     ///当前结点不为空
30         {
31             parentnode = currentnode;  ///储存父结点
32             if(currentnode->date > node)
33                 currentnode = currentnode->left;  ///左子树
34             else
35                 currentnode = currentnode->right; ///右子树
36         }
37         if(parentnode->date > node)
38             parentnode->left = newnode;
39         else
40             parentnode->right = newnode;
41     }
42     return root;
43 }
44 
45 b_tree create(int *data, int len)
46 {
47     int i;
48     b_tree root = NULL;
49     for(int i = 1; i <= len; i++)
50     {
51         root = add(root, data[i]);
52     }
53     return root;
54 }
55 
56 void print(b_tree root)
57 {
58     if(root != NULL)
59     {
60         cout << root->date << ' ';
61         print(root->left);
62         print(root->right);
63     }
64 }
65 
66 int main()
67 {
68     int N;
69     b_tree root = NULL;
70     cin >> N;
71     int node[N+1];
72     for(int i = 1; i <= N; i++)
73         cin >> node[i];
74     root = create(node, N);
75     print(root);
76     cout << endl;
77     return 0;
78 }
原文地址:https://www.cnblogs.com/ymzjj/p/9348698.html