数据结构-二叉树

二叉树的定义与操作

一、二叉树的定义


    通用树结构是采用双亲孩子表示法模型建立的,每个结点都有一个指向其双亲的指针;每个结点

都有若干个指向其孩子的指针。但是我们还有另一种树的模型,那就是孩子兄弟表示法模型,每个结

点都有一个指向其第一个孩子的指针,每个结点都有一个指向其第一个右兄弟的指针;每个结点包含

一个数据指针和两个结点指针:

    数据指针:指向保存于树中的数据;
    
    孩子结点指针:指向第一个孩子;  

    兄弟结点指针:指向第一个右兄弟。

这种模型表示法的特点是能够表示任意的树型结构,每个结点中有且仅有三个指针域(数据指针、孩

子结点指针、兄弟结点指针),每个结点的结构简单,只有孩子结点和兄弟结点指针构成了“树

杈”。 

1>定义:二叉树是由 n(n>=0)个结点组成的有限集合,该集合或者为空,或者是由一个根结点加上

分别称为 左子树右子树的、互不相交的二叉树组成。

     满二叉树(Full Binary Tree):如果二叉树中所有的分支结点的度数都为2,且叶子结点都在同

一层次上,则称这类二叉树为满二叉树。

     完全二叉树(Complete Binary Tree):如果一棵具有n个结点的高度为k的二叉树,它的每一个结

点都与高度为k的满二叉树中编号为 1--n的结点一一对应,则称这棵二叉树为完全二叉树。(从上到

下,从左到右编号)。

完全二叉树的叶结点出现在最下面两层,最下层的叶节点一定出现在左边,倒数第二层的叶结点一定

出现在右边;完全二叉树中度为1的结点只有左孩子;同样结点数的二叉树,完全二叉树的高度最

小。

二、二叉树的深层性质

1>性质1:在二叉树的第i层最多有2的i-1次方幂个结点。(i > 1).

2>性质2:深度为k的二叉树最多有2的k次方幂-1个结点。(k>0);

3>性质3:对任何一棵二叉树,如果其叶结点有n0个,度为2的非叶结点有n2个,则有n0=n2+1.

4>性质4:具有n个结点的完全二叉树的高度为 [log2n]+1.

5>性质5:一棵具有n个结点的二叉树(高度为 [log2n]+1),按层次对结点进行编号,对任意的结点i有:

如果i=1,则结点i是二叉树的根;

如果i>1,则其双亲结点为[i/2];

如果2i<=n,则结点i的左子树为2i;

如果2i>n,则结点i无左子树;

如果2i+1<=n,则结点i的右孩子为2i+1;

如果2i+1>n,则结点i无右孩子

三、创建二叉树

1>指路法定位结点:指路法通过结点与目标结点的相对位置进行定位,可以避开二叉树递归的性质“线性”定位。思想:在c语言中可以利用bit位进行指路

    #define BT_LEFT 0
    #define BT_RIGHT 1
    
    typedef unsigned long long BTPos;

2>二叉树存储结构

    用结构体来定义二叉树中的指针域,二叉树的头结点也可以用结构体实现;

结点指针域定义:

typedef struct _tag_BTreeNode BTreeNode;
struct _tag_BTreeNode
{
    BTreeNode* left;
    BTreeNode* right;
};

头结点定义:

typedef struct _tag_BTree TBTree;
struct _tag_BTree
{
    int count;
    BTreeNode* root;
};

数据元素定义示例:
struct Node
{
    BTreeNode header;
    char v;
};
 

3>二叉树的操作

关键技巧:利用二进制的0和1分别表示left和right,位元算是实现指路法的基础。

while( (count > 0 ) && (current != NULL ) )
{
    bit = pos & 1;
    pos = pos >> 1;

    count--;
    
    parent = current;

    if( bit == BT_LEFT)
        current = current->left;
    
    else if( bit == BT_RIGHT )
        current = current->right;
}

