二叉树

 创建一个二叉树

using namespace std;
//链式结构二叉树
#define END '#'//结束符  #代表空
typedef char  ElemType;

typedef struct BtNode//
{
    BtNode* leftchild;
    //BtNode* parent;
    BtNode* rightchild;
    ElemType data;
}BtNode, * BinaryTree;


BtNode* Buynode   //购买结点
{
    BtNode* s = (BtNode*)malloc(sizeof(BtNode));
    if (NULL == s) exit(1);
    memset(s, 0, sizeof(BtNode));
    return s;
}
//先序遍历  根左右
void PreOrder(BtNode* ptr)
{
    if (ptr != NULL)
    {
        printf("%c ", ptr->data);
        PreOrder(ptr->leftchild);
        PreOrder(ptr->rightchild);
    }
}
//中序遍历 左根右
void InOrder(BtNode* ptr)
{
    if (ptr != NULL)
    {
        InOrder(ptr->leftchild);
        printf("%c ", ptr->data);
        InOrder(ptr->rightchild);
    }
}
//后续遍历   左右根
void PastOrder(BtNode* ptr)
{
    if (ptr != NULL)
    {
        PastOrder(ptr->leftchild);
        PastOrder(ptr->rightchild);
        printf("%c ", ptr->data);
    }
}
//创建树
BtNode* CreateTree()
{
    ElemType ch;
    BtNode* s = NULL;
    cin >> ch;
    if (ch != END)
    {
        s = Buynode();
        s->data = ch;
        s->leftchild = CreateTree();
        s->rightchild = CreateTree();
    }
    return s;
}
int main()
{
    BinaryTree root = NULL;

    root = CreateTree();

    PreOrder(root);
    printf("\n");
    InOrder(root);
    printf("\n");
    PastOrder(root);
    printf("\n");
    return 0;
}

用先序和中序创建一个二叉树

//用中序序列寻找下标
int FindPos(const char* is, int n, ElemType val)
{
    int pos = -1;
    for (int i = 0; i < n; ++i)
    {
        if (is[i] == val)
        {
            pos = i;
            break;
        }
    }
    return pos;
}
//用先序序列创建
BtNode* CreatePI(const char* ps, const char* is, int n)
{
    BtNode* s = NULL;
    if (n > 0)
    {
        s = Buynode();
        s->data = ps[0];
        int pos = FindPos(is, n, ps[0]);
        if (pos == -1) exit(1);
        s->leftchild = CreatePI(ps + 1, is, pos);
        s->rightchild = CreatePI(ps + 1 + pos, is + 1 + pos, n - pos - 1);
    }
    return s;
}
//创建二叉树
BtNode* CreateBTreePI(const char* ps, const char* is, int n)
{
    if (ps == NULL || is == NULL || n < 1) return NULL;
    else return CreatePI(ps, is, n);
}
int main()
{
    const char ps[] = { "ABCDEFGH" };//先序遍历
    const char is[] = { "CBEDFAGH" };//中序遍历
    
    int n = strlen(is);

    BinaryTree root = NULL;
    root = CreateBTreePI(ps, is, n);//使用先序中序创建二叉树
    
    return 0;
}

用中序和后序创建一个二叉树

int FindPos(const char* is, int n, ElemType val)
{
    int pos = -1;
    for (int i = 0; i < n; ++i)
    {
        if (is[i] == val)
        {
            pos = i;
            break;
        }
    }
    return pos;
}
BtNode* CreateIP(const char* is, const char* ls, int n)
{
    BtNode* s = NULL;
    if (n > 0)
    {
        s = Buynode();
        s->data = ls[n - 1];
        int pos = FindPos(is, n, ls[n - 1]);
        s->leftchild = CreateIP(is, ls, pos);
        s->rightchild = CreateIP(is + pos + 1, ls + pos, n - pos - 1);
    }
    return s;
}
BtNode* CreateBTreeIP(const char* is, const char* ls, int n)
{
    if (is == NULL || ls == NULL || n < 1) return NULL;
    else return CreateIP(is, ls, n);
}
int main()
{
    
    const char is[] = { "CBEDFAGH" };//中序遍历
    const char ls[] = { "CEFDBHGA" };//后续遍历
    int n = strlen(is);

    BinaryTree root = NULL;
    
    root = CreateBTreeIP(is, ls, n);//使用中序和后续创建二叉树
    
    return 0;
}

