由于树结构经常是面试官拷问的知识点,掌握好它是必须的,又看了些资料,再试着记录一点心得。
一般无规律的树没什么意义,太复杂面试时间也有限。所以主要讨论的是二元搜索树(binary search tree)
二元搜索树的优势是查找很快。时间复杂度是O(log2(n)),也常写成O(log(n)).
因为比如
2x = n (x代表次数, n代表节点树(data size))
x = log2n
这种指数级的速度是很快的。2的10次方等于1204, 在这里等效为最多10次就可以从1024个数据中找出需要的节点来。
不过如果二叉树左右分布不均的话,甚至每个节点只有一个右节点,这样就成了链结构,就失去了该优势。
代码:
结构定义:
初始化二元搜索树
遍历:
查询节点:
增加父节点
一般无规律的树没什么意义,太复杂面试时间也有限。所以主要讨论的是二元搜索树(binary search tree)
二元搜索树的优势是查找很快。时间复杂度是O(log2(n)),也常写成O(log(n)).
因为比如
查询40这个节点,需要3次遍历,整个树节点是7。 于是有这个关系70
/ /
50 90
/ / / /
40 45 80 120
2x = n (x代表次数, n代表节点树(data size))
x = log2n
这种指数级的速度是很快的。2的10次方等于1204, 在这里等效为最多10次就可以从1024个数据中找出需要的节点来。
不过如果二叉树左右分布不均的话,甚至每个节点只有一个右节点,这样就成了链结构,就失去了该优势。
代码:
结构定义:
- typedef struct nodeT
- {
- struct nodeT *left;
- struct nodeT *right;
- int value;
- }node;
初始化二元搜索树
- #include <assert.h>
- #define NUM 7
- int data[NUM] = {70, 50, 90, 40, 45, 80, 120};
- /*
- input:
- data: 新节点data值
- return:
- 新节点指针
- */
- PNode newNode(int data)
- {
- PNode p = (PNode)malloc(sizeof(Node));
- assert( p != NULL);
- p->data = data;
- p->lChild = NULL;
- p->rChild = NULL;
- return p;
- }
- /*
- return:
- false:插入重复data值节点
- true: 成功构建
- */
- bool CreateBTree(PNode &root)
- {
- int i;
- root = newNode(data[0]);
- PNode p;
- PNode parent;
- for (i=1; i<NUM; i++)
- {
- p = root;
- while (p != NULL)
- {
- // 保存插入节点的父节点
- parent = p;
- if (data[i] > p->data)
- p = p->rChild;
- else if (data[i] < p->data)
- p = p->lChild;
- // 要求节点data值不重复
- else
- return false;
- }
- if (p == NULL)
- {
- // 新建节点,设置其data值和父节点
- p = newNode(data[i]);
- //p->parent = parent;
- if (p->data < parent->data)
- parent->lChild = p;
- else
- parent->rChild = p;
- }
- }
- return true;
- }
- void PreOrderTraversal(PNode root)
- {
- if (root == NULL)
- return;
- else
- {
- // printf的位置决定了三种遍历方法
- printf("%d ", root->data);
- PreOrderTraversal(root->lChild);
- PreOrderTraversal(root->rChild);
- }
- }
查询节点:
- /*
- params:
- value: 寻找data值为value的节点
- return:
- 成功: 返回该节点
- 失败: 返回NULL
- */
- PNode SearchNode(PNode root, int value)
- {
- if (root == NULL)
- return NULL;
- PNode p = root;
- while (p)
- {
- if (p->data < value)
- p = p->rChild;
- else if (p->data > value)
- p = p->lChild;
- else
- return p;
- }
- return NULL;
- }
- PNode newNode(int data)
- {
- PNode p = (PNode)malloc(sizeof(Node));
- assert( p != NULL);
- p->data = data;
- p->lChild = NULL;
- p->rChild = NULL;
- p->parent = NULL; //添加
- return p;
- }
- /*
- 添加父节点
- */
- void AddParent(PNode root)
- {
- PNode p;
- if (root == NULL)
- return;
- p = root;
- if (root->lChild != NULL)
- {
- root->lChild->parent = p;
- AddParent(root->lChild);
- }
- if (root->rChild != NULL)
- {
- root->rChild->parent = p;
- AddParent(root->rChild);
- }
- }