堆和搜索树

本文介绍如何使用C++实现最大堆类、Huffman树及二叉搜索树的构建。主要内容包括最大堆的插入与删除操作、Huffman编码生成、二叉搜索树的插入与遍历等。同时,通过键盘录入一系列整数来展示这些数据结构的实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文章主要包括以下内容:
1、 创建最大堆类。最大堆的存储结构使用链表。
2、 提供操作:堆的插入、堆的删除。堆的初始化。Huffman树的构造。二叉搜索树的构造。
3、 接收键盘录入的一系列整数,输出其对应的最大堆、Huffman编码以及二叉搜索树。
4、 堆排序。
下面是c++代码实现:


#include <stdio.h>
#include <iostream>  
#include <cstdlib>
#include <cstdio>
#include <stack>  
using namespace std;  



#define MAXSIZE 20
#define MAXDEPTH 10

class BinaryTreeNode//二叉树节点类
{
public:
    BinaryTreeNode() {leftChild = rightChild = 0;}
    BinaryTreeNode(int d) {data = d; leftChild = rightChild = 0;}
    BinaryTreeNode(int d, BinaryTreeNode* left, BinaryTreeNode* right) {data = d; leftChild = left; rightChild = right;}

    int data;
    BinaryTreeNode* leftChild;
    BinaryTreeNode* rightChild;
};

class MaxHeap//最大堆类
{
private:
    int currentSize, maxSize;
    int* heap;
public:
    MaxHeap(int size = 10)//类初始化
    {
        maxSize = size;
        heap = new int[maxSize + 1];
        currentSize = 0;
    }
    void init(int array[], int arrayCurrentSize, int arrayMaxSize)//接收一个数组产生一个最大堆
    {
        delete [] heap;
        heap = array;
        currentSize = arrayCurrentSize;
        maxSize = arrayMaxSize;

        // 产生一个最大堆
        for(int i = currentSize / 2; i >= 1; i--)
        {
            int y = heap[i];// 子树的根

            // 寻找放置 y的位置
            int c = 2*i;// c的父节点是y的目标位置
            while(c <= currentSize)
            {
                if(c < currentSize && heap[c] < heap[c + 1]) c++;

                if(y >= heap[c]) break;//同一层比较大的

                heap[c / 2] = heap[c];//孩子上移
                c *= 2;
            }
            heap[c / 2] = y;
        }
    }
    void insert(int x)//插入一个元素
    {
        if(currentSize == maxSize) {cout << "out of bounds"; return;}

        int i = ++currentSize;
        while(i != 1 && x > heap[i / 2])
        {
            heap[i] = heap[i / 2];
            i /= 2;
        }
        heap[i] = x;
    }
    int deleteMax()//删除最大元素
    {
        if(currentSize == 0) {cout << "there is no mem"; return -1;}

        int x = heap[1];
        // 重构堆
        int y = heap[currentSize--];// 最后一个元素
        // 从根开始,为 y 寻找合适的位置
        int i = 1;
        int ci = 2;
        while(ci <= currentSize)
        {
            if(ci < currentSize && heap[ci] < heap[ci + 1]) ci++;

            if(y >= heap[ci]) break;//这是while的跳出条件,即为最后的节点找到适当的位置

            heap[i] = heap[ci];//把孩子放入上一层
            i = ci;//下移一层
            ci *= 2;
        }
        heap[i] = y;

        return x;
    }

};


//下面是堆排序
void heapSort(int a[], int n)
{
    int b[n + 1];

    MaxHeap maxHeap;
    maxHeap.init(a, n, n);

    for(int i = 1; i <= n; i++)
    {
        cout << maxHeap.deleteMax() << endl;
    }
    for(int i = 1; i <= n; i++)
    {
        a[i] = b[i];
    }
}


class BinarySearchTree//搜索树类
{
public:
    BinaryTreeNode* root;
    BinarySearchTree() {root = 0;}

