您的位置:首页 > 理论基础 > 数据结构算法

常用数据结构3——二叉树

2013-03-25 10:38 169 查看
下边这段话是百度百科中二叉树的定义,孤直接将其拷贝过来: 在计算机科学中,树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构。二叉树是每个节点最多有两个子树的有序树。通常子树被称作“左子树”(left
subtree)和“右子树”(right subtree)。二叉树常被用于实现
二叉查找树二叉堆。值得注意的是,二叉树不是树的特殊情形。在图论中,二叉树是一个连通的无环图,并且每一个顶点的度不大于3。有根二叉树还要满足根结点的度不大于2。有了根结点后,每个顶点定义了唯一的根结点,和最多2个子结点。然而,没有足够的信息来区分左结点和右结点。

虽然普通二叉树在业界用的很少(可能主要是考虑到平均时间复杂度),大家用的都是些什么avl、B+B-、红黑树等等,但对初学者而言首先弄清楚普通树的操作就相当于练武的人先练习蹲马步。
上代码。
/***************************************************************************
程序文件名 :binTree.c
作者       :船长
日期       :20110928
版本       :1.0
实现功能  :有序二叉树的创建、插入、显示、删除等
***************************************************************************
修改记录:
Modi Report:Format: <number>, <time>, <author>, <desc>
***************************************************************************/

/** @file:binTree.c
* @details:本文件实现了有序二叉树的创建、插入、显示、删除等等操作
*/

#include<stdio.h>
#include<stdlib.h>

typedef int dataType;    //定义数据类型
typedef struct binaryTree_s
{
dataType nodeData;
struct binaryTree_s *leftChild;  //指向左子树的指针
struct binaryTree_s *rightChild; //指向右子树的指针
}binTree;               //定义二叉树的数据结构

/**************************************************************************
函数原型: void insertBinTree(binTree * root, binTree *node)
说明    :将node结点插入根为root的二叉树中, 非递归实现
输入    :binTree * root,被插入树的根
binTree *node,待插入的结点
返回    :0 成功,-1 失败
**************************************************************************/
int insertBinTree(binTree * root, binTree *node)
{
if (root==NULL || node==NULL)return;  //若其中一个为空就不做任何操作
binTree * p=root;                     //定义一个指针变量
binTree * parent;					  //用来保存父结点指针
while(1)
{
if(node->nodeData >p->nodeData)   //若待插入节点的数据大,则插入右子树
{
parent = p;
p = p->rightChild;
if(NULL==p)					  //这里没结点,就在这里插入
{
parent->rightChild=node;
return 0;
}
else
continue;
}
else if(node->nodeData < p->nodeData)//若待插入节点的数据小,则插入左子树
{
parent = p;
p = p->leftChild;
if(NULL==p)
{
parent->leftChild=node;
return 0;
}
else
continue;
}
else
{
return -1;						//已经有了,不插入
}
}
}

/**************************************************************************
函数原型: binTree *creatBinTree(dataType data)
说明    :创建二叉树根节点
输入    :dataType data,根结点的数据元素
返回    :binTree * ,二叉树的根
**************************************************************************/
binTree *creatBinTree(dataType data)
{
binTree * root = (binTree*)calloc(1,sizeof(binTree)) ; //为根节点分配内存
if(NULL==root)
{
printf("Creat binary tree fail!");
return NULL;
}
root->nodeData = data;
return root;
}

/**************************************************************************
函数原型: void showBinTree_midOrder(binTree * root)
说明    :中序遍历并显示该有序二叉树
输入    :binTree * root,待遍历显示的二叉树根节点
返回    :无
**************************************************************************/
void showBinTree_midOrder(binTree * root)
{
if(NULL==root)return;
showBinTree_midOrder(root->leftChild);  //先中序遍历左子树
printf("0x%x:data %d,  left child addr:0x%x,\tright child addr:0x%x\r\n",
&root->nodeData,root->nodeData,root->leftChild,root->rightChild);
showBinTree_midOrder(root->rightChild); //显示根结点元素后,遍历右子树
}

/**************************************************************************
函数原型: void deleteBinTree(binTree ** pRoot)
说明    :删除有序二叉树
输入    :binTree ** pRoot,待删除的二叉树根节点
返回    :无
**************************************************************************/
void deleteBinTree(binTree *root)
{
if(NULL==root)return;
if(root->leftChild!=NULL)
{
deleteBinTree(root->leftChild);    //删除左子树
}

if (root->rightChild!=NULL)
{
deleteBinTree(root->rightChild);   //删除右子树
}
free(root);								 //释放根结点内存
}

int main()
{
dataType i;
binTree * root = creatBinTree(4);
binTree *pTreeNode=(binTree*)calloc(20,sizeof(binTree));
for(i=0;i<10;i++)
{
pTreeNode[i].nodeData=3*i;
if(insertBinTree(root,&pTreeNode[i])<0)
{
free(&pTreeNode[i]); //插入失败,释放
}
}

for(i=0;i<10;i++)
{
pTreeNode[10+i].nodeData=2*i;
if(insertBinTree(root,&pTreeNode[10+i])<0)
{
free(&pTreeNode[i]);
}
}
showBinTree_midOrder(root);
deleteBinTree(root);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: