天勤数据结构代码——树基本操作

 链式树

typedef struct BTNode {
    char data; //数据域
    struct BTNode *lchild;// 左指针域
    struct BTNode *rchild;// 右指针域
};

二叉排序树

typedef struct BTNode1 {
    int key; //关键字
    struct BTNode1 *lchild;// 左指针域
    struct BTNode1 *rchild;// 右指针域
};

线索树

typedef struct TBTNode {
    char data; //数据域
    int ltag, rtag;//线索标记,=0时则表示对应指针域为指针, =1表示对应指针域为线索,指向该结点的直接前驱(后继)
    struct TBTNode *lchild;// 左指针域
    struct TBTNode *rchild;// 右指针域
};

二叉树三种遍历

void Visit(BTNode *p) {
    //某种操作,例如输出等等,
}
void preorder(BTNode *p) { //先序遍历
    if (p != NULL) {
        Visit(p); // 某种操作
        preorder(p->lchild);
        preorder(p->rchild);
    }
}
void inorder(BTNode *p) { //中序遍历
    if (p != NULL) {
        inorder(p->lchild);
        Visit(p);
        inorder(p->rchild);
    }
}
void postorder(BTNode *p) { //后序遍历
    if (p != NULL) {
        postorder(p->lchild);
        postorder(p->rchild);
        Visit(p);
    }
}

求表达式(a-(b+c)*(d/e))存储在二叉链表为存储结构的二叉树中,求出该表达式的值

int op(int a, int b, char Op) { //运算函数 完成 a Op b 的运算
    if (Op == '+')
        return a + b;
    if (Op == '-')
        return a - b;
    if (Op == '*')
        return a * b;
    if (Op == '/') {
        if (b == 0) {    //被除数不能为0
            return 0;
        }
        else {
            return a / b;
        }
    }
}
int comp(BTNode *p) {  //仅使用于这一种算式
    int A, B;
    if (p != NULL) {
        if (p->lchild != NULL && p->rchild != NULL) { //左右子树都不为空
            /*后序遍历求其值*/
            A = comp(p->lchild);
            B = comp(p->rchild);
            return op(A, B, p->data);
        }
        else {
            return p->data - '0'; // 如果左右子树都为空,则为数值,直接返回对应数字 (因为定义时是char)

        }
    }
    return 0;  //空树,返回0;
}

计算二叉树的深度

int getDepth(BTNode *p) {
    int LD, RD;
    if (p == NULL) {
        return 0;
    }
    else {
        LD = getDepth(p->lchild);
        RD = getDepth(p->rchild);
        return (LD > RD ? LD : RD) + 1;
    }
}

查找二叉树中 值等于key的节点是否存在,若存在将p指向该节点,否则将q赋值为NULL,data为int型

typedef struct BTNode2 {
    int data; //数据域
    struct BTNode2 *lchild;// 左指针域
    struct BTNode2 *rchild;// 右指针域
};
/*假设二叉树已经存在,且p指向其根节点*/
void search(BTNode2 *p, BTNode2 *&q, int key) {
    if (p != NULL) {
        if (p->data == key) {
            q = p;
        }
        else {
            search(p->lchild, q, key);
            search(p->rchild, q, key);
        }
    }
}

假设二叉树采用二叉链表存储结构存储,编写一个程序输出先序(中序,后序)序列中第k个结点的值。

int n = 0; //全局变量
int trave(BTNode *p, int k) { //先序
    if (p != NULL) {
        ++n;
        if (k == n) {
            cout << p->data << endl;
            return 0;
        }
        trave(p->lchild,k);
        trave(p->rchild,k);
    }
}
int trave(BTNode *p, int k) {  //中序
    if (p != NULL) {
        trave(p->lchild, k);
        ++n;
        if (k == n) {
            cout << p->data << endl;
            return 0;
        }
        trave(p->rchild, k);
    }
}
int trave(BTNode *p, int k) {  //后序
    if (p != NULL) {
        trave(p->lchild, k);
        trave(p->rchild, k);
        ++n;
        if (k == n) {
            cout << p->data << endl;
            return 0;
        }
    }
}

层次遍历