    void insert(int e)//插入一个元素
    {
        BinaryTreeNode* p = root;
        BinaryTreeNode* pp = 0;// p的父节点指针

        while(p)

        {//检查 p - > d a t a
            pp = p;
            if(e < p->data) p = p->leftChild;// 将p移向孩子节点
            else if(e > p->data) p = p->rightChild;
            else {cout << "bad input"; return;}//又重复的
        }

        // 为e 建立一个节点,并将该节点连接至 to pp                                                                                                  
        BinaryTreeNode* r = new BinaryTreeNode(e);
        if(root)
        {
            if(e < pp->data) pp->leftChild = r;
            else pp->rightChild = r;
        }
        else
            root = r;
    }
    void preOrder(BinaryTreeNode* t)//前序遍历
    {
        if(t != NULL)
        {
            preOrder(t->leftChild);
            cout << t->data << endl;
            preOrder(t->rightChild);
        }
    }

};


class HuffmanTree
{
public:
    //数组a储存的是各个树的权重
    HuffmanTree(int a[], int n)
    {
        b = new BinaryTreeNode*[100];

        for(int i = 0; i < n; i++)
            b[i] = new BinaryTreeNode(a[i + 1]);


        for(int i = 1; i < n; i++)//进行 n-1 次循环建立哈夫曼树
        {
            //k1表示森林中具有最小权值的树根结点的下标,k2为次最小的下标
            int k1 = -1, k2;
            for(int j = 0; j < n; j++)//让k1初始指向森林中第一棵树,k2指向第二棵
            {
                if(b[j] != NULL && k1 == -1)
                {
                    k1 = j;
                    continue;
                }
                if(b[j] != NULL)
                {
                    k2 = j;
                    break;
                }
            }
            for(int j = k2; j < n; j++)//从当前森林中求出最小权值树和次最小
            {
                if(b[j] != NULL)
                {
                    if (b[j]->data < b[k1]->data)
                    {
                        k2 = k1;
                        k1 = j;
                    }
                    else if (b[j]->data < b[k2]->data)
                        k2 = j;
                }
            }
            //下面是最小和次最小的合并
            BinaryTreeNode *q = new BinaryTreeNode();
            q->data = b[k1]->data + b[k2]->data;
            q->leftChild = b[k1];
            q->rightChild = b[k2];

            b[k1] = q;
            b[k2] = NULL;

        }
    }

    void preOrder(BinaryTreeNode* b)//这是遍历一个树的函数
    {
        if (b != NULL)
        {
            cout << b->data << endl;
            preOrder(b->leftChild);
            preOrder(b->rightChild);
        }
    }
    void printCode(BinaryTreeNode* b, int len)//这是打印霍夫曼编码的函数
    {
        static int code[MAXDEPTH];
        if(b != NULL)
        {
            if(b->leftChild == NULL && b->rightChild == NULL)
            {
                cout << "the huffman code of " << b->data << " is ";
                for(int i = 0; i < len; i++)
                {
                    cout << code[i];
                }
                cout << endl;

            }
            code[len] = 0;
            printCode(b->leftChild, len + 1);
            code[len] = 1;
            printCode(b->rightChild, len + 1);
        }
    }

    BinaryTreeNode** b;
};



