二叉树用C++如何实现?

二叉树用C++如何实现?,第1张

二叉树是程序应用得比较多的一种结构。它可以反映物体之间的层次结构,还能通过孩子和双亲反映两物体之间某些特殊关系;排序二叉树还能帮助我们进行排序,并因此而提供快速的查找;二叉树基础上的伸展树能不断地优化我们系统的结构。并查集能很好地让进行分类;小根堆能帮助快速找到值最小的结点,它是优先队列的雏形。所有的这些都是以二叉树为基础的。

实现的二叉树的基本功能包括前中后序的递归和非递归访问,求结点个数和叶子结点个数,还有求树高。这些是用C++类实现的。

BTreeh文件(类声明文件)
[cpp] view plain copy
#ifndef BTREE_H  
#define BTREE_H  
  
struct BTreeNode  
{  
    int data;  
    BTreeNode lChild,rChild;  
};  
  
class BTree  
{public:  
    void setRoot(BTreeNode r){ root=r;}  
    BTreeNode getRoot(){ return root;}  
  
    //中序遍历(递归)  
    void inOrder();  
    //中序遍历(非递归)  
    void NotReInOrder();  
    BTreeNode createBTree();  
  
    //前序遍历(递归)  
    void preOrder();  
    //前序遍历(非递归)  
    void NotRePreOrder();  
  
    //后序遍历(递归)  
    void postOrder();  
      
    //后序遍历(非递归)  
    void NotRePostOrder();  
  
    //求结点个数  
    int BTreeSize();  
    //求叶子结点个数  
    int BTreeLeaves();  
  
    //求树高  
    int BTreeHeight();  
    //层次法求树高  
    int layerHeight();  
      
protected:  
    //中序遍历  
    void inOrder(BTreeNode);  
    //前序遍历  
    void preOrder(BTreeNode);  
    //后序遍历  
    void postOrder(BTreeNode);  
      
    //结点个数  
    int BTreeSize(BTreeNode);  
    //叶子结点  
    int BTreeLeaves(BTreeNode);  
  
    //树高  
    int BTreeHeight(BTreeNode);  
private:  
    BTreeNode root;  
};  
  
#endif  
BTreecpp(类的实现文件)
[cpp] view plain copy
#include <iostream>  
#include <stack>  
#include <queue>  
#include "BTreeh"  
using namespace std;  
  
//建立二叉树的算法  
BTreeNode BTree::createBTree()  
{  
    BTreeNode current=0;  
    int val=0;  
  
    cin>>val;  
  
    //-1的个数比数值的个数多1  
    if(val==-1)  
        return NULL;  
    else  
    {  
        current=new BTreeNode;  
        current->data=val;  
        current->lChild=createBTree();  
        current->rChild=createBTree();  
        return current;  
    }  
      
}  
  
//利用重载的方法  
void BTree::inOrder()  
{  
    inOrder(root);  
    cout<<endl;  
}  
  
//中序访问二叉树(递归)  
void BTree::inOrder(BTreeNode r)  
{  
    if(r!=0) //是if,而不是while  
    {  
        inOrder(r->lChild); //递归访问  
        cout<<r->data<<" ";  
        inOrder(r->rChild); //递归访问  
    }  
}  
  
//中序遍历(非递归)  
void BTree::NotReInOrder()  
{  
    stack<BTreeNode> s;  
  
    BTreeNode r=getRoot();  
  
    while(!sempty()||r!=0)  
    {  
        while(r!=0)  
        {  
            spush(r);  
            r=r->lChild;  
        }  
  
        if(!sempty())  
        {  
            r=stop();  
            spop();  
            cout<<r->data<<" ";  
            r=r->rChild;  
        }  
    }  
}  
  
//重载形式  
void BTree::preOrder()  
{  
    preOrder(root);  
    cout<<endl;  
}  
  
//前序递归访问二叉树(递归)  
void BTree::preOrder(BTreeNode r)  
{  
    if(r!=0) //是if,而不是while  
    {  
        cout<<r->data<<" ";  
        preOrder(r->lChild); //递归访问  
        preOrder(r->rChild); //递归访问  
    }  
}  
  
  
//前序遍历(非递归)  
void BTree::NotRePreOrder()  
{  
    stack<BTreeNode> s;  
    BTreeNode r=getRoot();  
    spush(r);  
  
    while(!sempty())  
    {  
        r=stop();  
        spop();  
  
        cout<<r->data<<" ";  
  
        if(r->rChild!=0)  
            spush(r->rChild);  
        if(r->lChild!=0)  
            spush(r->lChild);  
    }  
}  
  
  
//重载形式  
void BTree::postOrder()  
{  
    postOrder(root);  
    cout<<endl;  
}  
  
