C++数据结构的一些代码(树部分)

本文详细介绍了二叉树的创建和遍历方法,包括先序、中序、后序创建以及广度优先遍历。同时,讲解了二叉排序树的插入操作,并提供了深度优先遍历的递归和迭代实现。此外,还涵盖了赫夫曼树的相关概念。

三、树

1.二叉树创建

1.1二叉树先序创建

下面的写法适合给定一个前序排列的字符串,然后据此创建二叉树

class TreeNode
{
public:
    char data;
    TreeNode *left, *right;
    TreeNode() { left = right = NULL; }
};
class BinTree
{
private:
    TreeNode *root;

    TreeNode *CreateBinTree()
    {
        char data;
        cin >> data;
        if (data == '0')
            return NULL;

        TreeNode *temp = new TreeNode;
        temp->data = data;
        temp->left = CreateBinTree();
        temp->right = CreateBinTree();

        return temp;
    }

public:
    BinTree() { root = CreateBinTree(); }
    TreeNode *BTRoot() { return root; }
};

1.2二叉树中后序遍历创建

按中序遍历和后序遍历给出一棵二叉树

#include <iostream>
#include <vector>
using namespace std;

class TreeNode
{
public:
    int data;
    TreeNode *left, *right;

    TreeNode() { left = right = NULL; }
    TreeNode(int x) : data(x) { left = right = NULL; }
};
class BinTree
{
public:
    TreeNode *root;
    int minw;

    BinTree() : minw(99999) { root = NULL; }
    TreeNode *CreateBinTree(vector<int> ino, vector<int> posto)
    {
        if (posto.empty())
            return NULL;

        int rootval = posto[posto.size() - 1];
        TreeNode *r = new TreeNode(rootval);

        if (posto.size() == 1)
            return r;

        int cutpos;
        for (cutpos = 0; cutpos < ino.size(); cutpos++)
            if (ino[cutpos] == rootval)
                break;

        vector<int> leftino(ino.begin(), ino.begin() + cutpos);
        vector<int> rightino(ino.begin() + cutpos + 1, ino.end());

        posto.resize(posto.size() - 1);
        vector<int> leftposto(posto.begin(), posto.begin() + leftino.size());
        vector<int> rightposto(posto.begin() + leftino.size(), posto.end());

        r->left = CreateBinTree(leftino, leftposto);
        r->right = CreateBinTree(rightino, rightposto);
        return r;
    }
    void PreOrder(TreeNode *r)
    {
        if (!r)
            return;
        else if (!r->left && !r->right)
        {
            if (r->data < minw)
                minw = r->data;
            return;
        }

        PreOrder(r->left);
        PreOrder(r->right);
    }
};

int main(int argc, char const *argv[])
{
    int n;
    while (cin >> n)
    {
        vector<int> ino(n), posto(n);
        for (int i = 0; i < n; i++)
            cin >> ino[i];
        for (int i = 0; i < n; i++)
            cin >> posto[i];

        BinTree bt;
        bt.root = bt.CreateBinTree(ino, posto);
        bt.PreOrder(bt.root);
        cout << bt.minw << endl;
    }

    return 0;
}

2.二叉树深度

int depth(TreeNode *root) //迭代
{
    if (root == NULL)
        return 0;

    int dep = 0;
    queue<TreeNode *> tn;
    tn.push(root);
    while (!tn.empty())
    {
        dep++;
        int num = tn.size(); //每一层结点的个数

        for (int i = 0; i < num; i++)
        {
            TreeNode *temp = tn.front();
            tn.pop();

            if (temp->left != NULL)
                tn.push(temp->left);
            if (temp->right != NULL)
                tn.push(temp->right);
        }
    }
    return dep;
}

三行递归

int depth(TreeNode *root)//递归
{
	if (root == NULL)
		return 0;

	return max(depth(root->left), depth(root->right)) + 1;
}

3.二叉排序树创建

二叉排序树(Binary Sort Tree)又称二叉查找树、二叉搜索树。 它或者是一棵空树;或者是具有下列性质的二叉树:

