2.8 树

2.8 树

    树是一种分层性数据结构。在一棵树里存储着一组项,每个项保存一个值,它可以有指针指向0个或多个元素,但只能被另一个项所指。树根是其中惟一的例外,没有其他项的指针指向它。

    实际存在许多不同种类的树,它们表示各种复杂的结构。在这里,我们使用二分检索树来说明树的原理。二分检索树的每个结点带有两个子结点指针,leftright,它们分别指向对应的子结点。而对于一个特定的节点,其左节点中一般储存着较小的值;而右节点中一般储存着较大的值。而这种存在形式则十分利于检索。

    我们同样使用Nameval型的结构体来作为一个节点。

typedef struct Nameval Nameval;
struct Nameval
{
	char *name;
	int value;
	Nameval *left;/*smaller value*/
	Nameval *right;/*bigger value*/
};

    由于树的许多结点包含多个指向其他元素的指针,所以,很多在表或者数组结构中需要O(n)时间的操作,在树中只需要O(log(n))时间。结点存在多个指针能减少为寻找一个结点所需要访问的结点个数,从而降低操作的复杂性。

    对于构建一个新的二叉树,我们一般在递归向下,根据情况确定左节点或者右节点,直到找到节点所处的正确位置。这个新的节点应该正确的初始化为一个名字、一个数值和两个空指针。

    对于构建一个新的叶子节点,一种直观的感觉就是顺着现有的枝杈来到末端,构建好之后仔原路返回。因此,递归就是一个很好的实现方式。

    则代码的实现则为:

#include "stdafx.h"
#include "stdlib.h"
#include "string.h"
#include <iostream>

using namespace std;

typedef struct Nameval Nameval;
struct Nameval
{
	char *name;
	int value;
	Nameval *left;
	Nameval *right;
};

/*插入节点*/
/*treep定义为搜索开始的节点*/
/*treep->left和treep->right都为指向下一个节点(叶子)的头地址*/
Nameval *insert(Nameval *treep, Nameval *newp)
{
	int cmp;
	if (treep == NULL)
	{
		/*插入节点*/
		return newp;
	}
	cmp = strcmp(newp->name, treep->name);
	if (cmp == 0)
	{
		printf("The name '%s' has already been created", newp->name);
	}
	/*搜索插入位置*/
	else if (cmp < 0)
	{
		treep->left = insert(treep->left, newp);
	}
	else
	{
		treep->right = insert(treep->right, newp);
	}
	/*原路返回*/
	return treep;
}

Nameval *lookup(Nameval *treep, char *name)
{
	int cmp;
	if (treep == NULL)
	{
		return NULL;
	}
	cmp = strcmp(name, treep->name);
	if (cmp == 0)
	{
		return treep;
	}
	else if (cmp < 0)
	{
		/*注意这里的return*/
		/*递归时,返回值的数量要与递归函数相匹配*/
		return lookup(treep->left, name);
	}
	else
	{
		return lookup(treep->right, name);
	}
}
void initial(Nameval *list, char *name, int value)
{
	list->left = NULL;
	list->right = NULL;
	list->value = value;
	list->name = name;
}
int main()
{
	Nameval *list_1 = NULL, *list_2 = NULL, *test = NULL;
	list_1 = (Nameval *)malloc(sizeof(Nameval));
	list_2 = (Nameval *)malloc(sizeof(Nameval));
	initial(list_1, "abc", 1);
	initial(list_2, "def", 2);
	/*验证是否函数调用成功*/
	cout << list_1->right << endl;
	list_2 = insert(list_1, list_2);
	cout << list_1->right << endl;
	test = lookup(list_1, "abc");
	cout << test->name << endl;
    return 0;
}


猜你喜欢

转载自blog.csdn.net/coulson_zhao/article/details/79874665
2.8