//后序遍历(递归)  
void BTree::postOrder(BTreeNode r)  
{  
    if(r!=0) //是if,而不是while  
    {  
        postOrder(r->lChild); //递归访问  
        postOrder(r->rChild); //递归访问  
        cout<<r->data<<" ";  
    }  
}  
  
  
//后序非递归访问要定义新的结构体类型  
struct Node  
{  
    BTreeNode tp;  
    bool flag;  
};  
  
//后序遍历(非递归)  
void BTree::NotRePostOrder()  
{  
    Node node; //定义Node结构体的一个结点  
    stack<Node> s;  
  
    BTreeNode r=getRoot();  
    while(!sempty()||r!=0)  
    {  
        while(r!=0)  
        {  
            nodetp=r;  
            nodeflag=0;  
            spush(node);  
            r=r->lChild;  
        }  
  
        if(!sempty())  
        {  
            node=stop();  
            spop();  
            r=nodetp; //将栈顶的BTreeNode部分赋给r  
            if(nodeflag==1)  
            {  
                cout<<r->data<<" ";  
                r=0; //表示已经访问了该结点  
            }  
            else  
            {  
                nodeflag=1;  
                spush(node);  
                r=r->rChild;  
            }  
        }  
    }  
}  
  
  
//重载形式  
int BTree::BTreeSize()  
{  
    return BTreeSize(root);  
}  
  
//求二叉树结点个数的函数  
int BTree::BTreeSize(BTreeNode r)  
{  
    //二叉树的结点个数为左右子树的高度之和再+1  
    if(r==0) return 0;   
    else  
        return 1+BTreeSize(r->lChild)+BTreeSize(r->rChild);  
}  
  
//重载形式  
int BTree::BTreeLeaves()  
{  
    return BTreeLeaves(root);  
}  
  
//求二叉树叶子结点个数的函数  
int BTree::BTreeLeaves(BTreeNode r)  
{  
    //当为空时,返回0;当找到叶子时返回1  
    if(r==0) return 0;   
    else  
        if(r->lChild==0&&r->rChild==0)  
            return 1;  
    else  
        return BTreeLeaves(r->lChild)+BTreeLeaves(r->rChild);  
}  
  
//重载形式  
int BTree::BTreeHeight()  
{  
    return BTreeHeight(root);  
}  
  
//求二叉树高度的函数  
int BTree::BTreeHeight(BTreeNode r)  
{  
    if(r==0) return 0;  
    else  
    {  
        //二叉树的高度为左右子树的最大者+1  
        int lHei=BTreeHeight(r->lChild);  
        int rHei=BTreeHeight(r->rChild);  
        return (lHei>rHei)  lHei+1:rHei+1;  
    }  
}  
  
  
  
//层次遍历求树高需要利用的新结构  
struct LayerBTreeNode  
{  
    BTreeNode ptr;  
    int height;  
};  
  
//层次遍历求高度  
int BTree::layerHeight()  
{  
    queue<LayerBTreeNode> que;  
    LayerBTreeNode temp,lTemp,rTemp; //牺牲空间来获得算法的清晰度  
  
    BTreeNode r=getRoot();  
  
    int hei=1;  
    tempptr=r;  
    tempheight=1;  
    quepush(temp); //先将根对应的LayerBTreeNode对象进队  
      
    //不为空时  
    while(!queempty())  
    {  
        //BTreeNode btreePtr=0;  
  
        temp=quefront(); //取出队首元素  
        quepop();  
          
        r=tempptr;  
  
        //用当前的高度跟取出的队首进行比较  
        if(hei<tempheight)  
                hei=tempheight;  
  
        if(r->lChild!=0||r->rChild!=0)  
        {  
            //如果它的左右子树不为空,则进队列  
            if(r->lChild!=0)  
            {  
                lTempptr=r->lChild;  
                lTempheight=tempheight+1; //在原来高度基础上加1,再入队列  
                quepush(lTemp);  
            }  
            if(r->rChild!=0)  
            {  
                rTempptr=r->rChild;  
                rTempheight=tempheight+1;  
                quepush(rTemp);  
            }  
  
        }  
    }  
    return hei;  
}

