zoukankan      html  css  js  c++  java
  • 堆 续5

    -------------------siwuxie095

       

       

       

       

       

       

       

       

    索引从 1 开始

       

       

    程序 1:最大索引堆的实现

       

    MaxIndexHeap.h:

       

    #ifndef MAXINDEXHEAP_H

    #define MAXINDEXHEAP_H

       

    #include <iostream>

    #include <string>

    #include <cassert>

    #include <algorithm>

    using namespace std;

       

       

       

    //最大索引堆:索引从1开始

    template<typename Item>

    class MaxIndexHeap

    {

       

    private:

    Item *data; //指向存储元素的数组

    int *indexes; //指向存储索引的数组

    int count;

    int capacity;

       

       

    //私有函数,用户不能调用

    void shiftUp(int k)

    {

    //如果新添加的元素大于父节点的元素,则进行交换

    while (k > 1 && data[indexes[k / 2]] < data[indexes[k]])

    {

    swap(indexes[k / 2], indexes[k]);

    k /= 2;

    }

    }

       

       

    //也是私有函数,用户不能调用

    void shiftDown(int k)

    {

    //只要当前节点有孩子就进行循环

    while (2 * k <= count)

    {

    // 在此轮循环中,data[indexes[k]]data[indexes[j]]交换位置

    int j = 2 * k;

       

    // data[indexes[j]]data[indexes[j]]data[indexes[j+1]]中的最大值

    if (j + 1 <= count && data[indexes[j + 1]] > data[indexes[j]])

    {

    j += 1;

    }

       

    if (data[indexes[k]] >= data[indexes[j]])

    {

    break;

    }

       

    swap(indexes[k], indexes[j]);

    k = j;

    }

    }

       

       

    public:

       

    MaxIndexHeap(int capacity)

    {

       

    //因为存储时是从索引1开始的,所以要加1

    //多开辟一个空间

    data = new Item[capacity + 1];

    //同理..

    indexes = new int[capacity + 1];

    //计数器,这里索引等于计数器

    count = 0;

    this->capacity = capacity;

       

    }

       

       

    ~MaxIndexHeap()

    {

    delete []data;

    delete []indexes;

    }

       

       

    int size()

    {

    return count;

    }

       

       

    bool isEmpty()

    {

    return count == 0;

    }

       

       

    // 传入的i对用户而言,是从0索引的,即外部是

    //0开始的,而内部是从1开始的

    void insert(int i, Item item)

    {

    //防止越界

    assert(count + 1 <= capacity);

    assert(i + 1 >= 1 && i + 1 <= capacity);

       

    i += 1;

    data[i] = item;

    indexes[count + 1] = i;

    count++;

       

    shiftUp(count);

    }

       

       

    //取出最大的data

    Item extractMax()

    {

    //首先要保证堆不为空

    assert(count > 0);

       

    Item ret = data[indexes[1]];

    swap(indexes[1], indexes[count]);

    count--;

    shiftDown(1);

    return ret;

    }

       

       

    //取出最大的data对应的index

    int extractMaxIndex()

    {

    assert(count > 0);

       

    //对于外部来说,索引从0开始,所以要减一

    int ret = indexes[1] - 1;

    swap(indexes[1], indexes[count]);

    count--;

    shiftDown(1);

    return ret;

    }

       

       

    Item getMax()

    {

    assert(count > 0);

    //对于外部来说,索引从0开始,所以要减一

    return data[indexes[1]];

    }

       

       

    int getMaxIndex()

    {

    assert(count > 0);

    return indexes[1] - 1;

    }

       

       

    Item getItem(int i)

    {

    //对于外部来说,索引从0开始,

    //对于内部来说,索引从1开始,

    //所以要加一

    return data[i + 1];

    }

       

       

    //修改 index 对应的 data

    void change(int i, Item newItem)

    {

       

    i += 1;

    data[i] = newItem;

       

    // 找到indexes[j] = i, j表示data[i]在堆中的位置

    // 之后尝试着shiftUp(j)一下, shiftDown(j)一下

    //看看能不能向上或向下移动以保持堆的性质

    for (int j = 1; j <= count; j++)

    {

    if (indexes[j] == i)

    {

    shiftUp(j);

    shiftDown(j);

    return;

    }

    }

       

    //该函数的时间复杂度O(n)+O(lgn)级别的,也就是O(n)级别的函数

    //其中:遍历是nShift UpShift Downlgn

    //

    //之前的插入操作和删除操作,都能保证是lgn级别的,使得它的性

    //能优势非常明显,现在修改一个元素,它的时间复杂度变成了O(n)

    //级别,那么对用户来讲,在外部进行n个堆操作,在最坏的情况下,

    //总的时间就有可能变成O(n^2)这个级别,这是非常不理想的一种情

    //况,change()这个函数可以进行优化

    }

       

       

    public:

       

    //在控制台打印测试用例

    void testPrint()

    {

       

    //限制:只能打印100个元素以内的堆,因为控制台一行的字符数量有限

    if (size() >= 100)

    {

    cout << "Fancy print can only work for less than 100 int";

    return;

    }

       

    //限制:只能打印类型是int的堆

    if (typeid(Item) != typeid(int))

    {

    cout << "Fancy print can only work for int item";

    return;

    }

       

    cout << "The Heap size is: " << size() << endl;

    cout << "data in heap: ";

    for (int i = 1; i <= size(); i++)

    {

    cout << data[i] << " ";

    }

    cout << endl;

    cout << endl;

       

    int n = size();

    int max_level = 0;

    int number_per_level = 1;

    while (n > 0)

    {

    max_level += 1;

    n -= number_per_level;

    number_per_level *= 2;

    }

       

    int max_level_number = int(pow(2, max_level - 1));

    int cur_tree_max_level_number = max_level_number;

    int index = 1;

    for (int level = 0; level < max_level; level++)

    {

    string line1 = string(max_level_number * 3 - 1, ' ');

       

    int cur_level_number = min(count - int(pow(2, level)) + 1,

    int(pow(2, level)));

       

    bool isLeft = true;

       

    for (int index_cur_level = 0; index_cur_level < cur_level_number;

    index++, index_cur_level++)

    {

    putNumberInLine(indexes[index], line1, index_cur_level,

    cur_tree_max_level_number * 3 - 1, isLeft);

       

    isLeft = !isLeft;

    }

    cout << line1 << endl;

       

       

    if (level == max_level - 1)

    {

    break;

    }

       

       

    string line2 = string(max_level_number * 3 - 1, ' ');

    for (int index_cur_level = 0; index_cur_level < cur_level_number;

    index_cur_level++)

    {

    putBranchInLine(line2, index_cur_level, cur_tree_max_level_number * 3 - 1);

    }

       

    cout << line2 << endl;

       

    cur_tree_max_level_number /= 2;

    }

    }

       

       

       

    private:

       

    void putNumberInLine(int num, string &line, int index_cur_level,

    int cur_tree_width, bool isLeft)

    {

       

    int sub_tree_width = (cur_tree_width - 1) / 2;

       

    int offset = index_cur_level * (cur_tree_width + 1) + sub_tree_width;

       

    assert(offset + 1 < line.size());

       

    if (num >= 10)

    {

    line[offset + 0] = '0' + num / 10;

    line[offset + 1] = '0' + num % 10;

    }

    else

    {

    if (isLeft)

    line[offset + 0] = '0' + num;

    else

    line[offset + 1] = '0' + num;

    }

    }

       

       

    void putBranchInLine(string &line, int index_cur_level, int cur_tree_width)

    {

       

    int sub_tree_width = (cur_tree_width - 1) / 2;

       

    int sub_sub_tree_width = (sub_tree_width - 1) / 2;

       

    int offset_left = index_cur_level * (cur_tree_width + 1) + sub_sub_tree_width;

       

    assert(offset_left + 1 < line.size());

       

    int offset_right = index_cur_level * (cur_tree_width + 1) + sub_tree_width

    + 1 + sub_sub_tree_width;

       

    assert(offset_right < line.size());

       

    line[offset_left + 1] = '/';

    line[offset_right + 0] = '\';

    }

    };

       

       

       

    #endif

       

       

       

    main.cpp:

       

    #include "MaxIndexHeap.h"

    #include <ctime>

       

       

    int main()

    {

       

    MaxIndexHeap<int> maxIndexHeap = MaxIndexHeap<int>(100);

       

    srand(time(NULL));

    for (int i = 0; i < 15; i++)

    {

    maxIndexHeap.insert(i, rand() % 100);

    }

       

    maxIndexHeap.testPrint();

       

    cout << endl;

    while (!maxIndexHeap.isEmpty())

    {

    cout << maxIndexHeap.extractMax() << " ";

    }

    cout << endl;

       

    system("pause");

    return 0;

    }

       

       

    运行一览:

       

       

       

       

       

       

       

       

    程序 2:最大索引堆的优化

       

    MaxIndexHeap.h:

       

    #ifndef MAXINDEXHEAP_H

    #define MAXINDEXHEAP_H

       

    #include <iostream>

    #include <string>

    #include <cassert>

    #include <algorithm>

    using namespace std;

       

       

       

    //最大索引堆:索引从1开始

    template<typename Item>

    class MaxIndexHeap

    {

       

    private:

    Item *data; //指向存储元素的数组

    int *indexes; //指向存储索引的数组

    int *reverse; //指向存储反向索引的数组

    int count;

    int capacity;

       

       

    //私有函数,用户不能调用

    void shiftUp(int k)

    {

    //如果新添加的元素大于父节点的元素,则进行交换

    while (k > 1 && data[indexes[k / 2]] < data[indexes[k]])

    {

    swap(indexes[k / 2], indexes[k]);

    reverse[indexes[k / 2]] = k / 2;

    reverse[indexes[k]] = k;

    k /= 2;

    }

    }

       

       

    //也是私有函数,用户不能调用

    void shiftDown(int k)

    {

    //只要当前节点有孩子就进行循环

    while (2 * k <= count)

    {

    // 在此轮循环中,data[indexes[k]]data[indexes[j]]交换位置

    int j = 2 * k;

       

    // data[indexes[j]]data[indexes[j]]data[indexes[j+1]]中的最大值

    if (j + 1 <= count && data[indexes[j + 1]] > data[indexes[j]])

    {

    j += 1;

    }

       

    if (data[indexes[k]] >= data[indexes[j]])

    {

    break;

    }

       

    swap(indexes[k], indexes[j]);

    reverse[indexes[k]] = k;

    reverse[indexes[j]] = j;

    k = j;

    }

    }

       

       

    public:

       

    MaxIndexHeap(int capacity)

    {

       

    //因为存储时是从索引1开始的,所以要加1

    //多开辟一个空间

    data = new Item[capacity + 1];

    //同理..

    indexes = new int[capacity + 1];

    //同理..

    reverse = new int[capacity + 1];

    //初始化reverse数组

    for (int i = 0; i <= capacity; i++)

    {

    //因为索引从1开始,所以0没有意义

    reverse[i] = 0;

    }

       

    //计数器,这里索引等于计数器

    count = 0;

    this->capacity = capacity;

       

    }

       

       

    ~MaxIndexHeap()

    {

    delete []data;

    delete []indexes;

    delete []reverse;

    }

       

       

    int size()

    {

    return count;

    }

       

       

    bool isEmpty()

    {

    return count == 0;

    }

       

       

    // 传入的i对用户而言,是从0索引的,即外部是

    //0开始的,而内部是从1开始的

    void insert(int i, Item item)

    {

    //防止越界

    assert(count + 1 <= capacity);

    assert(i + 1 >= 1 && i + 1 <= capacity);

       

    i += 1;

    data[i] = item;

    indexes[count + 1] = i;

    reverse[i] = count + 1;

    count++;

       

    shiftUp(count);

    }

       

       

    //取出最大的data

    Item extractMax()

    {

    //首先要保证堆不为空

    assert(count > 0);

       

    Item ret = data[indexes[1]];

    swap(indexes[1], indexes[count]);

    reverse[indexes[count]] = 0;

    reverse[indexes[1]] = 1;

    count--;

    shiftDown(1);

    return ret;

    }

       

       

    //取出最大的data对应的index

    int extractMaxIndex()

    {

    assert(count > 0);

       

    //对于外部来说,索引从0开始,所以要减一

    int ret = indexes[1] - 1;

    swap(indexes[1], indexes[count]);

    reverse[indexes[count]] = 0;

    reverse[indexes[1]] = 1;

    count--;

    shiftDown(1);

    return ret;

    }

       

       

    Item getMax()

    {

    assert(count > 0);

    //对于外部来说,索引从0开始,所以要减一

    return data[indexes[1]];

    }

       

       

    int getMaxIndex()

    {

    assert(count > 0);

    return indexes[1] - 1;

    }

       

       

    bool contain(int i){

    assert(i + 1 >= 1 && i + 1 <= capacity);

    //因为索引从1开始,0不存在,且reverse数组在

    //构造函数中都初始化为0,所以拿0做比较

    return reverse[i + 1] != 0;

    }

       

       

    Item getItem(int i)

    {

    assert(contain(i));

    //对于外部来说,索引从0开始,

    //对于内部来说,索引从1开始,

    //所以要加一

    return data[i + 1];

    }

       

       

    //修改 index 对应的 data

    void change(int i, Item newItem)

    {

    //防止越界和检查i是否在堆中,

    //因为有可能已经取出去了

    assert(contain(i));

       

    i += 1;

    data[i] = newItem;

       

    // 找到indexes[j] = i, j表示data[i]在堆中的位置

    // 之后尝试着shiftUp(j)一下, shiftDown(j)一下

    //看看能不能向上或向下移动以保持堆的性质

    int j = reverse[i];

    shiftUp(j);

    shiftDown(j);

       

    //先用O(1)的时间找到位置,再用O(lgn)的时间完成

    //Shift UpShift Down,此时,该函数的时间复杂

    //度就是O(lgn)级别的,如果有n个堆操作,总时间

    //就是O(n*lgn)

    //

    //加入了反向查找后,性能得到了巨大的提升

    }

       

       

    public:

       

    //在控制台打印测试用例

    void testPrint()

    {

       

    //限制:只能打印100个元素以内的堆,因为控制台一行的字符数量有限

    if (size() >= 100)

    {

    cout << "Fancy print can only work for less than 100 int";

    return;

    }

       

    //限制:只能打印类型是int的堆

    if (typeid(Item) != typeid(int))

    {

    cout << "Fancy print can only work for int item";

    return;

    }

       

    cout << "The Heap size is: " << size() << endl;

    cout << "data in heap: ";

    for (int i = 1; i <= size(); i++)

    {

    cout << data[i] << " ";

    }

    cout << endl;

    cout << endl;

       

    int n = size();

    int max_level = 0;

    int number_per_level = 1;

    while (n > 0)

    {

    max_level += 1;

    n -= number_per_level;

    number_per_level *= 2;

    }

       

    int max_level_number = int(pow(2, max_level - 1));

    int cur_tree_max_level_number = max_level_number;

    int index = 1;

    for (int level = 0; level < max_level; level++)

    {

    string line1 = string(max_level_number * 3 - 1, ' ');

       

    int cur_level_number = min(count - int(pow(2, level)) + 1,

    int(pow(2, level)));

       

    bool isLeft = true;

       

    for (int index_cur_level = 0; index_cur_level < cur_level_number;

    index++, index_cur_level++)

    {

    putNumberInLine(indexes[index], line1, index_cur_level,

    cur_tree_max_level_number * 3 - 1, isLeft);

       

    isLeft = !isLeft;

    }

    cout << line1 << endl;

       

       

    if (level == max_level - 1)

    {

    break;

    }

       

       

    string line2 = string(max_level_number * 3 - 1, ' ');

    for (int index_cur_level = 0; index_cur_level < cur_level_number;

    index_cur_level++)

    {

    putBranchInLine(line2, index_cur_level, cur_tree_max_level_number * 3 - 1);

    }

       

    cout << line2 << endl;

       

    cur_tree_max_level_number /= 2;

    }

    }

       

       

       

    private:

       

    void putNumberInLine(int num, string &line, int index_cur_level,

    int cur_tree_width, bool isLeft)

    {

       

    int sub_tree_width = (cur_tree_width - 1) / 2;

       

    int offset = index_cur_level * (cur_tree_width + 1) + sub_tree_width;

       

    assert(offset + 1 < line.size());

       

    if (num >= 10)

    {

    line[offset + 0] = '0' + num / 10;

    line[offset + 1] = '0' + num % 10;

    }

    else

    {

    if (isLeft)

    line[offset + 0] = '0' + num;

    else

    line[offset + 1] = '0' + num;

    }

    }

       

       

    void putBranchInLine(string &line, int index_cur_level, int cur_tree_width)

    {

       

    int sub_tree_width = (cur_tree_width - 1) / 2;

       

    int sub_sub_tree_width = (sub_tree_width - 1) / 2;

       

    int offset_left = index_cur_level * (cur_tree_width + 1) + sub_sub_tree_width;

       

    assert(offset_left + 1 < line.size());

       

    int offset_right = index_cur_level * (cur_tree_width + 1) + sub_tree_width

    + 1 + sub_sub_tree_width;

       

    assert(offset_right < line.size());

       

    line[offset_left + 1] = '/';

    line[offset_right + 0] = '\';

    }

    };

       

       

    #endif

       

       

       

    main.cpp:

       

    #include "MaxIndexHeap.h"

    #include <ctime>

       

       

    int main()

    {

       

    MaxIndexHeap<int> maxIndexHeap = MaxIndexHeap<int>(100);

    srand(time(NULL));

    for (int i = 0; i < 15; i++)

    {

    maxIndexHeap.insert(i, rand() % 100);

    }

       

    maxIndexHeap.testPrint();

       

    cout << endl;

    while (!maxIndexHeap.isEmpty())

    {

    cout << maxIndexHeap.extractMax() << " ";

    }

    cout << endl;

       

    system("pause");

    return 0;

    }

       

       

    运行一览:

       

       

       

       

       

       

       

       

    程序 3:最大索引堆的再优化

       

    MaxIndexHeap.h:

       

    #ifndef MAXINDEXHEAP_H

    #define MAXINDEXHEAP_H

       

    #include <iostream>

    #include <string>

    #include <cassert>

    #include <algorithm>

    using namespace std;

       

       

       

    //最大索引堆:索引从1开始

    template<typename Item>

    class MaxIndexHeap

    {

       

    private:

    Item *data; //指向存储元素的数组

    int *indexes; //指向存储索引的数组

    int *reverse; //指向存储反向索引的数组

    int count;

    int capacity;

       

       

    //私有函数,用户不能调用

    //使用插入排序的优化方式进行优化

    void shiftUp(int k)

    {

    Item e = data[indexes[k]];

    int i = indexes[k];

    //如果新添加的元素大于父节点的元素,则进行交换

    while (k > 1 && data[indexes[k / 2]] < e)

    {

    indexes[k] = indexes[k / 2];

    reverse[indexes[k]] = k;

    k /= 2;

    }

    indexes[k] = i;

    reverse[indexes[k]] = k;

    }

       

       

    //也是私有函数,用户不能调用

    //使用插入排序的优化方式进行优化

    void shiftDown(int k)

    {

    Item e = data[indexes[k]];

    int i = indexes[k];

    //只要当前节点有孩子就进行循环

    while (2 * k <= count)

    {

    // 在此轮循环中,data[indexes[k]]data[indexes[j]]交换位置

    int j = 2 * k;

       

    // data[indexes[j]]data[indexes[j]]data[indexes[j+1]]中的最大值

    if (j + 1 <= count && data[indexes[j + 1]] > data[indexes[j]])

    {

    j += 1;

    }

       

    if (e >= data[indexes[j]])

    {

    break;

    }

       

    indexes[k] = indexes[j];

    reverse[indexes[k]] = k;

    k = j;

    }

    indexes[k] = i;

    reverse[indexes[k]] = k;

    }

       

       

    public:

       

    MaxIndexHeap(int capacity)

    {

       

    //因为存储时是从索引1开始的,所以要加1

    //多开辟一个空间

    data = new Item[capacity + 1];

    //同理..

    indexes = new int[capacity + 1];

    //同理..

    reverse = new int[capacity + 1];

    //初始化reverse数组

    for (int i = 0; i <= capacity; i++)

    {

    //因为索引从1开始,所以0没有意义

    reverse[i] = 0;

    }

       

    //计数器,这里索引等于计数器

    count = 0;

    this->capacity = capacity;

       

    }

       

       

    ~MaxIndexHeap()

    {

    delete []data;

    delete []indexes;

    delete []reverse;

    }

       

       

    int size()

    {

    return count;

    }

       

       

    bool isEmpty()

    {

    return count == 0;

    }

       

       

    // 传入的i对用户而言,是从0索引的,即外部是

    //0开始的,而内部是从1开始的

    void insert(int i, Item item)

    {

    //防止越界

    assert(count + 1 <= capacity);

    assert(i + 1 >= 1 && i + 1 <= capacity);

       

    i += 1;

    data[i] = item;

    indexes[count + 1] = i;

    reverse[i] = count + 1;

    count++;

       

    shiftUp(count);

    }

       

       

    //取出最大的data

    Item extractMax()

    {

    //首先要保证堆不为空

    assert(count > 0);

       

    Item ret = data[indexes[1]];

    swap(indexes[1], indexes[count]);

    reverse[indexes[count]] = 0;

    reverse[indexes[1]] = 1;

    count--;

    shiftDown(1);

    return ret;

    }

       

       

    //取出最大的data对应的index

    int extractMaxIndex()

    {

    assert(count > 0);

       

    //对于外部来说,索引从0开始,所以要减一

    int ret = indexes[1] - 1;

    swap(indexes[1], indexes[count]);

    reverse[indexes[count]] = 0;

    reverse[indexes[1]] = 1;

    count--;

    shiftDown(1);

    return ret;

    }

       

       

    Item getMax()

    {

    assert(count > 0);

    //对于外部来说,索引从0开始,所以要减一

    return data[indexes[1]];

    }

       

       

    int getMaxIndex()

    {

    assert(count > 0);

    return indexes[1] - 1;

    }

       

       

    bool contain(int i){

    assert(i + 1 >= 1 && i + 1 <= capacity);

    //因为索引从1开始,0不存在,且reverse数组在

    //构造函数中都初始化为0,所以拿0做比较

    return reverse[i + 1] != 0;

    }

       

       

    Item getItem(int i)

    {

    assert(contain(i));

    //对于外部来说,索引从0开始,

    //对于内部来说,索引从1开始,

    //所以要加一

    return data[i + 1];

    }

       

       

    //修改 index 对应的 data

    void change(int i, Item newItem)

    {

    //防止越界和检查i是否在堆中,

    //因为有可能已经取出去了

    assert(contain(i));

       

    i += 1;

    data[i] = newItem;

       

    // 找到indexes[j] = i, j表示data[i]在堆中的位置

    // 之后尝试着shiftUp(j)一下, shiftDown(j)一下

    //看看能不能向上或向下移动以保持堆的性质

    int j = reverse[i];

    shiftUp(j);

    shiftDown(j);

       

    //先用O(1)的时间找到位置,再用O(lgn)的时间完成

    //Shift UpShift Down,此时,该函数的时间复杂

    //度就是O(lgn)级别的,如果有n个堆操作,总时间

    //就是O(n*lgn)

    //

    //加入了反向查找后,性能得到了巨大的提升

    }

       

       

    public:

       

    //在控制台打印测试用例

    void testPrint()

    {

       

    //限制:只能打印100个元素以内的堆,因为控制台一行的字符数量有限

    if (size() >= 100)

    {

    cout << "Fancy print can only work for less than 100 int";

    return;

    }

       

    //限制:只能打印类型是int的堆

    if (typeid(Item) != typeid(int))

    {

    cout << "Fancy print can only work for int item";

    return;

    }

       

    cout << "The Heap size is: " << size() << endl;

    cout << "data in heap: ";

    for (int i = 1; i <= size(); i++)

    {

    cout << data[i] << " ";

    }

    cout << endl;

    cout << endl;

       

    int n = size();

    int max_level = 0;

    int number_per_level = 1;

    while (n > 0)

    {

    max_level += 1;

    n -= number_per_level;

    number_per_level *= 2;

    }

       

    int max_level_number = int(pow(2, max_level - 1));

    int cur_tree_max_level_number = max_level_number;

    int index = 1;

    for (int level = 0; level < max_level; level++)

    {

    string line1 = string(max_level_number * 3 - 1, ' ');

       

    int cur_level_number = min(count - int(pow(2, level)) + 1,

    int(pow(2, level)));

       

    bool isLeft = true;

       

    for (int index_cur_level = 0; index_cur_level < cur_level_number;

    index++, index_cur_level++)

    {

    putNumberInLine(indexes[index], line1, index_cur_level,

    cur_tree_max_level_number * 3 - 1, isLeft);

       

    isLeft = !isLeft;

    }

    cout << line1 << endl;

       

       

    if (level == max_level - 1)

    {

    break;

    }

       

       

    string line2 = string(max_level_number * 3 - 1, ' ');

    for (int index_cur_level = 0; index_cur_level < cur_level_number;

    index_cur_level++)

    {

    putBranchInLine(line2, index_cur_level, cur_tree_max_level_number * 3 - 1);

    }

       

    cout << line2 << endl;

       

    cur_tree_max_level_number /= 2;

    }

    }

       

       

       

    private:

       

    void putNumberInLine(int num, string &line, int index_cur_level,

    int cur_tree_width, bool isLeft)

    {

       

    int sub_tree_width = (cur_tree_width - 1) / 2;

       

    int offset = index_cur_level * (cur_tree_width + 1) + sub_tree_width;

       

    assert(offset + 1 < line.size());

       

    if (num >= 10)

    {

    line[offset + 0] = '0' + num / 10;

    line[offset + 1] = '0' + num % 10;

    }

    else

    {

    if (isLeft)

    line[offset + 0] = '0' + num;

    else

    line[offset + 1] = '0' + num;

    }

    }

       

       

    void putBranchInLine(string &line, int index_cur_level, int cur_tree_width)

    {

       

    int sub_tree_width = (cur_tree_width - 1) / 2;

       

    int sub_sub_tree_width = (sub_tree_width - 1) / 2;

       

    int offset_left = index_cur_level * (cur_tree_width + 1) + sub_sub_tree_width;

       

    assert(offset_left + 1 < line.size());

       

    int offset_right = index_cur_level * (cur_tree_width + 1) + sub_tree_width

    + 1 + sub_sub_tree_width;

       

    assert(offset_right < line.size());

       

    line[offset_left + 1] = '/';

    line[offset_right + 0] = '\';

    }

    };

       

       

    #endif

       

       

       

    main.cpp:

       

    #include "MaxIndexHeap.h"

    #include <ctime>

       

       

    int main()

    {

       

    MaxIndexHeap<int> maxIndexHeap = MaxIndexHeap<int>(100);

       

    srand(time(NULL));

    for (int i = 0; i < 15; i++)

    {

    maxIndexHeap.insert(i, rand() % 100);

    }

       

    maxIndexHeap.testPrint();

       

    cout << endl;

    while (!maxIndexHeap.isEmpty())

    {

    cout << maxIndexHeap.extractMax() << " ";

    }

    cout << endl;

       

    system("pause");

    return 0;

    }

       

       

    运行一览:

       

       

       

       

       

       

       

       

       

       

       

    【made by siwuxie095】

  • 相关阅读:
    day25:接口类和抽象类
    vue1
    How the weather influences your mood?
    机器学习实验方法与原理
    How human activities damage the environment
    Slow food
    Brief Introduction to Esports
    Massive open online course (MOOC)
    Online learning in higher education
    Tensorflow Dataset API
  • 原文地址:https://www.cnblogs.com/siwuxie095/p/6951115.html
Copyright © 2011-2022 走看看