树(C语言)

顺序存储结构

typedef struct BNode {
    int data;
    struct BNode* Ichild, * rchild;
}BNode,*BTree;

遍历二叉树

1.先序
创建
void create(BTree& T) {
    char ch;
    scanf_s(&ch);
    if (ch == '#') {
        T = NULL;
    }
    else {
        T->data = ch;
        create(T->lchild);
        create(T->rchild);
    }
}

输出

法1:

void preorder(BTree T) {
    if (T == NULL) {
        cout << "空" << endl;
    }
else {
        cout << T->data;
        preorder(T->lchild);
        preorder(T->rchild);
    }
}

法2:

void pre(BTree T) {
    if (T != NULL) {
        cout << T->data;
        pre(T->lchild);
        pre(T->rchild);
    }
}

2.中序
void inorder(BTree T) {
    if (T == NULL) {
        cout << "空" << endl;
    }
    else {
        inorder(T->lchild);
        cout << T->data;
        inorder(T->rchild);
    }
}

3.后序
void post(BTree T) {
    if (T == NULL) {
        cout << "空" << endl;
    }
    else {
        post(T->lchild);
        post(T->rchild);
        cout << T->data;
    }
}

4.层次
//加上<malloc.h>头文件
​
BTree create(){
    int data,maxsize;
    BTree BT,T;
    Queue Q=init(maxsize);
    scanf("%d",&data);
    if(data!=noinfo){
        BT=(BTree)malloc(sizeof(BNode));
        BT->data=data;
        BT->lchild=BT->rchild=NULL;
        Add(Q,BT);
    }
    else return NULL;
    while(!isempty(Q)){
        T=Delete(Q);
        scanf("%d",&data);
        if(data==noinfo){
            T->lchild=NULL;
        }
        else{
            T->lchild=(BTree)malloc(sizeof(BNode));
            T->lchild->data=data;
            T->lchild->lchild=T->lchild->rchild=NULL;
            Add(Q,T->lchild);
        }
        scanf("%d",&data);
        if(data==noinfo){
            T->rchild=NULL;
        }
        else{
            T->rchild=(BTree)malloc(sizeof(BNode));
            T->rchild->data=data;
            T->rchild->lchild=T->rchild->rchild=NULL;
            Add(Q,T->rchild);
        }
    }
    return BT;
}

链式存储结构

typedef struct TNode {
    int data;
    struct INode* lchild, * parent, * rchild;
}TNode,*TTree;