这是我前几天写的,看了下应该可以满足要求,由于测试还不够,不知道有没有bug。
第一点你自己改改,2、3都达到了,至于第四,不用说肯定是平衡了的二叉树相对查找效率要高一些,平衡,随机插入,打乱插入等 *** 作都是为了防止最差情况的线性树的出现。测试的话用rand()生成随机数外加timeh里的几个函数,配合使用下就出来了。
#include <stdioh>
#include <stdlibh>
// binary search tree
typedef struct BST
{
int data;
struct BST lhs;
struct BST rhs;
}BST;
// 插入一个节点
BST BSTInsertNode(BST root, int elem)
{
BST node;
node = (BST)malloc(sizeof(BST));
node->data = elem;
node->lhs = node->rhs = 0;

if(!root)
return node;

while(1)
{
if(node->data < root->data)
{
if(root->lhs)
root = root->lhs;
else
{
root->lhs = node;
return root->lhs;
}
}
else
{
if(root->rhs)
root = root->rhs;
else
{
root->rhs = node;
return root->rhs;
}
}
}
}
// 获得父节点
BST BSTGetParentNode(BST root, BST node)
{
if(root == node)
return 0;

if(root->lhs && node->data < root->lhs->data)
return BSTGetParentNode(root->lhs, node);
else if(root->rhs && node->data > root->rhs->data)
return BSTGetParentNode(root->rhs, node);
else
return root;
}
// 删除一个节点
BST BSTDeleteNode(BST root, BST node)
{
BST parent;
BST whichNode;
BST temp;

if(root != node)
{

parent = BSTGetParentNode(root, node);
whichNode = parent->lhs == node &parent->lhs : &parent->rhs;
}
else
whichNode = &root;
if(!node->lhs && !node->rhs)
whichNode = 0;
else if(!((node->lhs 1 : 0) ^ (node->rhs 1 : 0)))
whichNode = node->lhs node->lhs : node->rhs;
else
{
temp = node->rhs;
while(temp->lhs)
temp = temp->lhs;
temp->lhs = node->lhs;
whichNode = node->rhs;
}
free(node);
return whichNode;
}
// 删除树
void BSTDeleteTree(BST node)
{
if(node)
{
BSTDeleteTree(node->lhs);
BSTDeleteTree(node->rhs);
free(node);
}
}
// 建造树,从数组构造
BST BSTBuildTree(int beg, int end)
{
BST root;

if(beg >= end)
return 0;

root = (BST)malloc(sizeof(BST));
root->data = beg++;
root->lhs = root->rhs = 0;

while(beg != end)
BSTInsertNode(root, beg++);

return root;
}
// 查找节点
BST BSTSearchNode(BST root, int elem)
{
if(root)
{
if(elem < root->data)
return BSTSearchNode(root->lhs, elem);
else if(elem > root->data)
return BSTSearchNode(root->rhs, elem);
else
return root;
}
else
return 0;
}
// 获得最小值
BST BSTGetMinimumNode(BST root)
{
while(root->lhs)
root = root->lhs;
return root;
}
// 获得最大值
BST BSTGetMaximumNode(BST root)
{
while(root->rhs)
root = root->rhs;
return root;
}
// 前序遍历
void BSTPreorderTraverse(BST node)
{
if(node)
{
printf("%d ", node->data);
BSTPreorderTraverse(node->lhs);
BSTPreorderTraverse(node->rhs);
}
}
// 中序遍历
void BSTInorderTraverse(BST node)
{
if(node)
{
BSTInorderTraverse(node->lhs);
printf("%d ", node->data);
BSTInorderTraverse(node->rhs);
}
}
// 后序遍历
void BSTPostorderTraverse(BST node)
{
if(node)
{
BSTPostorderTraverse(node->lhs);
BSTPostorderTraverse(node->rhs);
printf("%d ", node->data);
}
}
// 获得前继值
BST BSTGetPredecessor(BST root, BST node)
{
BST predecessor;
BST rightCld;

if(node->lhs)
return BSTGetMaximumNode(node->lhs);

predecessor = rightCld = node;
while((predecessor = BSTGetParentNode(root, predecessor)))
if(predecessor->rhs == rightCld)
return predecessor;
else
rightCld = predecessor;
return 0;
}
// 获得后继值
BST BSTGetSuccessor(BST root, BST node)
{
BST successor;
BST leftCld;

if(node->rhs)
return BSTGetMinimumNode(node->rhs);

successor = leftCld = node;
while((successor = BSTGetParentNode(root, successor)))
if(successor->lhs == leftCld)
return successor;
else
leftCld = successor;
return 0;
}
// 获得树高
int BSTGetTreeHeight(BST root)
{
int l;
int r;
if(root)
{
l = BSTGetTreeHeight(root->lhs);
r = BSTGetTreeHeight(root->rhs);
return 1 + (l > r l : r);
}
else
return -1;
}
// 计算子节点数
int BSTGetSubtreeNodeNum(BST node)
{
if(node)
return BSTGetSubtreeNodeNum(node->lhs)
+ BSTGetSubtreeNodeNum(node->rhs)
+ 1;
else
return 0;
}
// 用于打乱数组,交换
inline void Swap(int a, int b)
{
int temp;
temp = a;
a = b;
b = temp;
}
// 用于打乱数组,qsort的比较用过程
inline int CMP(const void lhs, const void rhs)
{
return (const int)lhs - (const int)rhs;
}
// 数组有序
int IsOrdered(int beg, int end)
{
int attri;
int cmpVal;
if(beg >= end)
return 0;
if(end - beg <= 2)
return 1;

if(beg < (beg + 1))
attri = 1;
else
attri = 0;

cmpVal = beg++;
while(++beg != end)
{
if(attri)
{
if(cmpVal > beg)
return 0;
}else
{
if(cmpVal < beg)
return 0;
}
}
return 1;
}
// 高层次打乱数组
void HighlyUnorderArray(int beg, int end)
{

int mid = beg + (end - beg)/2;
int folk;
if(!IsOrdered(beg, end))
qsort(beg, end - beg, sizeof(int), CMP);

if((mid - beg) & 1)
Swap(beg++, mid);
folk = beg + 2;
while(folk < mid)
{
Swap(beg++, folk++);
Swap(beg++, folk++);
}

folk = mid + 2;
while(folk < end)
{
Swap(folk, folk - 1);
folk += 2;
}
}
// 中序遍历结果输出到数组
void BSTInorderWalkToArray(BST root, int p)
{
if(root)
{
BSTInorderWalkToArray(root->lhs, p);
p = root->data;
(p)++;
BSTInorderWalkToArray(root->rhs, p);
}
}
// 平衡树,返回平衡好的新树
BST BSTBalanceTree(BST root)
{
int size = BSTGetSubtreeNodeNum(root);
int a = (int)malloc(sizeof(int) size);
int end = a;
BST balancedTree;

BSTInorderWalkToArray(root, &end);
HighlyUnorderArray(a, end);
balancedTree = BSTBuildTree(a, end);
free(a);
return balancedTree;
}
int main()
{
int a[] = {5,6,3,7,9,8,1,0,4,2};
int c[] = {50,17,76,9,23,54,14,19,72,12,67};
BST bstTree = BSTBuildTree(a, a + sizeof(a)/sizeof(a[0]));

BSTPreorderTraverse(bstTree);
putchar('\n');
BSTInorderTraverse(bstTree);
putchar('\n');
BSTPostorderTraverse(bstTree);
printf("\n\n");

BST balancedTree = BSTBalanceTree(bstTree);
printf("%d %d\n", BSTGetTreeHeight(bstTree), BSTGetTreeHeight(balancedTree));
BSTDeleteTree(bstTree);
BSTDeleteTree(balancedTree);
}

#include<iostreamh>
#include <stdioh>
#include <stdlibh>
typedef struct node {
char data;
struct node lchild,rchild;//
}BiTNode,BiTree;
void CreatBiTree(BiTree &T)
{
char ch;
ch=getchar();
if (ch == ' ')
T = 0;
else {
T=(BiTNode)malloc(sizeof(BiTNode));
T->data=ch;//生成根节点
CreatBiTree(T->lchild);//构造左子树
CreatBiTree(T->rchild);//构造右子树
}
}
void preorder(BiTree T)//前序遍历
{
if (T!=NULL){
printf ("%c",T->data);
preorder(T->lchild);
preorder(T->rchild);
}
}
void inorder(BiTree T)//中序遍历
{
if (T!=NULL){
inorder(T->lchild);
printf ("%c",T->data);
inorder(T->rchild);
}
}
void postorder(BiTree T)//后序遍历
{
if (T!=NULL){
postorder(T->lchild);
postorder(T->rchild);
printf ("%c",T->data);
}
}
void main ()
{
cout<<"请输入要创建的二叉树包括空格:"<<endl ;
BiTree T;
CreatBiTree(T);//创建二叉树
cout<<"前序遍历的结果为:"<<endl;
preorder(T);
cout<<endl;
cout<<"中序遍历的结果为:"<<endl;
inorder(T);
cout<<endl;
cout<<"后序遍历的结果为:"<<endl;
postorder(T);
}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13140299.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-06-10
下一篇 2023-06-10

发表评论

登录后才能评论

评论列表(0条)

保存