非递归遍历规则

//非递归中序遍历   用栈   (先进后出)
void NiceInOrder(BtNode* ptr)
{
    if (ptr == NULL)  return;
    stack<BtNode*> st;
    while (ptr != NULL || !st.empty())
    {
        while (ptr != NULL)
        {
            st.push(ptr);//入栈
            ptr = ptr->leftchild;
        }

        ptr = st.top(); st.pop();//取栈顶元素
        cout << ptr->data << " ";//取ptr指向的值
        ptr = ptr->rightchild;//指向右孩子
    }
    cout << endl;
}
//非递归后续遍历规则
void NicePastOrder(BtNode* ptr)
{
    if (ptr == NULL)  return;
    stack<BtNode*> st;
    BtNode* tag = NULL;//标志位
    while (ptr != NULL || !st.empty())
    {
        while (ptr != NULL)
        {
            st.push(ptr);
            ptr = ptr->leftchild;
        }

        ptr = st.top(); st.pop();
        if (ptr->rightchild == NULL || ptr->rightchild == tag)
        {
            cout << ptr->data << " ";
            tag = ptr;//代表ptr被访问过
            ptr = NULL;
        }
        else
        {
            st.push(ptr);
            ptr = ptr->rightchild;
        }
    }
    cout << endl;
}
//前序遍历
void NicePreOrder(BtNode* ptr)
{
    if (ptr == NULL) return;
    stack<BtNode*> st;
    st.push(ptr);
    while (!st.empty())
    {
        ptr = st.top(); st.pop();
        cout << ptr->data << " ";
        if (ptr->rightchild != NULL)//先右后左入
        {
            st.push(ptr->rightchild);
        }
        if (ptr->leftchild != NULL)
        {
            st.push(ptr->leftchild);
        }
    }
    cout << endl;
}
//层次遍历
void NiceLevelOrder(BtNode* ptr)
{
    if (ptr == NULL) return;
    queue<BtNode*> st;
    st.push(ptr);
    while (!st.empty())
    {
        ptr = st.front(); st.pop();
        cout << ptr->data << " ";
        if (ptr->leftchild != NULL)
        {
            st.push(ptr->leftchild);
        }
        if (ptr->rightchild != NULL)
        {
            st.push(ptr->rightchild);
        }

    }
    cout << endl;
}
int main()
{
    const char ps[] = { "ABCDEFGH" };//先序遍历
    const char is[] = { "CBEDFAGH" };//中序遍历
    const char ls[] = { "CEFDBHGA" };//后续遍历
    int n = strlen(is);

    BinaryTree root = NULL;
    
    NicePreOrder(root);

    NiceInOrder(root);

    NicePastOrder(root);

    NiceLevelOrder(root);

    return 0;
}

 z字型打印(应使用一个栈一个队列)

//z字形打印
void PrintZ(BtNode* ptr)
{
    if (ptr == NULL)return;
    stack<BtNode*> sta;
    stack<BtNode*> stb;
    sta.push(ptr);
    while (!sta.empty() || !stb.empty())
    {
        while (!sta.empty())
        {
            ptr = sta.top(); sta.pop();
            cout << ptr->data << " ";
            if (ptr->rightchild != NULL)
            {
                stb.push(ptr->rightchild);
            }
            if (ptr->leftchild != NULL)
            {
                stb.push(ptr->leftchild);
            }
        }
        while (!stb.empty())
        {
            ptr = stb.top(); stb.pop();
            cout << ptr->data << " ";
            if (ptr->leftchild != NULL)
            {
                sta.push(ptr->leftchild);
            }
            if (ptr->rightchild != NULL)
            {
                sta.push(ptr->rightchild);
            }
        }
    }
    cout << endl;
}

如何验证二叉树为满二叉树

