数据结构——二叉树

一、二叉树的递归定义    

  1.  要么二叉树没有根节点,是一棵空树。
  2.  要么二叉树由根节点、左子树、右子树组成,且左子树和右子树都是二叉树。   

 

 

二、二叉树的存储结构

  一般来说,二叉树使用链表来定义。二叉树每个结点有两条出边,因此指针域有两个——分别指向左子树和右子树的根结点地址,因此右把这种链表叫做二叉链表。其定义方式如下:

1 #define typename int
2 // 二叉树结构定义 
3 struct node {
4     typename data;        // 数据域
5     node* lchild;        // 指向左子树的根结点
6     node* rchild;        // 指向右子树的根结点 
7 };

 

 

  如果需要新建结点,可以使用下面的函数:

1 // 生成一个新节点,v为数据 
2 node* newNode(typename v) {
3     node* Node = (node*)malloc(sizeof(node));
4     Node->data = v;
5     // 初始状态下没有左右子树 
6     Node->lchild = Node->rchild = NULL;
7     return Node;
8 } 

 

 

 

 

 

 

三、二叉树的基本操作

  二叉树的常用操作有以下几个:二叉树的建立、二叉树结点的查找、修改、插入与删除。本节主要介绍查找、修改、插入、建树的通用思想。

 

  1. 二叉树结点的查找、修改

  查找操作是指在给定数据域的条件下,在二叉树中找到所有数据域为给定数据域的结点,并将它们的数据域修改为给定的数据域。  

  可以使用递归来完成查找修改操作。先判断当前结点是否是需要查找的结点:如果是,则对其进行修改操作;如果不是,则分别往该结点的左孩子和右孩子递归,直到当前结点为 NULL 为止。代码如下:

 1 // 在根结点为root的二叉树查找所有数据域为x的结点并修改为newdata 
 2 void search(node* root, typename x, typename newdata) {
 3     if(root == NULL) {
 4         return;        // 空树 
 5     }
 6     if(root->data == x) {    // 查到 x 
 7         root->data = newdata;    // 修改 
 8     }
 9     search(root->lchild, x, newdata);    // 遍历左子树
10     search(root->rchild, x, newdata);    // 遍历右子树      
11 } 

 

 

  2. 二叉树结点的插入

  二叉树结点的插入位置与二叉树本身的性质有关,下面代码以二叉排序树为例:

 1 // 在以*root为根结点的二叉树插入一个新节点 
 2 void insert(node** root, typename x) {
 3     if((*root) == NULL) {        // 找到插入位置 
 4         (*root) = newNode(x);
 5         return; 
 6     }
 7     if(x < (*root)->data) {        // 往左子树插入 
 8         insert(&((*root)->lchild), x);
 9     } else {                    // 往右子树插入 
10         insert(&((*root)->rchild), x);
11     }
12 }

 

 

  在上述代码中,函数参数使用了二维指针 **。这么做的原因是,在 insert 函数中新建了结点,并把新结点的地址赋给了当层的 root。

  那么,如何判断是否要加指针呢?一般来说,如果函数中需要新建结点,即对二叉树的结构做出修改,就需要加引用;如果只是修改当前已有结点的内容,或仅仅是遍历树,就不用加指针。

 

  3. 二叉树的创建

  二叉树的创建其实就是二叉树结点的插入过程,比较常用的写法是把需要插入的数据存储在数组中,然后再将它们使用 insert 函数一个个插入二叉树中,并最终返回根结点的指针 root。代码如下:

// 二叉树的建立 
node* create(typename data[], int n) {
    node* root = NULL;        // 新建空根结点 root 
    int i;
    for(i=0; i<n; ++i) {    // 将 data 中的数据插入二叉树 
        insert(&root, data[i]);
    } 
    return root;            // 返回根结点 
} 

 

 

  完整 C 代码如下:

 1 /*
 2     二叉树 
 3 */
 4 
 5 #include <stdio.h>
 6 #include <string.h>
 7 #include <math.h>
 8 #include <stdlib.h>
 9 #include <time.h>
10 #include <stdbool.h>
11 
12 #define typename int
13 // 二叉树结构定义 
14 typedef struct _node {
15     typename data;        // 数据域
16     struct _node* lchild;        // 指向左子树的根结点
17     struct _node* rchild;        // 指向右子树的根结点 
18 } node; 
19 
20 // 生成一个新节点,v为数据 
21 node* newNode(typename v) {
22     node* Node = (node*)malloc(sizeof(node));
23     Node->data = v;
24     // 初始状态下没有左右子树 
25     Node->lchild = Node->rchild = NULL;
26     return Node;
27 } 
28 
29 // 在根结点为root的二叉树查找所有数据域为x的结点并修改为newdata 
30 void search(node* root, typename x, typename newdata) {
31     if(root == NULL) {
32         return;        // 空树 
33     }
34     if(root->data == x) {    // 查到 x 
35         root->data = newdata;    // 修改 
36     }
37     search(root->lchild, x, newdata);    // 遍历左子树
38     search(root->rchild, x, newdata);    // 遍历右子树      
39 } 
40 
41 // 在以*root为根结点的二叉树插入一个新节点 
42 void insert(node** root, typename x) {
43     if((*root) == NULL) {        // 找到插入位置 
44         (*root) = newNode(x);
45         return; 
46     }
47     if(x < (*root)->data) {        // 往左子树插入 
48         insert(&((*root)->lchild), x);
49     } else {                    // 往右子树插入 
50         insert(&((*root)->rchild), x);
51     }
52 }
53 
54 // 二叉树的建立 
55 node* create(typename data[], int n) {
56     node* root = NULL;        // 新建空根结点 root 
57     int i;
58     for(i=0; i<n; ++i) {    // 将 data 中的数据插入二叉树 
59         insert(&root, data[i]);
60     } 
61     return root;            // 返回根结点 
62 } 
63 
64 // 输出二叉树,先序 
65 void print(node* root) {
66     if(root == NULL) {
67         return;
68     }
69     printf("%d ", root->data);
70     print(root->lchild);
71     print(root->rchild);
72 }
73 
74 int main() {
75     int data[5] = {1, 2, 3, 4, 5};
76     node* tree = create(data, 5);    // 创建二叉树 
77     print(tree);                    // 输出二叉树 
78     return 0;
79 }
二叉树基本操作

 

posted @ 2018-01-25 17:00  Just_for_Myself  阅读(530)  评论(0编辑  收藏  举报