树的性质(不定期更新)

完全二叉树可以和数组完美转换

若将完全二叉树的节点按构件顺序进行编号(从0开始,即树根节点编号为0)。

性质1:节点i的两个子节点的编号为2i+1和2i+2.

性质2:由性质1可得,当i > 0 时,其父节点为 floor((i-1)/2)

性质3:完全二叉树中最后一个有子节点的节点为 n/2 - 1。 n为节点数量

利用顶堆的堆积排序:

大/小顶堆的性质:

1、顶堆一定是完全二叉树,所以可以用数组直接表示

2、大/小顶堆的每个子树也是大/小顶堆

排序思路:

基本思想:把待排序的元素按照大小在二叉树位置上排列,排序好的元素要满足:父节点的元素要大于等于其子节点;这个过程叫做堆化过程,如果根节点存放的是最大的数,则叫做大根堆;如果是最小的数,自然就叫做小根堆了。根据这个特性(大根堆根最大,小根堆根最小),就可以把根节点拿出来,然后再堆化下,再把根节点拿出来,,,,循环到最后一个节点,就排序好了。

参考1:https://blog.csdn.net/YuZhiHui_No1/article/details/44258297

参考2:http://www.seotest.cn/jishu/46956.html

实现:

1、堆化过程:从最后一个分支结点(n div 2)开始,到根(1)为止,依次对每个分支结点进行调整(下沉),以便形成以每个分支结点为根的堆,当最后对树根结点进行调整后,整个树就变成了一个堆。

所谓下沉,即将节点通过不断与自己的子节点进行比较、交换,直到行进到某个位置使得自己是当前子树中最大或最小的。因为单独的下沉过程并不能保证子树的正确性。所以一定要从最下层有子节点的节点开始下沉,以保证整体算法的正确性。

2、方法是依次将堆的根节点数记下,然后删除根节点,如此反复直到堆为空。上面提到了删除操作,每次删除之后都是要调整堆让堆的性质不变,即根节点必为最大值或最小值。

具体操作可以使每次都将根节点与当前排序的数组片段的最后一位互换,然后对新数组的第一个元素进行下沉操作(并将进行堆化的数组长度-1)

由顶堆的性质(或根据堆化的过程)可知,在排序阶段,除每次的顶点外的其他顶点都是已经经过下沉操作的,所以直接对新顶点进行下沉即可得到新的顶堆

#include "core.hpp"
void heap(int *data, int size);
void ad_heap(int *data, int i, int size);

void heap(int *data, int size){
    // int i, j, tmp;
    // 根据性质可得,节点 i = size/2 -1 是最后一个有子节点的节点
    // 且i节点之前的所有节点都一定有两个子树
    // 从节点i开始向前,对所有节点进行下沉操作,保证当前节点下的所有子树的正确性
    for(int i=(size/2 - 1);i>=0;i--){
        ad_heap(data, i, size);
    }
    cout << "\n 堆积内容:";
    print_array(data, size);
    for(int i = size - 2; i >0; i--){
        mswap(data[0], data[i+1]);              // 交换堆化后数组的第一个值和最后一个值, mswap仅实现了数值交换
        ad_heap(data,0, i);                    // 对长度减一的数组的根节点进行下沉操作
    }
    print_array(data, size);

}


// 该函数的作用是将节点i的值下沉到正确位置,并不是将以i为顶点的二叉树转为顶堆
// 当下沉到某个节点,使得i的值比当前节点两个子节点斗大即完成下沉
// 子树的正确性由调用函数保证
void ad_heap(int *data, int i, int size){
    cout << "called====================" << endl;
    int j, tmp, post;
    j = 2*i + 1;
    tmp = data[i];
    post = 0;
    while (j < size && post ==0){
        cout << "j: " << j << " i: " << i << " root: " << tmp  << " left: " << data[j] << endl;
        if(j < size && j+1 < size){        // 标记左右子树中最大的一个
            if(data[j] < data[j+1]){
                j++;
            }
        }
        if(tmp >= data[j]){                // 如果当前节点比左右子树都大则认为下沉完成
            post = 1;                      // 不再进一步校验下一层的原因是,默认子树已经完成下沉,再进行校验就是重复校验了
        }
        else{
            data[(j-1)/2] = data[j];        // 当前节点小于左节点或右节点,需要交换该子节点的值与当前根节点的值
            j = 2*j + 1;                    // 因为发生了交换,不能保证交换后的各个子树仍然正确,故需要继续对下一层进行检查
        }
    }
    
    data[(j-1)/2] = tmp;
    print_array(data, size);
    cout << "end====================" << endl;

}


int main(){
    int data[8] = {34,19,40,14,57,17,4,43};
    heap(data, 8);
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,753评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,668评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,090评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,010评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,054评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,806评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,484评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,380评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,873评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,021评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,158评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,838评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,499评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,044评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,159评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,449评论 3 374
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,136评论 2 356

推荐阅读更多精彩内容

  • 一些概念 数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这...
    Winterfell_Z阅读 5,836评论 0 13
  • 1)这本书为什么值得看: Python语言描述,如果学的Python用这本书学数据结构更合适 2016年出版,内容...
    孙怀阔阅读 12,486评论 0 15
  • <希尔排序> 详细代码请参考Algorithm。参考代码比文字好理解。希尔排序,也称递减增量排序算法,是插入排序的...
    明明的魔样阅读 1,744评论 0 1
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 5,188评论 0 52
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到已排序好...
    依依玖玥阅读 1,258评论 0 2