精华内容
下载资源
问答
  • 对于完全二叉树,如果将其中的元素按层次遍历顺序存放入一个一维数组中:设数组大小为n(节点数为n),节点标号(key)为数组下标i,即0,1,2,3,4,,,那么:1.完全二叉树的高度为: ceil(log2(n+1))2.i = 0: 根节点,...
    对于完全二叉树,如果将其中的元素按层次遍历顺序存放入一个一维数组中:
    设数组大小为n(节点数为n),节点标号(key)为数组下标i,即0,1,2,3,4,,,
    那么:
    1.完全二叉树的高度为: ceil(log2(n+1))
    2.i = 0: 根节点,root,无父节点。
    i >= 1: 父节点为 floor((i-1)/2);
    3.若2*i<n-1: 节点i的左子女为 2*i + 1
    若2*i<n-2: 节点i的右子女为 2*i + 2
    4.若节点编号 i 为奇数,i != 1, 它处于右兄弟位置,则它的左兄弟为节点 i-1
    5.若节点编号 i 为偶数,i != 1, 它处于左兄弟位置,则它的右兄弟为节点 i+1
    6.节点i所在的层次为 floor(log2(i-1))+1;

    Java实现:
     1  
     2 /**
     3  * Created by XuTao on 2018/11/18 11:54
     4  * 完全二叉树:
     5  * 用数组按层次序排列
     6  *
     7  */
     8 
     9  
    10 public class BT {
    11     private Node root;
    12     private int [] data;
    13     public BT_ArrayStore(int []a){
    14         this.data =a;
    15         this.root = create(a,0);
    16     }
    17 
    18     public int getHeight(){
    19         return (int)Math.floor(Math.log(data.length)/Math.log(2))+1;  //这里涉及到Math,易错
    20     }
    21     public int getFather(int i){
    22         if (i==0) return 0;
    23         return (int)(Math.floor((i-1)/2));
    24     }
    25 
    26     public int getLeft(int i){
    27         return 2*i+1;
    28     }
    29     public int getRight(int i){
    30         return 2*i+2;
    31     }
    32 
    33     public int getBrother(int i){
    34         if (i%2==0)
    35             return i-1;
    36         else return i+1;
    37     }
    38     public int  getLevel(int i){
    39         return (int)(Math.floor(Math.log(i-1)/Math.log(2)))+1;
    40     }
    41 
    42 
    43     private Node create(int[] arr, int index) {
    44         if (index >= arr.length)       // 可以不需要,但是所有的值必须要写满,任一个#都要写,不然会越界
    45             return null;
    46         else if (String.valueOf(arr[index]).equals("#")||String.valueOf(arr[index]).equals("*")) {
    47             return null;
    48         } else {
    49             Node node = new Node(arr[index]);
    50             node.left = create(arr, 2 * index + 1);
    51             node.right  = create(arr, 2 * index + 2);
    52             return node;
    53         }
    54     }
    55 
    56     class Node{
    57         private Node left;
    58         private Node right;
    59         private int data;
    60         public Node(int data){
    61             this.data = data;
    62         }
    63     }
    64 
    65     public static void main(String[] args) {
    66         int []a = new int[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
    67         BT bt = new BT (a);
    68         System.out.println(bt.getHeight());
    69         System.out.println(bt.getFather(14));
    70         System.out.println(bt.getLeft(4));
    71         System.out.println(bt.getRight(5));
    72         System.out.println(bt.getBrother(5));
    73         System.out.println(bt.getLevel(5));
    74 
    75     }
    76 }

    如果是1---n, 那么上述公式每个i加1即可。

     

    转载于:https://www.cnblogs.com/XT-xutao/p/9977769.html

    展开全文
  • // Study_Program.cpp : Defines the entry point for the console application. // #include "...//完全二叉树的最大节点数量s = (2^n)-1,n = 树的高度 //对于一个数组结构的tree,要先...
    // Study_Program.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <math.h>
    #define SIZE 20
    //求深度
    //完全二叉树的最大节点数量s = (2^n)-1,n = 树的高度
    //对于一个数组结构的tree,要先求tree的深度n,求最大指数2^n-1=size = 2^n = size+1 。所以 n =  log2 (size+1)。n向上取整
    int getHeight2(int size){
    	return (int)ceil(log10((double)size+1)/log10(2.0));
    }
    
    //求左孩子
    int *getLchild(int arr[],int index){
    	if(index*2 > SIZE){
    		//printf("this node is not lift child");
    		return NULL;
    	}
    	return &arr[index*2];
    }
    
    //求右孩子
    int *getRchild(int arr[],int index){
    	if(index*2+1 > SIZE){
    		//  printf("this node is not right child");
    		return NULL;
    	}
    	return &arr[index*2+1];
    }
    
    //求双亲
    int *getParent(int arr[],int index){
    	if(index < 2 || index > SIZE){
    		printf("this node is not parent");
    		return NULL;
    	}
    	return &arr[index/2];
    }
    
    //先序遍历
    void perorder2(int *arr, int in
    展开全文
  • 堆–完全二叉树数组实现 堆的定义 堆是计算机科学中一类特殊的数据结构的统称,堆通常可以看作是一棵完全二叉树数组对象。 堆的特性 1.它是完全二叉树,除了树的最后一层结点不需要是满的,其它的每一层从左到右...

    堆–完全二叉树的数组实现

    堆的定义

    堆是计算机科学中一类特殊的数据结构的统称,堆通常可以看作是一棵完全二叉树的数组对象。

    堆的特性

    1.它是完全二叉树,除了树的最后一层结点不需要是满的,其它的每一层从左到右都是满的,如果最后一层结点不是满的,那么要求左满右不满。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mgn8z2hn-1627916359968)(images/image28.png)]

    2.它通常用数组来实现。

    ​ 具体方法就是将二叉树的结点按照层级顺序放入数组中,根结点在位置1,它的子结点在位置2和3,而子结点的子结点则分别在位置4,5,6和7,以此类推。

    A,E,G,H,I,N,O,P,R,S,T
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eKgpolXJ-1627916359974)(images/image29.png)]

    如果一个结点的位置为k,则它的父结点的位置为[k/2],而它的两个子结点的位置则分别为2k和2k+1。这样,在不使用指针的情况下,我们也可以通过计算数组的索引在树中上下移动:从a[k]向上一层,就令k等于k/2,向下一层就令k等于2k或2k+1

    3.每个结点都大于等于它的两个子结点。这里要注意堆中仅仅规定了每个结点大于等于它的两个子结点,但这两个子结点的顺序并没有做规定,跟二叉查找树是有区别的。

    堆的API设计

    类名Heap
    构造方法Heap(int capacity):创建容量为capacity的Heap对象
    成员方法1.private boolean less(int i,int j):判断堆中索引i处的元素是否小于索引j处的元素
    2.private void exch(int i,int j):交换堆中i索引和j索引处的值
    3.public T delMax():删除堆中最大的元素,并返回这个最大元素
    4.public void insert(T t):往堆中插入一个元素
    5.private void swim(int k):使用上浮算法,使索引k处的元素能在堆中处于一个正确的位置
    6.private void sink(int k):使用下沉算法,使索引k处的元素能在堆中处于一个正确的位置
    成员变量1.private T[] imtes : 用来存储元素的数组
    2.private int N:记录堆中元素的个数

    堆的实现

    insert插入方法的实现

    ​ 堆是用数组完成数据元素的存储的,由于数组的底层是一串连续的内存地址,所以我们要往堆中插入数据,我们只能往数组中从索引0处开始,依次往后存放数据,但是堆中对元素的顺序是有要求的,每一个结点的数据要大于等于它的两个子结点的数据,所以每次插入一个元素,都会使得堆中的数据顺序变乱,这个时候我们就需要通过一些方法让刚才插入的这个数据放入到合适的位置。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XvoUTT7d-1627916359976)(images/image30.png)]

    ​ 所以,如果往堆中新插入元素,我们只需要不断的比较新结点a[k]和它的父结点a[k/2]的大小,然后根据结果完成数据元素的交换,就可以完成堆的有序调整

    delMax删除最大元素方法的实现

    ​ 由堆的特性我们可以知道,索引1处的元素,也就是根结点就是最大的元素,当我们把根结点的元素删除后,需要有一个新的根结点出现,这时我们可以暂时把堆中最后一个元素放到索引1处,充当根结点,但是它有可能不满足堆的有序性需求,这个时候我们就需要通过一些方法,让这个新的根结点放入到合适的位置。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7dfty3Ib-1627916359979)(images/image31.png)]

    ​ 所以,当删除掉最大元素后,只需要将最后一个元素放到索引1处,并不断的拿着当前结点a[k]与它的子结点a[2k]和a[2k+1]中的较大者交换位置,即可完成堆的有序调整。

    堆的代码实现
    /**
     * 堆--完全二叉树的数组实现
     * A,E,G,H,I,N,O,P,R,S,T(大->小)
     */
    public class Heap<T extends Comparable<T>> {
        // 存储堆中的元素
        private T[] items;
        // 记录堆中元素的个数
        private int N;
    
        public Heap(int capacity) {
            items = (T[]) new Comparable[capacity + 1];
            N = 0;
        }
    
        // 往堆中插入一个元素
        public void insert(T t) {
            items[++N] = t;
            swim(N);
        }
    
        // 删除堆中最大的元素,并返回这个最大元素
        public T delMax() {
            // 记录最大的元素
            T max = items[1];
            // 删除最大的元素(让完全二叉树中的最右侧的元素变为临时根结点)
            exch(1, N);
            // 最大元素的位置变更为N索引的位置,删除N索引位置的元素
            items[N] = null;
            // 元素个数-1
            N--;
            // 保持队中的规则,调用下沉算法
            sink(1);
            return max;
        }
    
        // 使用上浮算法,使索引k处的元素能在堆中处于一个正确的位置
        private void swim(int k) {
            // 通过循环,不断地比较当前结点的值与父结点的值,如果当前结点的值>其父结点的值,交换两处的值
            while (k > 1) {
                if (less(k / 2, k)) {
                    exch(k / 2, k);
                }
                k /= 2;
            }
        }
    
        // 使用下沉算法,使索引k处的元素能在堆中处于一个正确的位置
        private void sink(int k) {
            // 通过循环,不断的比较当前结点的值与其两个子结点中最大的结点的值,如果当前结点的值>其最大子结点的值,交换两处的值
            while (2 * k <= N) {
                // 获取当前结点的两个子结点中最大的值,记录索引
                int max;
                if ((2 * k + 1) <= N) { // 存在右子结点
                    if (less(2 * k + 1, 2 * k)) {
                        max = 2 * k;
                    } else {
                        max = 2 * k + 1;
                    }
                } else { // 不存在右子结点
                    max = 2 * k;
                }
                // 比较当前结点和最大子结点,如果大于结束循环
                if (!less(k, max)) {
                    break;
                }
                // 如果小于,交换两位置的值
                exch(k, max);
                k = max;
            }
        }
    
        // 判断堆中索引i处的元素是否小于索引j处的元素
        private boolean less(int i, int j) {
            return items[i].compareTo(items[j]) < 0;
        }
    
        // 交换堆中i索引和j索引处的值
        private void exch(int i, int j) {
            T tmp = items[i];
            items[i] = items[j];
            items[j] = tmp;
        }
    }
    
    展开全文
  • 此代码利用数组实现的完全二叉树插入,删除,以及遍历。 在私有数据成员包括了size(元素个数),capacity(容量),当size>=capacity时需要开辟空间,而开辟空间的大小为: capacity = capacity+((capa

    1、备用知识
    个人认为利用数组实现二叉树更为简单,二叉树的增、删、改、查也更为简单。在利用数组实现中不需要专门定义一个结构体去声明左孩子与右孩子,需要注意的是数组中的左右孩子是这样定义的:
    设父节点的下标为N,则左孩子的下标为:2N+1,右孩子的下标为2N+2。
    此代码利用数组实现的完全二叉树插入,删除,以及遍历。
    在私有数据成员包括了size(元素个数),capacity(容量),当size>=capacity时需要开辟空间,而开辟空间的大小为:
    capacity = capacity+((capacity/2)>0?capacity/2:1);设置成这样主要是为了防止capacity为1或0 的情况。
    具体代码如下,程序中有详细的说明:
    .cpp程序

    #include "stdafx.h"
    #include"BinaryTree.h"
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	BinaryTree<int> tree;
    	int data[] = { 23, 54, 76, 90, 12, 33, 74, 92, 19 };
    	tree.InitTree(data, 9);
    
    	//for (int i = 1; i <= 10; i++)
    	//	tree.InsertData(i);
    
    	tree.deleteData(90);
    	tree.travelTree(0);
    
    
    	return 0;
    }
    

    .h程序

    #pragma once
    #include<iostream>
    using namespace std;
    
    
    template<class T>
    class BinaryTree
    {
    public:
    	BinaryTree();//构造函数
    	~BinaryTree();//析构函数
    	void InitTree(const T*pData, int size);//初始化树
    	void InsertData(const T& insertData);//插入节点
    	void deleteData(const T&data);//删除节点
    	int findData(const T& data);//寻找节点
    	void travelTree(int travelType);//遍历树
    
    private:
    
    	void _preTravel(int index);//先序遍历
    	void _midTravel(int index);//中序遍历
    	void _lstTravel(int index);//后序遍历
    
    	T* pRoot;//数组
    	int size;//元素个数
    	int capacity;//容量
    };
    
    template<class T>
    BinaryTree<T>::BinaryTree()
    {
        pRoot = 0;
    	size = 0;
    	capacity = 0;
    }
    
    template<class T>
    BinaryTree<T>::~BinaryTree()
    {
    	if (pRoot)
    	{
    		delete[]pRoot;
    	}
    	pRoot = 0;
    	size = 0;
    	capacity = 0;
    }
    
    
    template<class T>
    void BinaryTree<T>::InitTree(const T*pData, int size)
    {
    	if (pRoot)
    	{
    		delete[]pRoot;
    	}
    
    	if (size>0)
    	{
    		pRoot = new T[size];
    		memcpy(pRoot, pData, size*sizeof(T));//将数组元素赋值给pRoot
    		this->size = (capacity = size);
    	}
    }
    
    template<class T>
    void BinaryTree<T>::InsertData(const T& data)
    {
    	if (size>=capacity)//判断是否需要开辟内存空间
    	{
    		capacity = capacity + ((capacity / 2 > 0) ? capacity / 2 : 1);//需要开辟空间的大小
    
    		T* pTemp = new T[capacity];//开辟空间
    
    		if (pRoot)
    		{
    			memcpy(pTemp, pRoot, sizeof(T)* size);//将原来的数据,复制到新的内存空间上,
    			delete[]pRoot;//再删除原来的内存空间
    		}
    		pRoot = pTemp;
    	}
    	pRoot[size++] = data;
    }
    
    template<class T>
    void BinaryTree<T>::deleteData(const T& data)
    {
    	int index = findData(data);//要删除的节点
    	if (index==-1)
    	{
    		return;//没有找到
    	}
    
    	if (index==size-1)//数组中最后一个元素
    	{
    		pRoot[size - 1] = 0;
    		size--;
    		return;
    	}
    	memcpy(&pRoot[index], &pRoot[index + 1], (size - index - 1)*sizeof(T));//除了最后一个元素,其他的元素,全部往前挪
    	size--;
    	return;
    }
    
    template<class T>
    int BinaryTree<T>::findData(const T& data)
    {
    	for (int i = 0; i < size; i++)
    	{
    		if (pRoot[i]==data)
    		{
    			return i;
    		}
    	}
    	return -1;
    }
    
    template<class T>
    void BinaryTree<T>::travelTree(int travelType)
    {
    	if (travelType==0)
    	{
    		cout << "前序遍历:";
    		_preTravel(0);
    		cout << endl;
    	}
    	else if (travelType==1)
    	{
    		cout << "中序遍历:";
    		_midTravel(0);
    		cout << endl;
    	}
    	else
    	{
    		cout << "后序遍历:";
    		_lstTravel(0);
    		cout << endl;
    	}
    }
    
    template<class T>
    void BinaryTree<T>::_preTravel(int index)
    {
    	if (index>=size)
    	{
    		return;
    	}
    	cout << pRoot[index] << " ";
    	_preTravel(2 * index + 1);
    	_preTravel(2 * index + 2);
    }
    
    template<class T>
    void BinaryTree<T>::_midTravel(int index)
    {
    	if (index >= size)
    	{
    		return;
    	}
    	_midTravel(2 * index + 1);
    	cout << pRoot[index] << " ";	
    	_midTravel(2 * index + 2);
    }
    
    template<class T>
    void BinaryTree<T>::_lstTravel(int index)
    {
    	if (index >= size)
    	{
    		return;
    	}
    	_lstTravel(2 * index + 1);
    	_lstTravel(2 * index + 2);
    	cout << pRoot[index] << " ";
    }
    
    
    
    
    展开全文
  • 数组方式存储完全二叉树(使用场景举例:最大堆) 如何存储 数组0号元素放元素的个数,1放根节点,后面放其他元素,一共n个元素。 怎样找到父节点 n/2嘛,就找到了父节点 怎样找到左孩子和右孩子节点 左孩子:n ×...
  • 完全二叉树数组

    千次阅读 2016-01-20 10:10:40
    完全二叉树因其紧密存储的特点,可以使用一位数组存储。只需要按照层序依次将节点放入队列中就ok了。 按层访问二叉树在前面已经介绍,但是访问队列是临时的,采取了出队操作。这里要保存数据的话,就不要出队操作...
  • 节点索引:i 父节点索引:(i-1)/2 左子节点:2i+1 右子节点:2i+2
  • N个结点的完全二叉树中,对于下标为 i 的结点: 1.当i/2取整>=1 时,i/2取整单元是其父结点;当i/2取整=0时,表明该结点是数的根节点,无父结点 2.当2i<=N 时,2i单元是其左孩子;否则无左孩子 3.当2i+1<=N...
  • 二叉树主要有两种实现方式,数组形式和链表形式,其中数组形式是利用完全二叉树的性质5: 性质5:如果对一棵有n个结点的完全二叉树的结点按层序编号,则对任一结点i(1in),有: (1) 如果i=1,则结点i是...
  • 二叉树用数组顺序存储(完全二叉树)并实现三种遍历。代码详解!!!
  • 二叉树可以采用数组的方法进行存储,把数组中的数据依次自上而下,自左至右存储到二叉树结点中,一般二叉树与完全二叉树对比,比完全二叉树缺少的结点就在数组中用0来表示。,如下图所示 从上图可以看出,右边的是一...
  • 将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果。 输入格式: 输入第一行给出一个不超过20的正整数N...
  • 额, 先看下什么是完全二叉树 ,...根据数组生成一个完全二叉树, 思路1:叶子节点的下标/2 就是对应的父节点,(此思路的核心) 先有一个数组保存所有的节点, 然后生成每一个节点,然后根据生成节点的下标/2 找到父节点,...
  • 二叉树数组存储

    2017-12-07 11:22:00
    数组下标为1的位置开始存放完全二叉树中的元素。 两点:第一,依次从上层往下层放;第二,每层依次从左往右放。 3 非完全二叉树数组存储 将每个结点的左右孩子用NULL结点补充完整构成一颗完全二叉树,然后用...
  • 二叉树可以采用数组的方法进行存储,把数组中的数据依次自上而下,自左至右存储到二叉树结点中,一般二叉树与完全二叉树对比,比完全二叉树缺少的结点就在数组中用0来表示。,如下图所示 从上图可以看出,右边的是...
  • c++实现二叉树数组存储,代码很简单,参考即可
  • DS二叉树——二叉树之...二叉树可以采用数组的方法进行存储,把数组中的数据依次自上而下,自左至右存储到二叉树结点中,一般二叉树与完全二叉树对比,比完全二叉树缺少的结点就在数组中用0来表示。,如下图所示 ...
  • python 数组构建完全二叉树

    千次阅读 2019-08-20 08:56:52
    满二叉树:树中除了叶子节点,每个节点都有两个子...二叉树主要有两种实现方式,数组形式和链表形式,其中数组形式是利用完全二叉树的性质5: 性质5:如果对一棵有n个结点的完全二叉树的结点按层序编号,则对任一...
  • 一维数组建立完全二叉树 python实现 // An highlighted block class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None def CreateTree(completeTreeList, start): """ 用...
  • 思路: 简单介绍了用数组存储完全二叉树的问题,重点就是找到父节点和子节点的关系(Node = 2leftNode+1,Node = 2rightNode+1 ) 下面的代码就是二叉树用数组存储后,怎么对数组进行前中后遍历的问题。 代码:...
  • //堆是完全二叉树 void swap(int tree[],int i,int max) //存在更大的结点值 (使此时最大结点的值与当前最大结点的值交换 { int temp; temp=tree[i]; tree[i]=tree[max]; tree[max]=temp; } void...
  • 对于完全二叉树,如果将其中的元素按层次遍历顺序存放入一个一维数组中:设数组大小为n(节点数为n),节点标号(key)为数组下标i,即0,1,2,3,4,,,那么:1.完全二叉树的高度为: ceil(log2(n+1))2.i = 0: 根节点,...
  • //根据数组生成完全二叉树 void print_tree(NODE* root); // 广度优先打印树 QUEUE* new_queue(int length); //初始化一个长度为length的队列 void push_queue(QUEUE *q,NODE *n);//压入队列 NODE* pop_queue(QUEUE...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 67,042
精华内容 26,816
关键字:

完全二叉树数组