数据结构-树

摘要:
树的存储结构1.父数组存储结构使用一维数组来存储树中的每个节点。数组元素是一个记录,包含两个字段:data和parent,分别表示数组中节点的数据值及其父节点的下标。图5-3树的父阵列存储结构位于父阵列中。查找节点的父节点或祖先很方便,但查找节点的子节点或兄弟节点很麻烦。您需要遍历整个阵列。

树的存储结构

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的位置存储的节点是根节点。

数据结构-树第1张

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

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

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

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

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

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

数据结构-树第2张

 

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

二叉树的存储结构

1、顺序存储结构

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

ABCDE F GHI 

 

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 != '

免责声明:内容来源于网络,仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Notification使用以及PendingIntent.getActivity() (转)DM7 备份还原、作业、DM 开发下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

数据结构:线性表(顺序表)

1、线性表 (1)定义 具有相同特性的数据元素的一个优先序列 第一个元素是起始结点,最后一个叫做终端结点 a结点的前一个结点叫做直接前驱,后一个结点叫做直接后继 元素可以是简单类型也可以是复杂类型(如:学生)的 2、线性表的顺序存储 (1)概念 把逻辑相邻的数据元素存储在物理上相邻的存储单元中的存储结构 第一个元素的存储位置称作起始地址或基地址 知道某一个...

Java小结

反射 java数据类型分为原始类型和引用类型。对于每种类型的对象java虚拟机会实例化不可变的java.lang.Class对象,它提供了在运行时检查对象属性的方法,这些属性包括它的成员和类型信息。 注:Class是泛型类,可以使用@SuppressWarnings("unchecked")忽略泛型或者使用Class<?>类型,?表示任意类...

一篇文章教会你创建vue项目和使用vue.js实现数据增删改查

【一、项目背景】 在管理员的一些后台页面里,数据列表中都会对这些数据进行增删改查的操作,例如管理员添加商品、修改商品价格、删除商品、查询商品,我们应该关注这些数据的操作和处理。 【二、项目目标】 主要有以下5个目标: 1、如何创建vue项目。 2、数据添加方法:获取到id和name在data上面获取,组织一个对象,把对象通过数组的相关方法,添加到当前dat...

进程隐藏的实现

通过Hook SSDT (System Service Dispatch Table) 隐藏进程1.原理介绍: Windows操作系统是一种分层的架构体系。应用层的程序是通过API来访问操作系统。而API又是通过ntdll里面的核心API来进行系统服务的查询。核心API通过对int 2e的切换,从用户模式转换到内核模式。2Eh中断的功能是通过NTOSKRN...

C++——双指针 (转)

转自: https://www.cnblogs.com/kyoner/p/11087755.html 左右指针示例: /** 二分查找 */ int find(vector<int> &values, int left, int right, int target) { while(left<...

优化查找和排序

优化查找和排序 C++程序会进行许多查找操作。从编程语言的编译器到浏览器,从控制链表到数据库,许多反复进行的程序活动都会在某个内部的循环底层进行查找操作。就经验而言,查找操作通常会出现在热点函数的列表中。因此我们需要特别注意查找操作的效率。 使用std::map和std::string的键值对表 使用std::map创建表是一个例子,它向我们展示了C++标...