void level(BTNode *p) {
    int front, rear; 
    BTNode *que[maxSize];  //定义一个循环队列,记录要访问的层次上的节点
    front = rear = 0;
    BTNode *q; 
    if (q != NULL) {
        rear = (rear + 1) % maxSize;
        que[rear] = p;  //根节点入队
        while (front != rear) {
            front = (front + 1) % maxSize;
            q = que[front];    //队头节点 出队
            Visit(p);
            if (q->lchild != NULL) {
                rear = (rear + 1) % maxSize;
                que[rear] = q->lchild;
            }
            if (q->rchild != NULL) {
                rear = (rear + 1) % maxSize;
                que[rear] = q->lchild;
            }
        }
    }
}

计算二叉树宽度

typedef struct St {
    BTNode *p;
    int lno;   //节点所在层号
};
int maxNode(BTNode *b) {
    St que[maxSize];    //定义顺序队列
    int front = 0, rear = 0; 
    int Lno,n,max;
    BTNode *q;
    if (b != NULL) {
        ++rear;
        que[rear].p = b;  //树根入队 
        que[rear].lno = 1; //层数为1
        while (front != rear) {
            ++front;
            q = que[front].p;
            Lno = que[front].lno;   //取当前节点 层号
            if (q->lchild != NULL) {
                ++rear;
                que[rear].p = q->lchild;
                que[rear].lno = Lno + 1;
            }
            if (q->rchild != NULL) {
                ++rear;
                que[rear].p = q->rchild;
                que[rear].lno = Lno + 1;
            }
        } //循环结束时,Lno 中保存的时这颗二叉树的最大层数(高度)
        max = 0;
        for (int i = 0; i < Lno; ++i) {
            n = 0;
            for (int j = 1; j <= rear; ++j) {
                if (que[j].lno == i) {
                    ++n;
                }
                if (max < n) {
                    max = n;
                }
            }
        }
        return max;
    }
    else
        return 0;
}

二叉树遍历的非递归算法(先,中,后)

void preorderNonrecursion(BTNode *bt) {  //先序遍历
    if (bt != NULL) {
        BTNode *Stack[maxSize]; 
        int top = -1;
        BTNode *p;
        Stack[++top] = bt;
        while (top != -1) {
            p = Stack[top--];
            Visit(p);
            if (p->rchild != NULL) {
                Stack[++top] = p->rchild;
            }
            if (p->lchild != NULL) {
                Stack[++top] = p->lchild;
            }
        }
    }
}
void inorderNonrecursion(BTNode *bt) { //中序遍历
    if (bt != NULL) {
        BTNode *Stack[maxSize];
        int top = -1;
        BTNode *p;
        p = bt;
        while (top != -1||p != NULL) {
            while (p != NULL) {
                Stack[++top] = p;
                p->lchild;
            }
            if (top != -1) {
                p = Stack[top--];
                Visit(p); 
                p = p->rchild;
            }
        }
    }
}
void postorderNonrecursion(BTNode *bt) { //后序遍历
    if (bt != NULL) {
        BTNode *Stack1[maxSize];
        int top1 = -1;
        BTNode *Stack2[maxSize];
        int top2 = -1;
        BTNode *p = NULL;
        Stack1[++top1] = bt;
        while (top1 != -1) {
            p = Stack1[top1--];
            Stack2[++top2] = p;
            if (p->lchild != NULL) {
                Stack1[++top1] = p->lchild;
            }
            if (p->rchild != NULL) {
                Stack2[++top1] = p->rchild;
            }
        }
        while (top2 != -1) {
            p = Stack2[top2--];
            Visit(p); 
        }
    }
}

根据先序和中序遍历构造出二叉树 

BTNode *CreateBT(char pre[], char in[], int l1, int r1, int l2, int r2) {
    BTNode *s;
    int i;
    if (l1 > r1) {   
        return NULL; 
    }
    BTNode *s = new BTNode;
    s->lchild = s->rchild = NULL;
    for (int i = l2; i < r2; i++) {  //查找等于当前子树根的节点再中序的位置
        if (in[i] == pre[l1]) {
            break;
        }
    }
    s->data = in[i]; 
    s->lchild = CreateBT(pre, in, l1 + 1, l1 + i - 12, 12, i - 1);
    s->rchild = CreateBT(pre, in, l1 + i - 12 + 1, r1, i + 1, r2);
    return s;
}

计算二叉树所有的节点数