(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;

(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;

(3)左、右子树也分别为二叉排序树;

class TreeNode
{
public:
    int data;
    TreeNode *left, *right;

    TreeNode() { left = right = NULL; }
};
class BSTree
{
public:
    TreeNode *root;

    BSTree() { root = NULL; }
    void AddintoTree(int num)
    {
        TreeNode *t = root;
        while (true)
        {
            if (num < t->data)
            {
                if (t->left == NULL)
                {
                    t->left = new TreeNode;
                    t->left->data = num;
                    return;
                }
                else
                {
                    t = t->left;
                }
            }
            else
            {
                if (t->right == NULL)
                {
                    t->right = new TreeNode;
                    t->right->data = num;
                    return;
                }
                else
                {
                    t = t->right;
                }
            }
        }
    }
};

4.二叉树的遍历1

分别从递归与迭代的角度,研究了二叉树的三种深度优先遍历

递归

void Preorder(TreeNode *root, vector<char> &ans) //递归前序
{
    if (root == NULL)
        return;

    ans.push_back(root->data);
    Preorder(root->left, ans);
    Preorder(root->right, ans);
}

void Inorder(TreeNode *root, vector<char> &ans) //递归中序
{
    if (root == NULL)
        return;

    Inorder(root->left, ans);
    ans.push_back(root->data);
    Inorder(root->right, ans);
}

void Postorder(TreeNode *root, vector<char> &ans) //递归后序
{
    if (root == NULL)
        return;

    Postorder(root->left, ans);
    Postorder(root->right, ans);
    ans.push_back(root->data);
}

迭代

迭代采用的写法是标记法,旨在用NULL空指针去标记栈中未进行处理的结点

vector<char> Preorder(TreeNode *root) //迭代前序
{
    vector<char> ans;
    stack<TreeNode *> tn;
    if (root != NULL)
        tn.push(root);
    while (!tn.empty())
    {
        TreeNode *temp = tn.top();
        tn.pop();
        if (temp != NULL)
        {
            //前序遍历,入栈顺序是右左根
            if (temp->right != NULL)
                tn.push(temp->right);
            if (temp->left != NULL)
                tn.push(temp->left);
            tn.push(temp); //放入访问过需要处理的根结点
            tn.push(NULL); //放入标记
        }
        else //遇到NULL表明其后面那个结点是需要处理的
        {
            temp = tn.top();           //将需要处理的结点取到
            tn.pop();                  //弹出
            ans.push_back(temp->data); //处理结点
        }
    }

    return ans;
}

vector<char> Inorder(TreeNode *root) //迭代中序
{
    vector<char> ans;
    stack<TreeNode *> tn;
    if (root != NULL)
        tn.push(root);
    while (!tn.empty())
    {
        TreeNode *temp = tn.top();
        tn.pop();
        if (temp != NULL)
        {
            //中序遍历,入栈顺序是右根左
            if (temp->right != NULL)
                tn.push(temp->right);
            tn.push(temp); //放入访问过需要处理的根结点
            tn.push(NULL); //放入标记
            if (temp->left != NULL)
                tn.push(temp->left);
        }
        else //遇到NULL表明其后面那个结点是需要处理的
        {
            temp = tn.top();           //将需要处理的结点取到
            tn.pop();                  //弹出
            ans.push_back(temp->data); //处理结点
        }
    }

    return ans;
}

vector<char> Postorder(TreeNode *root) //迭代后序null标记需要处理的结点
{
    vector<char> ans;
    stack<TreeNode *> tn;
    if (root != NULL)
        tn.push(root);
    while (!tn.empty())
    {
        TreeNode *temp = tn.top();
        tn.pop();
        if (temp != NULL)
        {
            //后序遍历,入栈顺序是根右左
            tn.push(temp); //放入访问过需要处理的根结点
            tn.push(NULL); //放入标记
            if (temp->right != NULL)
                tn.push(temp->right);
            if (temp->left != NULL)
                tn.push(temp->left);
        }
        else //遇到NULL表明其后面那个结点是需要处理的
        {
            temp = tn.top();           //将需要处理的结点取到
            tn.pop();                  //弹出
            ans.push_back(temp->data); //处理结点
        }
    }

    return ans;
}

5.二叉树的广度优先遍历

二叉树广度优先遍历,层次遍历

vector<char> Levelorder(TreeNode *root) //层次遍历
{
    vector<char> ans;
    queue<TreeNode *> tn;
    if (root != NULL)
        tn.push(root);
    while (!tn.empty())
    {
        int size = tn.size();
        for (int i = 0; i < size; i++)
        {
            TreeNode *temp = tn.front();
            tn.pop();
            ans.push_back(temp->data);//处理
            if (temp->left != NULL)
                tn.push(temp->left);
            if (temp->right != NULL)
                tn.push(temp->right);
        }
    }

    return ans;
}

6.赫夫曼树

内含资源如下: 1.基本数据结构 1.1.Array ........... 动态数组 1.2.LinkedList ... 链表 1.3.BST .............. 二分搜索 1.4.MapBST ..... 二分搜索(用于实现映射) 1.5.AVLTree ...... AVL 2.接口 2.1.Queue ........... 队列接口 2.2.Stack .............. 栈接口 2.3.Set .................. 集合接口 2.4.Map ............... 映射接口 2.5.Merger .......... 自定义函数接口 2.6.UnionFind ..... 并查集接口 3.高级数据结构 3.1.ArrayQueue .......................... 队列_基于动态数组实现 3.2.LinkedListQueue .................. 队列__基于链表实现 3.3.LoopQueue ........................... 循环队列_基于动态数组实现 3.4.PriorityQueue ....................... 优先队列_基于最大二叉堆实现 3.5.ArrayPriorityQueue ............. 优先队列_基于动态数组实现 3.6.LinkedListPriorityQueue ..... 优先队列_基于链表实现 3.7.ArrayStack ............................. 栈_基于动态数组实现 3.8.LinkedListStack ..................... 栈_基于链表实现 3.9.BSTSet ..................................... 集合_基于二分搜索实现 3.10.LinkedListSet ....................... 集合_基于链表实现 3.11.BSTMap ................................ 映射_基于二分搜索实现 3.12.AVLTreeMap ....................... 映射_ 基于AVL实现 3.13.LinkedListMap .................... 映射_基于链表实现 3.14.MaxHeap ............................. 最大二叉堆 3.15.SegmentTree ...................... 线段 3.16.Trie ......................................... 字典 3.17.QuickFind ............................ 并查集_基于数组实现 3.18.QuickUnion ......................... 并查集_基于思想实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值