二叉樹的建立


剛開始接觸圖論這一模塊是覺得什么二叉樹啊,什么堆啊,什么優先隊列啊這些東西很難搞,終於等到放假了,抱着本算法書,發現和教練說的一樣,樹是一種很神奇很簡單的東西,很討人喜歡。

二叉樹的性質:

性質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\n", 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\n", 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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM