zoukankan      html  css  js  c++  java
  • 二叉树的二叉链表存储

    节点形态:


    实现:

    /******************************************
    二叉树的二叉链表存储
    by Rowandjj
    2014/5/18
    ******************************************/
    #include<IOSTREAM>
    using namespace std;
    
    /*二叉树的二叉链表存储表示*/
    typedef int TElemType;
    typedef struct _TREENODE_
    {
        TElemType data;//值
        struct _TREENODE_ *lChild;//左孩子
        struct _TREENODE_ *rChild;//右孩子
    }TreeNode,*pTreeNode,**ppTreeNode;
    /*--------------辅助队列-------------------*/
    typedef struct _QUEUE_NODE_//队列节点定义
    {
        pTreeNode data;//数据域(存储二叉树节点)
        struct _QUEUE_NODE_ *pNext;//指针域
    }QueueNode,*pQueueNode;
    
    typedef struct _QUEUE_
    {
        pQueueNode pHead;//队列头指针
        pQueueNode pTail;//队列尾指针
        int nodeCount;//队列节点个数
    }Queue,*pQueue;
    /*队列基本操作*/
    void InitQueue(pQueue pQueueTemp);
    void EnQueue(pQueue pQueueTemp,pTreeNode pTreeNodeTemp);
    bool DeQueue(pQueue pQueueTemp,ppTreeNode ppTreeNodeTemp);
    bool IsQueueEmpty(Queue QueueTemp);
    void DestroyQueue(pQueue pQueueTemp);
    //-----------------------------------------------------------------------
    /*二叉树基本操作*/
    void InitTree(ppTreeNode ppTreeNodeTemp);
    void CreateTree(ppTreeNode ppTreeNodeTemp);
    void DestroyTree(ppTreeNode ppTreeNodeTemp);
    bool IsEmpty(pTreeNode pTreeNodeTemp);
    void PreTravel(pTreeNode pTreeNodeTemp);//先序遍历
    void MidTravel(pTreeNode pTreeNodeTemp);//中序遍历
    void PosTravel(pTreeNode pTreeNodeTemp);//后序遍历
    void LevelTravel(pTreeNode pTreeNodeTemp);//层次遍历
    int GetDepth(pTreeNode pTreeNodeTemp);//求二叉树深度
    void FindNode(pTreeNode pTreeNodeTemp,int data,ppTreeNode pFind);//查找节点。假设成功则用pFind返回
    void Assign(pTreeNode pTreeNodeTemp,TElemType data);//赋值
    void GetRoot(pTreeNode pTreeNodeTemp,void (*print)(TElemType));//获取根节点
    pTreeNode GetParent(pTreeNode pTreeNodeTemp,TElemType data);//获取父节点
    pTreeNode GetPoint(pTreeNode pTreeNodeTemp,TElemType data);//返回指向元素值为data的节点的指针
    pTreeNode GetLeftChild(pTreeNode pTreeNodeTemp,TElemType data);//获取元素值为data的左孩子
    pTreeNode GetRightChild(pTreeNode pTreeNodeTemp,TElemType data);//获取元素值为data的右孩子
    pTreeNode GetLeftSibling(pTreeNode pTreeNodeTemp,TElemType data);//获取元素值为data的左兄弟
    pTreeNode GetRightSibling(pTreeNode pTreeNodeTemp,TElemType data);//获取元素值为data的右兄弟
    bool InsertChild(pTreeNode pTreeNodeTemp,int flag,pTreeNode pTreeNew);//将pTreeNew总体插到pTreeNodeTemp中,约定pTreeNew右子树为空,依据标志位flag的0或者1来推断插入位置
    bool DeleteChild(pTreeNode pTreeNodeTemp,int flag);//flag==0,删除左子树。否则删除右子树
    
    void printNode(TElemType e);
    
    //-------------队列基本操作实现----------------------------------
    void InitQueue(pQueue pQueueTemp)
    {
        pQueueTemp->pHead = pQueueTemp->pTail = (pQueueNode)malloc(sizeof(QueueNode));
        if(pQueueTemp->pHead == NULL)
        {
            return;
        }
        pQueueTemp->pHead->pNext = NULL;
        pQueueTemp->nodeCount = 0;
    }
    
    void EnQueue(pQueue pQueueTemp,pTreeNode pTreeNodeTemp)
    {
        pQueueNode pNodeNew = (pQueueNode)malloc(sizeof(QueueNode));
        if(pNodeNew != NULL)
        {
            pNodeNew->data = pTreeNodeTemp;
            pNodeNew->pNext = NULL;
    
            pQueueTemp->pTail->pNext = pNodeNew;
            pQueueTemp->pTail = pNodeNew;
            
            pQueueTemp->nodeCount++;
        }
        
    }
    bool DeQueue(pQueue pQueueTemp,ppTreeNode ppTreeNodeTemp)
    {
        if(IsQueueEmpty(*pQueueTemp))
        {
            return false;
        }
        pQueueNode pDel = pQueueTemp->pHead->pNext;
        pQueueTemp->pHead->pNext = pDel->pNext;
        *ppTreeNodeTemp = pDel->data;    
        pQueueTemp->nodeCount--;
        if(pQueueTemp->pTail == pDel)
        {
            pQueueTemp->pTail = pQueueTemp->pHead;
        }
    
        free(pDel);
        return true;
    }
    bool IsQueueEmpty(Queue QueueTemp)
    {
        return (QueueTemp.nodeCount > 0) ?

    false : true; } void DestroyQueue(pQueue pQueueTemp) { if(pQueueTemp != NULL) { pQueueNode pTemp = pQueueTemp->pHead->pNext; while(pTemp!=NULL) { pQueueTemp->pHead->pNext = pTemp->pNext; free(pTemp); pTemp = pQueueTemp->pHead->pNext; } free(pQueueTemp->pHead); pQueueTemp->pHead = pQueueTemp->pTail = NULL; pQueueTemp->nodeCount = 0; } } //------------------二叉树操作实现-------------------------------- void CreateTree(ppTreeNode ppTreeNodeTemp) { int a = 0; cin>>a; if(a == -1) { return; } else { *ppTreeNodeTemp = (pTreeNode)malloc(sizeof(TreeNode)); if(*ppTreeNodeTemp != NULL) { (*ppTreeNodeTemp)->data = a; (*ppTreeNodeTemp)->lChild = NULL; (*ppTreeNodeTemp)->rChild = NULL; CreateTree(&(*ppTreeNodeTemp)->lChild); CreateTree(&(*ppTreeNodeTemp)->rChild); } } } void DestroyTree(ppTreeNode ppTreeNodeTemp) { if(*ppTreeNodeTemp == NULL) { return; } if((*ppTreeNodeTemp)->lChild != NULL) { DestroyTree(&(*ppTreeNodeTemp)->lChild); } if((*ppTreeNodeTemp)->rChild != NULL) { DestroyTree(&(*ppTreeNodeTemp)->rChild); } free(*ppTreeNodeTemp); *ppTreeNodeTemp = NULL; } bool IsEmpty(pTreeNode pTreeNodeTemp) { return (pTreeNodeTemp == NULL); } void PreTravel(pTreeNode pTreeNodeTemp)//先序遍历 { if(pTreeNodeTemp != NULL) { cout<<pTreeNodeTemp->data<<" ";//先訪问根节点 PreTravel(pTreeNodeTemp->lChild);//再先序遍历左子树 PreTravel(pTreeNodeTemp->rChild);//最后先序遍历右子树 } } void InitTree(ppTreeNode ppTreeNodeTemp) { *ppTreeNodeTemp = NULL; } void MidTravel(pTreeNode pTreeNodeTemp)//中序遍历 { if(pTreeNodeTemp != NULL) { MidTravel(pTreeNodeTemp->lChild);//先左子树 cout<<pTreeNodeTemp->data<<" ";//再根节点 MidTravel(pTreeNodeTemp->rChild);//最后右子树 } } void PosTravel(pTreeNode pTreeNodeTemp)//后序遍历 { if(pTreeNodeTemp != NULL) { PosTravel(pTreeNodeTemp->lChild);//先左子树 PosTravel(pTreeNodeTemp->rChild);//再右子树 cout<<pTreeNodeTemp->data<<" ";//最后根节点 } } int GetDepth(pTreeNode pTreeNodeTemp) { int i = 0; int j = 0; if(pTreeNodeTemp == NULL) { return 0; } else { if(pTreeNodeTemp->lChild != NULL) { i = GetDepth(pTreeNodeTemp->lChild); }else { i = 0; } if(pTreeNodeTemp->rChild != NULL) { j = GetDepth(pTreeNodeTemp->rChild); }else { j = 0; } return (i>j)?i+1:j+1; } } void FindNode(pTreeNode pTreeNodeTemp,int data,ppTreeNode pFind) { if(pTreeNodeTemp == NULL) { return; } if(pTreeNodeTemp->data == data) { *pFind = pTreeNodeTemp; } else { FindNode(pTreeNodeTemp->lChild,data,pFind); FindNode(pTreeNodeTemp->rChild,data,pFind); } } void Assign(pTreeNode pTreeNodeTemp,int data) { if(pTreeNodeTemp->data != NULL) { pTreeNodeTemp->data = data; } } void GetRoot(pTreeNode pTreeNodeTemp,void (*print)(TElemType)) { if(pTreeNodeTemp != NULL) { print(pTreeNodeTemp->data); }else { print(-1); } } pTreeNode GetParent(pTreeNode pTreeNodeTemp,TElemType data) { Queue qTemp; pTreeNode pTreeNodeNew; if(pTreeNodeTemp != NULL) { InitQueue(&qTemp); EnQueue(&qTemp,pTreeNodeTemp);//先入队根节点 while(!IsQueueEmpty(qTemp)) { DeQueue(&qTemp,&pTreeNodeNew); if(pTreeNodeNew->lChild&&pTreeNodeNew->lChild->data==data || pTreeNodeNew->rChild&&pTreeNodeNew->rChild->data==data) { return pTreeNodeNew; }else { if(pTreeNodeNew->lChild) { EnQueue(&qTemp,pTreeNodeNew->lChild); } if(pTreeNodeNew->rChild) { EnQueue(&qTemp,pTreeNodeNew->rChild); } } } } DestroyQueue(&qTemp); return NULL; } pTreeNode GetPoint(pTreeNode pTreeNodeTemp,TElemType data) { Queue qTemp; pTreeNode pTreeNodeNew; if(pTreeNodeTemp != NULL) { InitQueue(&qTemp); EnQueue(&qTemp,pTreeNodeTemp); while(!IsQueueEmpty(qTemp)) { DeQueue(&qTemp,&pTreeNodeNew); if(pTreeNodeNew->data == data) { return pTreeNodeNew; } else { if(pTreeNodeNew->lChild) { EnQueue(&qTemp,pTreeNodeNew->lChild); } if(pTreeNodeNew->rChild) { EnQueue(&qTemp,pTreeNodeNew->rChild); } } } } DestroyQueue(&qTemp); return NULL; } pTreeNode GetLeftChild(pTreeNode pTreeNodeTemp,TElemType data) { if(pTreeNodeTemp != NULL) { pTreeNode pParentNode = GetPoint(pTreeNodeTemp,data); if(pParentNode && pParentNode->lChild) { return pParentNode->lChild; } } return NULL; } pTreeNode GetRightChild(pTreeNode pTreeNodeTemp,TElemType data) { if(pTreeNodeTemp != NULL) { pTreeNode pParentNode = GetPoint(pTreeNodeTemp,data); if(pParentNode && pParentNode->rChild) { return pParentNode->rChild; } } return NULL; } pTreeNode GetLeftSibling(pTreeNode pTreeNodeTemp,TElemType data) { if(pTreeNodeTemp != NULL) { pTreeNode pParent = GetParent(pTreeNodeTemp,data); if(pParent && pParent->lChild && pParent->rChild->data == data) { return pParent->lChild; } } return NULL; } pTreeNode GetRightSibling(pTreeNode pTreeNodeTemp,TElemType data) { if(pTreeNodeTemp != NULL) { pTreeNode pParent = GetParent(pTreeNodeTemp,data); if(pParent && pParent->rChild && pParent->lChild->data == data) { return pParent->rChild; } } return NULL; } void LevelTravel(pTreeNode pTreeNodeTemp) { Queue qTemp; pTreeNode pTreeNodeTravel; if(pTreeNodeTemp != NULL) { InitQueue(&qTemp); EnQueue(&qTemp,pTreeNodeTemp); while(!IsQueueEmpty(qTemp)) { DeQueue(&qTemp,&pTreeNodeTravel); cout<<pTreeNodeTravel->data<<" "; if(pTreeNodeTravel->lChild) { EnQueue(&qTemp,pTreeNodeTravel->lChild); } if(pTreeNodeTravel->rChild) { EnQueue(&qTemp,pTreeNodeTravel->rChild); } } } DestroyQueue(&qTemp); } bool InsertChild(pTreeNode pTreeNodeTemp,int flag,pTreeNode pTreeNew) { if(pTreeNodeTemp != NULL && pTreeNew != NULL && pTreeNew->rChild == NULL) { if(flag == 0)//左插 { pTreeNew->rChild = pTreeNodeTemp->lChild; pTreeNodeTemp->lChild = pTreeNew; }else//flag == 1。右插 { pTreeNew->rChild = pTreeNodeTemp->rChild; pTreeNodeTemp->rChild = pTreeNew; } return true; } return false; } bool DeleteChild(pTreeNode pTreeNodeTemp,int flag) { if(pTreeNodeTemp != NULL) { if(flag == 0)//删除左子树 { DestroyTree(&pTreeNodeTemp->lChild); }else//删除右子树 { DestroyTree(&pTreeNodeTemp->rChild); } return true; } return false; } void printNode(TElemType e) { cout<<"root = "; cout<<e<<" "; }



  • 相关阅读:
    C# 杂活
    常用 SQL Server 规范集锦
    C# 文件操作
    使用Git 本地代码提交到 GitHub
    Numpy的小总结
    C#最佳工具集合:IDE、分析、自动化工具等
    Web服务器、应用服务器、Web容器、反向代理服务器区别与联系
    Platt SMO 和遗传算法优化 SVM
    Pycharm配置(三)
    Pycharm配置(二)
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5342286.html
Copyright © 2011-2022 走看看