int n = 0;    //非递归
void count(BTNode *p) {
    if (p != NULL) {
        ++n;
        count(p->lchild);
        count(p->rchild);
    }
}
int count2(BTNode *p) { //递归
    int n1, n2;
    if (p == NULL) {
        return 0;
    }
    else {
        n1 = count2(p->lchild);
        n2 = count2(p->rchild);
        return n1 + n2 + 1;
    }
}

计算二叉树的所有叶子节点数

int n = 0;    //非递归
void count3(BTNode *p) {
    if (p != NULL) {
        if (p->lchild == NULL && p->rchild == NULL) {
            ++n;
        }
        count3(p->lchild);
        count3(p->rchild);
    }
}
int count4(BTNode *p) { //递归
    int n1, n2;
    if (p == NULL) {
        return 0;
    }
    else if (p->lchild == NULL && p->rchild == NULL) {
        return 1;
    }
    else {
        n1 = count4(p->lchild);
        n2 = count4(p->rchild);
        return n1 + n2;
    }
}

利用节点的右孩子指针rchild 将一棵二叉树的叶子节点从左往右的顺序串成一个单链表(在题目中定义两个指针,head和tail,其中hear 指向第一个叶子节点,head初值为NUll,tail指向最后一个叶子节点)

void link(BTNode*p, BTNode*head, BTNode*&tail) {
    if (p != NULL) {
        if (p->lchild == NULL && p->rchild == NULL) {  //叶子节点
            if (head == NULL) {   //第一个节点,
                head = p;
                tail = p;
            }
            else {   //非第一个节点
                tail->rchild = p;
                tail = p;
            }
        }
        link(p->lchild, head, tail);
        link(p->rchild, head, tail);
    }
}

在二叉树的二叉链表存储结构中,增加一个指向双亲结点的parent指针,设计一个算法给这个指针赋值,并且输出所有节点到根节点的路径。

typedef struct BTNode3 {
    char data;
    struct BTNode3*parent;
    struct BTNode3*lchild;
    struct BTNode3*rchild; 
};
void triBtree(BTNode3*p, BTNode3 *q) {  //给parent赋值  p为根节点的时候,q应为NULL
    if (p != NULL) {
        p->parent = q; //当前所访问的节点的parent 指向q;
        q = p; 
        triBtree(p->lchild, q);
        triBtree(p->rchild, q);
    }
}
void printPath(BTNode3 *p) { //打印路径
    while (p != NULL) {
        cout << p->data << " " << endl;
        p->parent;
    }
}
void allPath(BTNode3 *p) { //打印所有路径
    if (p != NULL) {
        printPath(p);
        allPath(p->lchild);
        allPath(p->rchild);
    }
}

假设先序遍历序列储存在数组中,将其转变为后序遍历

void change(char pre[], int L1, int R1, char post[], int L2, int R2) {
    if (L1 <= R1) {
        post[R2] = pre[L1];   //将 pre的第一个元素放在post的末尾
        change(pre, L1 + 1, (L1 + 1 + R1) / 2, post, L2, (L2 + R2 - 1) / 2);
        change(pre, (L1 + 1 + R1) / 2 + 1, R1, post, (L2 + R2 - 1) / 2 + 1, R2 - 1);
    }
}

求二叉树中 值为x的节点的层号(高度)

int L = 1; //全局变量
void leno(BTNode *p, char x) {
    if (p != NULL) {
        if (p->data == x) {
            cout << L << endl;
        }
        ++L;  //去往下层 
        leno(p->lchild, x);
        leno(p->rchild, x);
        --L;  //回到上层
    }
}

双序遍历 (中左中右)

void Double_order(BTNode *t) {
    if (t != NULL) {
        Visit(t);
        Double_order(t->lchild);
        Visit(t);
        Double_order(t->rchild);
    }
}

输出根节点到所有结点的路径
 

int i;
int top = 0;
char pathstack[maxSize];
void allPath(BTNode *p) {
    if (p != NULL) {
        pathstack[top] = p->data;
        ++top;
        if (p->lchild == NULL && p->rchild == NULL) {  //叶子节点
            for (i = 0; i < top; ++i) {
                cout << pathstack[i];   //打印路径
            }
        }
        allPath(p->lchild);
        allPath(p->rchild);
        --top;
    }
}

 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值