创建二叉链表(空子节点表示为#)

void create(BTree& T) {
    char ch;
    scanf(“%c",&ch);
    if (ch == '#') {
        T = NULL;
    }
    else {
        T->data = ch;
        create(T->lchild);
        create(T->rchild);
    }
}

复制二叉树

int copy(BTree T, BTree& newT) {
    if (T == NULL) {
        newT = NULL;
        return 0;
    }
    else {
        newT = new BNode;
        newT->data = T->data;
        copy(T->lchild, newT->lchild);
        copy(T->rchild, newT->rchild);
    }
}

计算二叉树深度

int depth(BTree T) {
    if (T == NULL) {
        return 0;
    }
    else {
        int m = depth(T->lchild);
        int n = depth(T->rchild);
        if (m > n) {
            return m + 1;
        }
        else {
            return n + 1;
        }
    }
}

计算二叉树结点总数

int nodecount(BTree T) {
    if (T == NULL) {
        return 0;
    }
    else {
        return nodecount(T->lchild) + nodecount(T->rchild) + 1;
    }
}

计算二叉树叶子结点总数

int leafcount(BTree T) {
    if (T == NULL) {
        return 0;
    }
    if (T->lchild == NULL && T->rchild == NULL) {
        return 1;
    }
    else {
        return leafcount(T->lchild) + leafcount(T->rchild);
    }
}

二叉搜索树

动态查找(递归法)

int find(int x,BTree BT){
    if(!BT){
        return NULL;
    }
    if(x>BT->data){
        return find(x,BT->rchild);
    }
    else if(x<BT->data){
        return find(x,BT->lchild);
    }
    else{
        return BT->data;
    }
}

动态查找(非递归法)

int find(int x,BTree BT){
    while(BT){
        if(x>BT->data){
            BT=BT->rchild;
        }
        else if(x<BT->data){
            BT=BT->lchild;
        }
        else{
            break;
        }
    }
    return BT->data;
}

插入元素

BTree insert(BTree BT,int x){
    if(!BT){
        BT=(BTree)malloc(sizeof(BNode));
        BT->data=x;
        BT->lchild=BT->rchild=NULL;
    }
    else{
        if(x<BT->data){
            BT->lchild=insert(BT->lchild,x);
        }
        else if(x>BT->data){
            BT->rchild=insert(BT->rchild,x);
        }
    }
    return BT;
}

查找最小值

BTree findmin(BTree BT){
    if(!BT){
        return NULL;
    }
    else if(!BT->lchild){
        BT=BT->lchild;
    }
    return BT;
}

查找最大值

BTree findmax(BTree BT){
    if(!BT){
        return NULL;
    }
    else if(!BT->rchild){
        BT=BT->rchild;
    }
    return BT;
}

删除节点

BTree Delete(BTree BT,int x){
    BTree temp;
    if(!BT){
        printf("未找到删除元素");
    }
    else{
        if(x<BT->data){
            BT->lchild=Delete(BT->lchild,x);
        } 
        else if(x>BT->data){
            BT->rchild=Delete(BT->rchild,x);
        }
        else{
            if(BT->lchild&&BT->rchild){
                temp=findmin(BT->rchild);
                BT->data=temp->data;
                BT->rchild=Delete(BT->rchild,BT->data);
            }
            else{
                temp=BT;
                if(!BT->lchild){
                    BT=BT->rchild;
                }
                else{
                    BT=BT->lchild;
                }
                free(temp);
            }
        }
    }
    return BT;
}

平衡二叉树

插入操作
typedef struct AVLNode{
    int data;
    struct AVLNode* Left;
    struct AVLNode* Right;
    int Height;
}AVLNode,*AVLTree;
 int max(int a,int b){
    return a>b? a:b;
 }
 int GetHeight(AVLTree T){
    if(T==NULL){
        return 0;
    }
    else{
        int m=GetHeight(T->Left);
        int n=GetHeight(T->Right);
        if(m>n){
            return m+1;
        }
        else{
            return n+1;
        }
    }
}
AVLTree LeftRotation(AVLTree A){
    AVLTree B=A->Left;
    A->Left=B->Right;
    B->Right=A;
    A->Height=max(GetHeight(A->Left),GetHeight(A->Right))+1;
    B->Height=max(GetHeight(B->Left),A->Height)+1;
    return B; 
}
AVLTree RightRotation(AVLTree A){
    AVLTree B=A->Right;
    A->Right=B->Left;
    B->Left=A;
    A->Height=max(GetHeight(A->Left),GetHeight(A->Right))+1;
    B->Height=max(GetHeight(B->Left),A->Height)+1;
    return B; 
}
AVLTree DoubleLeftRightRotation(AVLTree A){
    A->Left=RightRotation(A->Left);
    return LeftRotation(A);
}
 AVLTree insert(AVLTree T,int x){
    if(!T){
        T=(AVLTree)malloc(sizeof(struct AVLNode));
        T->data=x;
        T->Height=1;
        T->Left=T->Right=NULL;
    }
    else if(x<T->data){
        T->Left=insert(T->Left,x);
        if(GetHeight(T->Left)-GetHeight(T->Right)==2){
            if(x<T->Left->data){
                T=LeftRotation(T);
            }
            else{
                T=DoubleLeftRightRotation(T);
            }
        }
    }
    else if(x>T->data){
        T->Right=insert(T->Right,x);
        if(GetHeight(T->Left)-GetHeight(T->Right)==-2){
            if(x>T->Right->data){
                T=RightRotation(T);
            }
            else{
                T=DoubleLeftRightRotation(T);
            }
        }
    }
    T->Height=max(GetHeight(T->Left),GetHeight(T->Right))+1;
    return T;
 }

左单旋算法
AVLTree LeftRotation(AVLTree A){
    AVLTree B=A->Left;
    A->Left=B->Right;
    B->Right=A;
    A->Height=max(GetHeight(A->Left),GetHeight(A->Right))+1;
    B->Height=max(GetHeight(B->Left),A->Height)+1;
    return B; 
}

右单旋算法
AVLTree RightRotation(AVLTree A){
    AVLTree B=A->Right;
    A->Right=B->Left;
    B->Left=A;
    A->Height=max(GetHeight(A->Left),GetHeight(A->Right))+1;
    B->Height=max(GetHeight(B->Left),A->Height)+1;
    return B; 
}

左右双旋算法
AVLTree DoubleLeftRightRotation(AVLTree A){
    A->Left=RightRotation(A->Left);
    return LeftRotation(A);
}

线索二叉树

结构

typedef struct BTNode {
    int data;
    int ltag, rtag;
    struct BTNode* lchild, * rchild;
}BTNode,*BTTree;

森林

结构

typedef struct PTNode {
    int data;
    int parent;
}PTNode;
#define max 100
typedef struct {
    PTNode nodes[max];
    int r, n;
}PTree;

树转化为二叉树

1.加线:兄弟之间加连线

2.抹线:对每个节点,除了左孩子,去除与其他孩子之间的关系

(兄弟相连留长子)

森林转化为二叉树

1.每棵树转化为二叉树

2.每棵树的根节点用线相连

3.第一棵树根节点为二叉树的根,一根节点为轴心,顺时针旋转

(树变二叉根相连)

二叉树转化成森林

1.抹线:二叉树根节点与其右孩子连线,及沿右分支搜索到的所有右孩子间的连线全部抹掉,使之变成孤立的二叉树

2.还原:将孤立的二叉树还原成树

(去掉全部右孩线,孤立二叉再还原)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值