int main()
{
    int a[MAXSIZE];
    int n;
    cout << "输入数组长度:" << endl;
    cin >> n;   //输入样例 5
    cout << "输入数据:" << endl;
    for(int i = 1; i <= n; i++) //输入样例 1 32 21 35 41
        cin >> a[i];

    cout << "bst:" << endl;
    BinarySearchTree bstree;
    for(int i =1; i <= 5; i++)
        bstree.insert(a[i]);
    cout << "preOrder:" << endl;
    bstree.preOrder(bstree.root);

    cout << "huffman:" << endl;
    HuffmanTree htree(a, 5);
    htree.preOrder(*htree.b);
    // htree.printCode(htree.b[0], 0);

    cout << "heap sort:" << endl;
    heapSort(a, 5);
    system("pause");
    return 0;
}
<think>好的,我现在需要处理用户关于山东大学数据结构实验七的请求,涉及搜索树的C语言实现代码。首先,我需要理解用户的具体需求。用户提到实验七的内容,特别是(Heap)搜索树(Search Tree)的实现,用C语言编写代码。同时,用户可能希望得到相关的代码示例解释,以及可能的问题。 接下来,我需要检查现有的引用内容,看看是否有相关的资料。根据提供的引用,引用[2]提到了二叉搜索树的创建,前序中序序列的输出,这可能与搜索树相关。引用[3]讨论了树形结构的实现,使用childbrother指针,这可能对理解树的结构有帮助,但可能不直接涉及或二叉搜索树的具体实现。引用[1]则比较笼统,提到树章节的代码题,可能相关但信息有限。 用户的问题可能涉及如何用C语言实现二叉搜索树。对于,通常是指二叉,分为最大最小,需要实现插入、删除等操作。而搜索树可能指二叉搜索树(BST),需要实现插入、查找、遍历等功能。 我需要确保提供的代码符合用户的要求,并且正确无误。由于用户可能正在做实验,代码的正确性规范性很重要。同时,需要考虑到用户可能对某些细节不太清楚,比如的调整操作或BST的递归实现。 对于的实现,通常使用数组来存储,关键操作是上浮(sift up)下沉(sift down)。而二叉搜索树则需要节点结构,包含左右子节点指针,以及插入遍历的方法。根据引用[2],用户可能需要处理重复关键字的情况,所以在插入时需要检查重复。 接下来,我需要生成相关的代码示例。例如,最大的插入删除操作,以及BST的插入前序、中序遍历。同时,需要解释代码的结构关键步骤,帮助用户理解。 可能的问题包括的时间复杂度、BST的平衡性问题,或者如何处理重复元素。用户还可能询问如何测试这些数据结构,或者如何将它们应用到实际问题中。 最后,需要确保回答结构清晰,分点说明,代码部分用正确的格式,并引用相关的引用内容。例如,引用[2]提到的二叉搜索树的创建输出可以对应到BST的代码部分。同时,生成的相关问题需要与搜索树相关,帮助用户进一步学习。</think>### 山东大学数据结构实验七:搜索树的C语言实现 #### 1. 的实现(以最大为例) 是一种完全二叉树,满足父节点值 ≥ 子节点值(最大)。以下是核心代码: ```c #include <stdio.h> #include <stdlib.h> #define MAX_HEAP_SIZE 100 typedef struct { int data[MAX_HEAP_SIZE]; int size; } MaxHeap; // 插入元素后的上浮调整 void sift_up(MaxHeap* heap, int index) { while (index > 0 && heap->data[index] > heap->data[(index-1)/2]) { int parent = (index-1)/2; int temp = heap->data[index]; heap->data[index] = heap->data[parent]; heap->data[parent] = temp; index = parent; } } // 插入操作 void insert(MaxHeap* heap, int value) { if (heap->size >= MAX_HEAP_SIZE) return; heap->data[heap->size] = value; sift_up(heap, heap->size); heap->size++; } // 删除顶后的下沉调整 void sift_down(MaxHeap* heap, int index) { int max_index = index; int left = 2*index + 1; if (left < heap->size && heap->data[left] > heap->data[max_index]) max_index = left; int right = 2*index + 2; if (right < heap->size && heap->data[right] > heap->data[max_index]) max_index = right; if (index != max_index) { int temp = heap->data[index]; heap->data[index] = heap->data[max_index]; heap->data[max_index] = temp; sift_down(heap, max_index); } } // 删除顶元素 int extract_max(MaxHeap* heap) { if (heap->size <= 0) return -1; int max = heap->data[0]; heap->data[0] = heap->data[heap->size-1]; heap->size--; sift_down(heap, 0); return max; } ``` #### 2. 二叉搜索树实现[^2] ```c typedef struct TreeNode { int key; struct TreeNode *left; struct TreeNode *right; } TreeNode; // 创建新节点 TreeNode* new_node(int key) { TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode)); node->key = key; node->left = node->right = NULL; return node; } // 插入操作(不允许重复) TreeNode* insert_bst(TreeNode* root, int key) { if (!root) return new_node(key); if (key < root->key) root->left = insert_bst(root->left, key); else if (key > root->key) root->right = insert_bst(root->right, key); return root; // 遇到重复直接返回 } // 前序遍历 void pre_order(TreeNode* root) { if (root) { printf("%d ", root->key); pre_order(root->left); pre_order(root->right); } } // 中序遍历 void in_order(TreeNode* root) { if (root) { in_order(root->left); printf("%d ", root->key); in_order(root->right); } } ``` #### 关键实现要点 1. **的数组存储**:利用完全二叉树特性,通过下标计算父子节点位置 2. **调整算法**:插入时上浮($O(\log n)$),删除时下沉($O(\log n)$) 3. **BST递归插入**:通过比较关键字决定插入方向,严格处理重复值 4. **树形结构遍历**:前序(根-左-右)、中序(左-根-右)的标准实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值