zoukankan      html  css  js  c++  java
  • 数据结构-树

    树的存储结构

    1.双亲数组存储结构

    用一个一维数组存储树中的各个节点,数组元素是一个记录,包含dataparent两个字段,分别表示节点的数据值和其双亲在数组中的下标。其类型定义如下:

    typedef struct
    {  
        ElemType data;
        int parent;
    } ParType[MaxSize];

    在这个一维数组中,树中节点可按任意顺序存放。

    例如,图5-1中给出的树,它的双亲数组存储表示如图5-3所示。其中,规定下标为0的位置存储的节点是根节点。

    位置

    0

    1

    2

    3

    4

    5

    6

    7

    空闲

    Maxsize-1

    data

    A

    B

    C

    D

    E

    F

    G

    H

    parent

    -1

    0

    0

    0

    2

    2

    3

    4

                                          图5-3  树的双亲数组存储结构

    在双亲数组中,找某个节点的双亲或祖先是很方便的,但要找某个节点的孩子或兄弟则较麻烦,需要遍历整个数组。

    2.孩子链表存储结构

    把每个节点的孩子节点排列起来,构成一个单链表,称为孩子链表。n个节点的树有n个这样的孩子链表,其中,树叶的孩子链表为空表。为便于查找,n个链表的表头指针放在一个顺序表中。这个顺序表中的每个元素有两个字段:一个存放节点的值;另一个存放第一个孩子的地址。孩子链表中的每个节点也有两个字段:指示孩子节点的值存放的位置;另一个存放下一个孩子的地址。在顺序表中,各元素可以按任意顺序存放。在每个孩子链表中,各节点也可以按任意顺序链接。

    单链表中每个节点的类型定义如下:

    typedef struct node1
    {  
        int adjvex;                             /*该节点值在顺序表中的位置*/
        struct node1 *next;
    } ChildType;

    顺序表的类型定义如下:

    typedef struct
    {  
        ElemType data;
        ChildType *children;
    } Child[MaxSize];

    5-4是图5-1所示树的孩子链表存储结构。其中,规定表头中下标为0的位置存储的节点是根节点。

    5-4  树的孩子链表存储结构

    显然,在孩子链表中,找某个节点的孩子很容易,但找节点的双亲则较困难。

    3.孩子兄弟链表存储结构

    孩子兄弟链表存储结构是一种二叉链表,链表中每个节点包含两个指针,分别指向对应节点的第一个孩子和下一个兄弟。每个节点的类型定义如下:

    typedef struct node2
    {  
        ElemType data;
        struct node2 *child,*brother;
    } CBNodeType;

    5-5是图5-1所示树的孩子兄弟链表存储结构,其中,T1指针指向树的根节点。

     

    出自:http://www.qacn.net/viewchapter.aspx?topicid=147&chapterid=2771

    二叉树的存储结构

    1、顺序存储结构

      A(B(D,E(G,H)),C(,F(I)))存储为

    A B C D E   F   G H I  

     

    2、链式存储结构

      利用左右孩子指针。

    二叉树的基本运算及四种遍历方式

     

    #include <iostream>
    #include <cstdlib>
    using namespace std;
    
    #define MaxSize 100
    
    typedef struct Node{
        char data;
        struct Node *lChild, *rChild;
    }BTNode;
    
    //先序遍历
    void PreOrder(BTNode *bt){
        if(bt != NULL){
            cout << bt->data << " ";
            PreOrder(bt->lChild);
            PreOrder(bt->rChild);
        }
    
    }
    
    //中序遍历
    void InOrder(BTNode *bt){
        if(bt != NULL){
            InOrder(bt->lChild);
            cout << bt->data << " ";
            InOrder(bt->rChild);
        }
    }
    
    //后序遍历
    void LastOrder(BTNode *bt){
        if(bt != NULL){
            LastOrder(bt->lChild);
            LastOrder(bt->rChild);
            cout << bt->data << " ";
        }
    }
    
    //层次遍历
    //先是根节点进入队列,紧接着是其左右孩子,在用左右孩子循环。
    void LeverOrder(BTNode *bt){
        BTNode *p;
        BTNode *qu[MaxSize];
        int front,rear;
        front = rear = -1;
        rear++;
        qu[rear] = bt;
        while(front != rear){
            front = (front+1)%MaxSize;
            p = qu[front];
            cout << p->data << " ";
            if(p->lChild != NULL){
                rear = (rear+1)%MaxSize;
                qu[rear] = p->lChild;
            }
            if(p->rChild != NULL){
                rear = (rear+1)%MaxSize;
                qu[rear] = p->rChild;
            }
        }
    }
    
    //以括号表示法输出二叉树
    void DispBTree(BTNode *bt)
    {
        if(bt!=NULL)
        {
            cout << bt->data;
            if(bt->lChild!=NULL || bt->rChild!=NULL)
            {
                cout<<"(";
                DispBTree(bt->lChild);                      /*递归处理左子树*/
                if(bt->rChild!=NULL)
    cout << ",";
                DispBTree(bt->rChild);                      /*递归处理右子树*/
                cout<<")";
            }
        }
    }
    
    //叶子节点数
    int LeafCount(BTNode *bt){
        int l,r;
        if(bt == NULL){
            return 0;
        }
        else{
            if(bt->lChild == NULL && bt->rChild == NULL){
                return 1;
            }
            else{
                l = LeafCount(bt->lChild);
                r = LeafCount(bt->rChild);
                return l+r;
            }
        }
    }
    
    //二叉树节点个数
    int NodeCount(BTNode *bt){
        int l,r;
        if(bt == NULL){
            return 0;
        }
        else{
            l = NodeCount(bt->lChild);
            r = NodeCount(bt->rChild);
            return (l+r+1);
        }
    }
    
    //二叉树高度运算
    int BTHeight(BTNode *bt){
        int l,r;
        if(bt == NULL){
            return 0;
        }
        else{
            char d = bt->data;
            //cout << d << endl;
            l = BTHeight(bt->lChild);
            //cout << "l:  " << l << endl;
            r = BTHeight(bt->rChild);
            //cout << "r:  " << r << endl;
            //cout << (l>r ? (l+1):(r+1)) << endl;
            return l > r ? (l+1):(r+1);
        }
    }
    
    //根据二叉树的括号表示法str建立二叉链
    void CreateBTree(BTNode* &bt,char* str){
        BTNode* st[MaxSize];
        BTNode* p = NULL;
        bt = NULL;
        int k,top=-1,j=0;
        char ch = str[j];
        while(ch != ''){
            switch(ch){
                case '(':
                    top++;
                    st[top] = p;
                    k = 1;
                    break;
                case ')':
                    top--;
                    break;
                case ',':
                    k = 2;
                    break;
                default:
                    p = new BTNode;
                    //p = (BTNode *)malloc(sizeof(BTNode));
                    p->data = ch;
                    p->lChild = p->rChild = NULL;
                    if(bt == NULL){
                        bt = p;
                    }
                    else{
                        switch(k){
                            case 1:
                                st[top]->lChild = p;
                                break;
                            case 2:
                                st[top]->rChild = p;
                                break;
                        }
                    }
            }
            j++;
            ch = str[j];
        }
    }
    
    int main()
    {
        BTNode *bt;
        CreateBTree(bt,"A(B(D,E(G,H)),C(,F(I)))");
        cout << "二叉树:";
        DispBTree(bt);
        int i = BTHeight(bt);
        int j = NodeCount(bt);
        int k = LeafCount(bt);
    
        //遍历
        cout << endl;
        cout << "先序遍历:";
        PreOrder(bt);
        cout << endl;
        cout << "中序遍历:";
        InOrder(bt);
        cout << endl;
        cout << "后序遍历:";
        LastOrder(bt);
        cout << endl;
        cout << "层次遍历:";
        LeverOrder(bt);
    
        return 0;
    }

     

     

     

  • 相关阅读:
    WSS 扩展文件夹的属性如何给文件夹添加扩展字段
    SharePoint 打开文档附件不弹出提示框
    SharePoint2010 安装时报“未能启动数据库服务 MSSQL$Sharepoint"解决办法
    常见问题
    sharepoint 关于pdf格式在线打开
    ASP.NET 2.0 连接Sql Server 2005报错 [DBNETLIB][ConnectionOpen (Invalid Instance()).]无效的连线。
    <转>SQL Server 2008 R2十大新特性解析
    windows查看端口占用情况
    SQL Server适用脚本收集一
    信息系统中用户的域AD认证功能
  • 原文地址:https://www.cnblogs.com/wn19910213/p/3654169.html
Copyright © 2011-2022 走看看