#ifndef _BTREE_H_ #define _BTREE_H_ typedef void BTree; typedef struct _tag_BTreeNode BTreeNode; struct _tag_BTreeNode { BTreeNode* left; BTreeNode* right; }; typedef unsigned long long BTPos; typedef void (BTree_printf)(BTreeNode*); BTree* BTree_Create(); void BTree_Destroy(BTree* tree); void BTree_Clear(BTree* tree); int BTree_Empty(BTree* tree); int BTree_Insert(BTree* tree,BTreeNode* node,BTPos pos,int count,int flag); BTreeNode* BTree_Delete(BTree* tree,BTPos pos,int count); BTreeNode* BTree_Get(BTree* tree,BTPos pos,int count); BTreeNode* BTree_Root(BTree* tree); int BTree_Height(BTree* tree); int BTree_Count(BTree* tree); int BTree_Degree(BTree* tree); void BTree_Display(BTree* tree,BTree_printf* pFunc,int gap,char div); #endif #include <stdio h=""> #include <malloc h=""> #include "BTree.h" #define BT_LEFT 0 #define BT_RIGHT 1 typedef struct _tag_BTree TBTree; struct _tag_BTree { BTreeNode* root; int count; }; static void recursive_display(BTreeNode* node,BTree_printf* pFunc,int format,int gap,char div) { int i = 0; if((node != NULL) && (pFunc != NULL)) { for(i=0;i<format i="" printf="" c="" div="" pfunc="" node="" printf="" n="" if="" node-="">left != NULL) || ( node->right != NULL)) { recursive_display(node->left,pFunc,format+gap,gap,div); recursive_display(node->right,pFunc,format+gap,gap,div); } } else { for(i=0;i<format i="" printf="" c="" div="" printf="" n="" static="" int="" recursive_count="" btreenode="" root="" int="" ret="0;" if="" root="" null="" ret="recursive_count(root-">left) + 1 + recursive_count(root->right); } return ret; } static int recursive_height(BTreeNode* root) { int ret = 0; if( root != NULL) { int lh = recursive_height(root->left); int rh = recursive_height(root->right); ret = ((lh >= rh) ? lh : rh) + 1; } return ret; } static int recursive_degree(BTreeNode* root) { int ret = 0; if(root != NULL) { if(root->left != NULL) { ret++; } if(root->right != NULL) { ret++; } if(ret == 1) { int lg = recursive_degree(root->left); int rg = recursive_degree(root->right); if(ret < lg) { ret = lg; } if( ret < rg) { ret = rg; } } } return ret; } BTree* BTree_Create() { TBTree* ret = (TBTree*)malloc(sizeof(TBTree)); if(ret != NULL) { ret->root = NULL; ret->count = 0; } return ret; } void BTree_Destroy(BTree* tree) { free(tree); } void BTree_Clear(BTree* tree) { TBTree* btree = (TBTree*)tree; if(btree != NULL) { btree->root = NULL; btree->count = 0; } } int BTree_Empty(BTree* tree) { TBTree* btree = (TBTree*)tree; int ret = 0; if((btree != NULL) && (btree->count == 0)) { ret = 1; } return ret; } int BTree_Insert(BTree* tree,BTreeNode* node,BTPos pos,int count,int flag) { TBTree* btree = (TBTree*)tree; if((btree != NULL) && (node != NULL) && (0 <= pos ) && ( 0 <= count) && ((flag ==0)||(flag == 1))) { BTreeNode* parent = NULL; BTreeNode* current = btree->root; node->left = NULL; node->right = NULL; int bit = 0; while((current != NULL) && (count != 0)) { bit = pos & 1; pos = pos >> 1; parent = current; if(bit == BT_LEFT) { current = current->left; } else if(bit == BT_RIGHT) { current = current->right; } count--; } if(flag == BT_LEFT) { node->left = current; } else if(flag == BT_RIGHT) { node->right = current; } if(parent != NULL) { if(bit == BT_LEFT) { parent->left = node; } else if(bit == BT_RIGHT) { parent->right = node; } } else { btree->root = node; } btree->count++; } } BTreeNode* BTree_Delete(BTree* tree,BTPos pos,int count) { TBTree* btree = (TBTree*)tree; BTreeNode* ret = NULL; if(btree != NULL) { BTreeNode* parent = NULL; BTreeNode* current = btree->root; int bit = 0; while((current != NULL) && (count != 0)) { bit = pos & 1; pos = pos >> 1; parent = current; if(bit == BT_LEFT) { current = current -> left; } else if(bit == BT_RIGHT) { current = current -> right; } count--; } if(parent != NULL) { if(bit == BT_LEFT) { parent->left = NULL; } else if(bit == BT_RIGHT) { parent->right = NULL; } } ret = current; btree->count = btree->count - recursive_count(ret); } return ret; } BTreeNode* BTree_Get(BTree* tree,BTPos pos,int count) { TBTree* btree = (TBTree*)tree; BTreeNode* ret = NULL; if((btree != NULL) && (0 <= pos) && (0 <= count)) { BTreeNode* current = btree->root; int bit = 0; while((current != NULL) && (count != 0)) { bit = pos & 1; pos = pos >> 1; if(bit == BT_LEFT) { current = current->left; } else if( bit == BT_RIGHT) { current = current->right; } count--; } ret = current; } return ret; } BTreeNode* BTree_Root(BTree* tree) { return BTree_Get(tree,0,0); } int BTree_Height(BTree* tree) { TBTree* btree = (TBTree*)tree; int ret = 0; if( btree != NULL) { ret = recursive_height(btree->root); } return ret; } int BTree_Count(BTree* tree) { TBTree* btree = (TBTree*)tree; int ret = 0; if(btree != NULL) { ret = recursive_count(btree->root); } return ret; } int BTree_Degree(BTree* tree) { TBTree* btree = (TBTree*)tree; int ret = 0; if(btree != NULL) { ret = recursive_degree(btree->root); } return ret; } void BTree_Display(BTree* tree,BTree_printf* pFunc,int gap,char div) { TBTree* btree = (TBTree*)tree; if((btree != NULL) && (pFunc != NULL)) { recursive_display(btree->root,pFunc,0,gap,div); } } <textarea style="WIDTH: 185px; HEIGHT: 128px" class="c++" rows="7" readonly="readonly" name="code"> #include <stdio h=""> #include <stdlib h=""> #include "BTree.h" /* run this program using the console pauser or add your own getch, system("pause") or input loop */ typedef struct _tag_value { BTreeNode header; char v; } DataElem; void printf_data(BTreeNode* node) { printf("%c",((DataElem*)node)->v); } int main(int argc, char *argv[]) { DataElem v1={{NULL,NULL},'A'}; DataElem v2={{NULL,NULL},'B'}; DataElem v3={{NULL,NULL},'C'}; DataElem v4={{NULL,NULL},'D'}; DataElem v5={{NULL,NULL},'E'}; DataElem v6={{NULL,NULL},'F'}; DataElem v7={{NULL,NULL},'G'}; DataElem v8={{NULL,NULL},'H'}; BTree* tree = BTree_Create(); BTree_Insert(tree,(BTreeNode*)&v1,0,0,0); BTree_Insert(tree,(BTreeNode*)&v2,0x00,1,0); BTree_Insert(tree,(BTreeNode*)&v3,0x01,1,0); BTree_Insert(tree,(BTreeNode*)&v4,0x00,2,0); BTree_Insert(tree,(BTreeNode*)&v5,0x02,2,0); BTree_Insert(tree,(BTreeNode*)&v6,0x02,3,0); BTree_Insert(tree,(BTreeNode*)&v7,0x06,3,0); BTree_Insert(tree,(BTreeNode*)&v8,0x00,3,0); printf("²åÈëÔªËØºó\n"); BTree_Display(tree,printf_data,4,'*'); printf("Ê÷µÄ½áµãÊý:\n"); printf("Ê÷µÄ½áµãÊýÊÇ%d\n",BTree_Count(tree)); printf("Ê÷µÄ¸ß¶È:\n"); printf("Ê÷µÄ¸ß¶ÈÊÇ%d\n",BTree_Height(tree)); printf("Ê÷µÄ¶È:\n"); printf("Ê÷µÄ¶ÈÊÇ%d\n",BTree_Degree(tree)); printf("Ê÷µÄ¸ù½áµãÔªËØÊÇ:\n"); printf("Ê÷µÄ¸ù½áµãÔªËØÊÇ%c\n",((DataElem*)BTree_Root(tree))->v); printf("Ê÷µÄµÚÈý¸öÔªËØÊÇ:\n"); printf("Ê÷µÄµÚÈý¸öÔªËØÊÇ%c\n",((DataElem*)BTree_Get(tree,0x00,2))->v); BTree_Delete(tree,0x00,3); printf("ɾ³ýÔªËØHºó\n"); BTree_Display(tree,printf_data,4,'*'); BTree_Delete(tree,0x02,2); printf("ɾ³ýÔªËØEºó\n"); BTree_Display(tree,printf_data,4,'*'); printf("Ê÷µÄ½áµãÊý:\n"); printf("Ê÷µÄ½áµãÊýÊÇ%d\n",BTree_Count(tree)); printf("Ê÷µÄ¸ß¶È:\n"); printf("Ê÷µÄ¸ß¶ÈÊÇ%d\n",BTree_Height(tree)); BTree_Delete(tree,0x01,1); printf("ɾ³ýÔªËØHºó\n"); BTree_Display(tree,printf_data,4,'*'); printf("Ê÷µÄ¶È:\n"); printf("Ê÷µÄ¶ÈÊÇ%d\n",BTree_Degree(tree)); BTree_Clear(tree); printf("Çå¿ÕÊ÷ºó\n"); BTree_Display(tree,printf_data,4,'*'); printf("Ê÷µÄ½áµãÊý:\n"); printf("Ê÷µÄ½áµãÊýÊÇ%d\n",BTree_Count(tree)); printf("Ê÷µÄ¸ß¶È:\n"); printf("Ê÷µÄ¸ß¶ÈÊÇ%d\n",BTree_Height(tree)); printf("Ê÷µÄ¶È:\n"); printf("Ê÷µÄ¶ÈÊÇ%d\n",BTree_Degree(tree)); BTree_Destroy(tree); return 0; } </stdlib></stdio>

转载于:https://www.cnblogs.com/pangblog/p/3310795.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值