//满二叉树
bool IsFullBiTree(BtNode* ptr)
{
    if (ptr == NULL)return true;
    queue<BtNode*> qu;
    qu.push(ptr);
    int n = 1;
    while(!qu.empty())
    {
        if (n != qu.size())
        {
            res = false;
            break;
        }
        int i = 0;
        while (i < n && &!qu.empty())
        {
            int i = 0;
            while (i < n && !qu.empty())
            {
                ptr = qu.front(); qu.pop();
                ++i;
                if (ptr->leftchild != NULL) qu.push(ptr->leftchild);
                if (ptr->rightchild != NULL)qu.push(ptr->rightchild);
            }
            if (i < n)
            {
                res = false;
                break;
            }
            n += n;//n=n<<1
        }
        return res;
}

完全二叉树(每一层均达到最大值)

//完全二叉树(每一层都达到最大值)
bool IsComBinTree(BtNode* ptr)
{
    bool res = true;
    if (ptr == NULL)return res;
    queue<BtNode*> qu;
    while (!qu.empty())
    {
        ptr = qu.front(); qu.pop();
        if (ptr == NULL)break;
        qu.push(ptr->leftchild);
        qu.push(ptr->rightchild);
    }
    while (!qu.empty())
    {
        ptr = qu.front(); qu.pop();
        if (ptr != NULL)
        {
            res = false;
            break;
        }
    }
    return res;
}

中序遍历后变成为一个双向链表(左孩子当做前驱,右孩子当做后继)

BtNode  *NiceList(BtNode* ptr)
{
    if (ptr == NULL)  return NULL;
    BtNode* head = NULL;
    BtNode* pre = NULL;
    stack<BtNode*> st;
    while (ptr != NULL || !st.empty())
    {
        while (ptr != NULL)
        {
            st.push(ptr);//入栈
            ptr = ptr->leftchild;
        }

        ptr = st.top(); st.pop();//取栈顶元素
        if (head == NULL)
        {
            head = ptr;
            pre = ptr;
        }
        else
        {
            pre->rightchild = ptr;
            ptr->leftchild = pre;
        }
        ptr = ptr->rightchild;//指向右孩子
    }
head->leftchild=pre;
pre->rightchild=head;
return head; } int main() { const char ps[] = { "ABCDEFGH" };//先序遍历 const char is[] = { "CBEDFAGH" };//中序遍历 const char ls[] = { "CEFDBHGA" };//后续遍历 int n = strlen(is); BinaryTree root = NULL; root = NiceList(root);//中序化 return 0; }

 打印根到叶序列

//打印根到叶序列
void PrintfVec(BtNode* ptr, vector<char>& vec)//vec必须引用,保证后面保持不变
{
    if (ptr != NULL)
    {
        vec.push_back(ptr->data);
        PrintVec(ptr->leftchild, vec);
        PrintVec(ptr->rightchild, vec);
        if (ptr->leftchild == NULL && ptr->rightchild == NULL)
        {
            for (auto& x : vec)
            {
                cout << x << " ";
            }
            cout << endl;
        }
        vec.pop_back();
    }
}
int main()
{
    const char ps[] = { "ABCDEFGH" };//先序遍历
    const char is[] = { "CBEDFAGH" };//中序遍历
    const char ls[] = { "CEFDBHGA" };//后续遍历
    int n = strlen(is);

    BinaryTree root = NULL;
    
    root = CreateBTreeIP(is, ls, n);//
    vector<int> vec;
    PrintVec(root, vec);
    cout << endl;
    return 0;
}

 二叉树的最大路径之和

int MaxPath(BtNode* ptr, int& maxv)//最大路径,引用:每到最大值就把他记录下来
{
    if (ptr == NULL) return 0;
    int left = max(0, MaxPath(ptr->leftchild,maxv));
    int right = max(0, MaxPath(ptr->rightchild, maxv));
    maxv = max(maxv, left + ptr->data + right);//与左子树大小,根,右子树大小之和进行比较
    return max(0, max(left, right) + ptr->data);
}
int main()
{
    int pa[] = { -10,9,20,15,7 };
    int ia[] = { 9,-10,15,20,7 };
    int n = sizeof(pa) / sizeof(pa[0]);
    BinaryTree root = CreatePI(pa, ia, n);
    NiceInOrder(root);

    int maxv = INT_MIN;
    MaxPath(root, maxv);
    cout << maxv << endl;
    return 0;
}

二叉搜索树的建立

typedef int KeyType;
typedef struct BstNode
{
    struct BstNode* leftchild;
    //struct BstNode* parent;
    struct BstNode* rightchild;
    KeyType key;
}BstNode, * BSTree;


BstNode* Buynode()
{
    BstNode* s = (BstNode*)malloc(sizeof(BstNode));
    if (NULL == s) exit(1);
    memset(s, 0, sizeof(BstNode));
    return s;
}


BstNode* MakeRoot(KeyType kx)//购买根节点
{
    BstNode* s = Buynode();
    s->key = kx;
    return s;
}
//查询
BstNode* FindValue(BstNode* ptr, KeyType kx)
{
    if (ptr == NULL || ptr->key == kx)
    {
        return ptr;
    }
    else if (kx < ptr->key)
    {
        return FindValue(ptr->leftchild, kx);
    }
    else if (kx > ptr->key)
    {
        return FindValue(ptr->rightchild, kx);
    }
}
//插入
bool Insert(BstNode* &root, KeyType kx)
{
    if (root == NULL)
    {
        root = MakeRoot(kx);
        return true;
    }
    BstNode* pa = NULL;
    BstNode* p = root; //
    while (p != NULL && p->key != kx)
    {
        pa = p;
        p = kx < p->key ? p->leftchild : p->rightchild;
    }
    if (p != NULL && p->key == kx) return false;

    p = Buynode();
    p->key = kx;
    if (p->key > pa->key)
    {
        pa->rightchild = p;
    }
    else
    {
        pa->leftchild = p;
    }
    return true;
}
int main()
{
    BSTree root = NULL; // CreateTree();
    int val;
    while (cin >> val, val != -1)
    {
        Insert(root, val);
    }
    InOrder(root);
    cout << endl;
    cin >> val;
    BstNode* pos = FindValue(root, val);//二叉搜索树的查询

    return 0;
}

怎样建立一个左右子树高度差不超过一(以二分查询方式创建二叉树)

void InOrder(BstNode* ptr)
{
    if (ptr != NULL)
    {
        InOrder(ptr->leftchild);
        cout << ptr->key << " ";
        InOrder(ptr->rightchild);
    }
}
//递归二叉树
BstNode* CreateBST(const KeyType* ar, int left, int right)
{
    BstNode* s = NULL;
    if (left <= right)
    {
        int mid = (right + left) / 2;
        s = Buynode();
        s->key = ar[mid];
        s->leftchild = CreateBST(ar, left, mid - 1);
        s->rightchild = CreateBST(ar, mid + 1, right);
    }
    return s;
}
int main()
{
    int ar[] = { 12,23,34,45,56,67,78,89,90,100 };
    int n = sizeof(ar) / sizeof(ar[0]);

    BSTree root = CreateBST(ar, 0, n - 1);

    InOrder(root);
    cout << endl;


    return 0;
}

对数组里面存在的二叉树进行中序遍历

BstNode * ArInOrder(const int* ar, int i, int n)
{
    BstNode* s = NULL;
    if (i < n && ar[i] != -1)
    {
        cout << ar[i] << "  ";
        ArInOrder(ar, i * 2 + 1, n); // left
        ArInOrder(ar, i * 2 + 2, n);// right;
    }
    return s;
}
int main()
{
    int ar[] = { 31,23,12,66,-1,5,17,70,62,-1,-1,-1,88,-1,55 };
    int n = sizeof(ar) / sizeof(ar[0]);

    ArInOrder(ar, 0, n);

    return 0;
}

排序二叉树的删除(BST)

//删除
bool Remvoe(BstNode*& ptr, KeyType kx)     //指针的引用ptr可改变
{
    if (ptr == NULL) return false;
    BstNode* pa = NULL;
    BstNode* p = ptr;  // root;
    while (p != NULL && p->key != kx)
    {
        pa = p;
        p = kx < p->key ? p->leftchild : p->rightchild;
    }
    if (p == NULL) return false;
    if (p->leftchild != NULL && p->rightchild != NULL)
    {
        BstNode* q = p->rightchild;
        pa = p;
        while (q->leftchild != NULL)
        {
            pa = q;
            q = q->leftchild;
        }
        p->key = q->key;
        p = q;
    }
     //
    BstNode* child = p->leftchild != NULL ? p->leftchild : p->rightchild;
    if (pa == NULL)
    {
        ptr = child; //newroot;
    }
    else
    { 
        if (pa->leftchild == p)
        {
            pa->leftchild = child;
        }
        else
        {
            pa->rightchild = child;
        }
    }
    Freenode(p);
    return true;
}

int main()
{
    BSTree root = NULL;

    //

    Remove(root);

}

AVL树

一颗AVL树或者是空树,或者具有下列二叉搜索树:它的左子树和右子树都是AVL树,且左子树和右子树的高度之差的绝对值不超过1

AVL树的旋转

左单旋转

void RotateLeft(AVLNode*& ptr)
{
    AVLNode* newroot = ptr->rightchild;
    newroot->parent = ptr->parent; // 1  改变第一个双亲
    ptr->rightchild = newroot->leftchild;
    if (newroot->leftchild != NULL)
    {
        newroot->leftchild->parent  = ptr;      //2  改变第二个双亲
    }
    newroot->leftchild = ptr;
    ptr->parent = newroot;      // 3  改变第三个双亲
    ptr = newroot;
}

右单旋转

 

 

void RotateRight(AVLNode*& ptr)
{
    AVLNode* newroot = ptr->leftchild;
    newroot->parent = ptr->parent;
    ptr->leftchild = newroot->rightchild;
    if (newroot->rightchild != NULL)
    {
        newroot->rightchild->parent = ptr;
    }
    newroot->rightchild = ptr;
    ptr->parent = newroot;
    ptr = newroot;
}

先左后右双循环

对左边做平衡

对右边做平衡

 

//先左后右双循环
void LeftBalance(AVLNode*& ptr)
{
    AVLNode* leftsub = ptr->leftchild, * rightsub = NULL;
    switch (leftsub->balance)
    {
    case 0: cout << "left sub tree balance \n" << endl; break;//平衡
    case -1://进行右单旋
        ptr->balance = 0;
        leftsub->balance = 0;
        RotateRight(ptr);
        break;
    case 1:
        rightsub = leftsub->rightchild;
        switch (rightsub->balance)
        {
        case 0:
            ptr->balance = 0;
            leftsub->balance = 0;
            break;
        case 1: 
            ptr->balance = 0;
            leftsub->balance = -1;
            break;
        case -1:
            ptr->balance = 1;
            leftsub->balance = 0;
            break;
        }
        rightsub->balance = 0;
        RotateLeft(ptr->leftchild);
        RotateRight(ptr);
        break;
    }
}
void RightBalance(AVLNode*& ptr)
{
    AVLNode* rightsub = ptr->rightchild, * leftsub = NULL;
    switch (rightsub->balance)
    {
    case 0: cout << "right sub balance " << endl; break;
    case 1:
        ptr->balance = 0;
        rightsub->balance = 0;
        RotateLeft(ptr);
        break;
    case -1:
        leftsub = rightsub->leftchild;
        switch (leftsub->balance)
        {
        case 0: 
            ptr->balance = 0;
            rightsub->balance = 0;
            break;
        case 1:
            ptr->balance = -1;
            rightsub->balance = 0;
            break;
        case -1: 
            ptr->balance = 0;
            rightsub->balance = 1;
            break;
        }
        leftsub->balance = 0;
        RotateRight(ptr->rightchild);
        RotateLeft(ptr);
        break;
    }
}
void Adjust(AVLNode* child)
{
    AVLNode* pa = child->parent;
    bool tall = true;
    while (tall && pa != NULL)
    {
        if (pa->leftchild == child)
        {
            switch (pa->balance)
            {
            case 0: pa->balance = -1; break;
            case 1: pa->balance = 0;
                tall = false;
                break;
            case -1: 
                LeftBalance(pa);
                tall = false;
                break;
            }
        }
        else
        {
            switch (pa->balance)
            {
            case 0: pa->balance = 1; break;
            case -1: 
                pa->balance = 0;
                tall = false;
                break;
            case 1:
                RightBalance(pa);
                tall = false;
                break;
            }

        }

        child = pa;
        pa = child->parent;
    }
}
bool InsertItem(AVLNode*& root,KeyType kx)
{
    if (root == NULL)
    {
        root = MakeRoot(kx);
        return true;
    }
    //
    //
    Adjust(p);
}

int main()
{
    return 0;
}

红黑树

 

 

红黑树的插入和调整

typedef enum { RED = 0, BLACK = 1 } ColorType;
typedef int KeyType;

typedef struct rb_node
{
    struct rb_node* leftchild;
    struct rb_node* parent;
    struct rb_node* rightchild;
    ColorType color;  // 0 1
    KeyType key;
}rb_node;

typedef struct
{
    rb_node* head;
    rb_node* _Nil;
    int cursize;//数据结点个数
}RBTree;

rb_node* Buynode(ColorType color = RED)
{
    rb_node* s = (rb_node*)malloc(sizeof(rb_node));
    if (NULL == s) exit(1);
    memset(s, 0, sizeof(rb_node));
    s->color = RED;
    return s;

}
void InitRBTree(RBTree* ptree)
{
    assert(ptree != NULL);

    ptree->cursize = 0;
    ptree->head = Buynode();
    ptree->_Nil = Buynode(BLACK);
    ptree->head->parent = ptree->_Nil;
}

//插入(带头结点和哨兵结点)
   //左旋
void RotateLeft(RBTree* ptree, rb_node * ptr)
{
    rb_node* newroot = ptr->rightchild;
    newroot->parent = ptr->parent; // 1
    ptr->rightchild = newroot->leftchild;
    if (newroot->leftchild != ptree->_Nil)
    {
        newroot->leftchild->parent = ptr; // 2
    }
    newroot->leftchild = ptr;
    if (ptr->parent == ptree->head)
    {
        ptree->head->parent  = newroot;
    }
    else
    {
        if (ptr->parent->rightchild == ptr)
        {
            ptr->parent->rightchild = newroot;
        }
        else
        {
            ptr->parent->leftchild = newroot;
        }
    }
    ptr->parent = newroot; // 3
}
//右旋
void RotateRight(RBTree* ptree, rb_node* ptr)
{
    rb_node* newroot = ptr->leftchild;

    newroot->parent = ptr->parent; //1
    ptr->leftchild = newroot->rightchild;
    if (newroot->rightchild != ptree->_Nil)//如果不是一个哨兵结点
    {
        newroot->rightchild->parent = ptr;
    }
    newroot->rightchild = ptr;

    if (ptr->parent == ptree->head)
    {
        ptree->head->parent = newroot;
    }
    else
    {
        if (ptr->parent->leftchild == ptr)
        {
            ptr->parent->leftchild = newroot;
        }
        else
        {
            ptr->parent->rightchild = newroot;
        }

    }
    ptr->parent = newroot;

}
//调整 
void Adjust(RBTree *ptree, rb_node *p)
{
    rb_node* pa = p->parent;

    while (pa != ptree->head->parent && pa->color == RED)   //  ?
    {
        if (p->parent->parent->rightchild == p->parent)  // right
        {
            rb_node *_Y = p->parent->parent->leftchild;
            if (_Y->color == RED)
            {
                _Y->color = BLACK;
                p->parent->color = BLACK;
                p->parent->parent->color = RED;
                p = p->parent->parent;
            }
            else
            {

                if (p->parent->leftchild == p)
                {
                    p = p->parent;
                    RotateRight(ptree, p);
                }
                p->parent->color = BLACK;
                p->parent->parent->color = RED;
                RotateLeft(ptree, p->parent->parent);
            }
        }
        else   //left
        {
            rb_node* _Y = p->parent->parent->rightchild;
            if (_Y->color == RED)
            {
                _Y->color = BLACK;
                p->parent->color = BLACK;
                p->parent->parent->color = RED;
                p = p->parent->parent;
            }
            else
            {

                if (p->parent->rightchild == p)
                {
                    p = p->parent;
                    RotateLeft(ptree, p);
                }
                p->parent->color = BLACK;
                p->parent->parent->color = RED;
                RotateRight(ptree, p->parent->parent);
            }
        }
        pa = p->parent;
    }
    ptree->head->parent->color = BLACK;
}
void InsertItem(RBTree* ptree)
{
    Adjust(ptree, p);
}
    
int main()
{
    RBTree myt;
    InitRBTree(&myt);
}

 

posted @ 2021-08-26 18:29  阿拉佩丫  阅读(47)  评论(0)    收藏  举报