王道数据结构代码——二叉树

1. 计算二叉树高度

#include<iostream>
 
using namespace std;
 
typedef char ElemType;
 
typedef struct BiTNode{
    ElemType data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
 
bool InitBiTree(BiTree& T); //初始化
int treeDepth(BiTree T);   //计算树的深度
 
bool InitBiTree(BiTree& T){
    ElemType ch;
    cin>>ch;
    if(ch=='#'){
        T = NULL;
    }else{
        T = (BiTNode*)malloc(sizeof(BiTNode));
        T->data = ch;
        InitBiTree(T->lchild);
        InitBiTree(T->rchild);
    }
}
 
int treeDepth(BiTree T){
    if(T==NULL) return 0;
    int l = treeDepth(T->lchild);
    int r = treeDepth(T->rchild);
    return l>r?l+1:r+1;
}

int main(){


	return 0;
}

2. 二叉树的先序,中序,后序遍历(递归)

#include<iostream>
 
using namespace std;
 
typedef char ElemType;
 
typedef struct BiTNode{
    ElemType data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
 
bool InitBiTree(BiTree& T); //初始化
void visit(BiTNode* p);     //打印节点信息
void PreOrder(BiTree T);    //先序遍历
void InOrder(BiTree T);     //中序遍历
void PostOrder(BiTree T);   //后序遍历
 
bool InitBiTree(BiTree& T){
    ElemType ch;
    cin>>ch;
    if(ch=='#'){
        T = NULL;
    }else{
        T = (BiTNode*)malloc(sizeof(BiTNode));
        T->data = ch;
        InitBiTree(T->lchild);
        InitBiTree(T->rchild);
    }
}
 
void visit(BiTNode* p){
    cout<<p->data<<" ";
}
 
void PreOrder(BiTree T){
    if(T==NULL) return ;
    visit(T);
    PreOrder(T->lchild);
    PreOrder(T->rchild);
}
 
void InOrder(BiTree T){
    if(T==NULL) return ;
    InOrder(T->lchild);
    visit(T);
    InOrder(T->rchild);
}
 
void PostOrder(BiTree T){
    if(T==NULL) return ;
    PostOrder(T->lchild);
    PostOrder(T->rchild);
    visit(T);
}

int main(){


	return 0;
}

3. 二叉树的先序,中序,后序遍历(非递归)

#include<iostream>
 
using namespace std;
 
typedef struct BiTNode{
    char data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
 
typedef struct LinkNode {
	BiTNode *data;
	struct LinkNode* next;
}*LiStack,LinkNode;
 
 
bool InitStack(LiStack& S);
bool StackEmpty(LiStack S);
bool Push(LiStack& S, BiTNode* x);
bool Pop(LiStack& S, BiTNode*& x);
bool GetTop(LiStack S, BiTNode*& x);
bool DestoryStack(LiStack& S);
 
bool InitBiTree(BiTree& T); //初始化
void visit(BiTNode* p);     //打印节点信息
 
void PostOrder(BiTree T);   //后序遍历
void InOrder(BiTree T);     //先序遍历
void PreOrder(BiTree T);    //前序遍历
 
bool InitStack(LiStack& S) {
	S = (LiStack)malloc(sizeof(LinkNode));
	if (S == NULL) return false;
	S->next = NULL;
	return true;
}
 
bool StackEmpty(LiStack S) {
	if (S->next == NULL) return true;
	return false;
}
 
bool Push(LiStack& S, BiTNode* x) {
	LinkNode* p;
	p = (LinkNode*)malloc(sizeof(LinkNode));
	if (p == NULL) return false;
	p->data = x;
	p->next = S->next;
	S->next = p;
	return true;
}
 
bool Pop(LiStack& S, BiTNode*& x) {
	if (StackEmpty(S)) return false;
	LinkNode* p = S->next;
	S->next = p->next;
	x = p->data;
	free(p);
	return true;
}
 
bool GetTop(LiStack S, BiTNode*& x) {
	if (StackEmpty(S)) return false;
	x = S->next->data;
	return true;
}
 
bool InitBiTree(BiTree& T){
    char ch;
    cin>>ch;
    if(ch=='#'){
        T = NULL;
    }else{
        T = (BiTNode*)malloc(sizeof(BiTNode));
        T->data = ch;
        InitBiTree(T->lchild);
        InitBiTree(T->rchild);
    }
}
 
 
void visit(BiTNode* p){
    cout<<p->data<<" ";
}
 
 
void PostOrder(BiTree T){
    LiStack S;
    InitStack(S);
    BiTree p = T;
    BiTNode *r = NULL;   //辅助指针,指向最近访问的节点
    while(p||!StackEmpty(S)){
        if(p){                              //走到最左边
            Push(S,p);
            p = p->lchild;
        }else{                              //走到最右边
            GetTop(S,p);                    //读栈顶元素(非出栈)
            if(p->rchild&&p->rchild!=r){    //若右子树存在且未被访问过
                p = p->rchild;              //转向右
                Push(S,p);                  //压入栈
                p = p->lchild;              //再走到最左
            }else{                          //否则弹出栈顶元素并访问
                Pop(S,p);
                visit(p);
                r = p;                      //记录最近访问过的节点
                p = NULL;                   //节点访问完后重置p指针
            }
        }
    }
}
 
void InOrder(BiTree T){
    LiStack S;
    InitStack(S);
    BiTree p = T;               //遍历指针
    while(p||!StackEmpty(S)){   //
        if(p){                  //一路向左
            Push(S,p);          //当前节点入栈
            p = p->lchild;      //左孩子不为空一直向左走
        }else{                  //出栈,并转向该节点的右孩子
            Pop(S,p);           //栈顶结点出栈,访问
            visit(p);
            p = p->rchild;      //向右子树走,
        }
    }
}
 
void PreOrder(BiTree T){
    LiStack S;
    InitStack(S);
    BiTree p = T;               //遍历指针
    while(p||!StackEmpty(S)){   //
        if(p){                  //一路向左
            visit(p);
            Push(S,p);          //当前节点入栈
            p = p->lchild;      //左孩子不为空一直向左走
        }else{                  //出栈,并转向该节点的右孩子
            Pop(S,p);           //栈顶结点出栈
            p = p->rchild;      //向右子树走,
        }
    }
}
 
int main(){
 
    return 0;
}

4. 二叉树的层序遍历

#include<iostream>
 
using namespace std;
 
typedef char ElemType;
 
typedef struct BiTNode{
    ElemType data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
 
 
typedef struct LinkNode {
	BiTNode* data;
	struct LinkNode* next;
}LinkNode;
 
typedef struct {
	LinkNode* front, * rear;
}LinkQueue;
 
 
bool InitBiTree(BiTree& T); //初始化树
void LevelOrder(BiTree T);  //层序遍历
void InitQueue(LinkQueue& Q);
bool QueueEmpty(LinkQueue Q);
bool EnQueue(LinkQueue& Q, BiTNode* x);
bool DeQueue(LinkQueue& Q, BiTNode*& x);
void visit(BiTNode* p);
 
void InitQueue(LinkQueue& Q) {
	Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
	Q.front->next = NULL;
}
 
bool QueueEmpty(LinkQueue Q) {
	if (Q.front == Q.rear) return true;
	return false;
}
 
bool EnQueue(LinkQueue& Q, BiTNode* x) {
	LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
	s->data = x;
	s->next = Q.rear->next;
	Q.rear->next = s;
	Q.rear = s;
	return true;
}
 
bool DeQueue(LinkQueue& Q, BiTNode*& x) {
	if (QueueEmpty(Q)) return false;
	LinkNode* q = Q.front->next;
	x = q->data;
	Q.front->next = q->next;
	if (Q.rear == q) {
		Q.rear = Q.front;
	}
	free(q);
	return true;
}
 
bool InitBiTree(BiTree& T){
    ElemType ch;
    cin>>ch;
    if(ch=='#'){
        T = NULL;
    }else{
        T = (BiTNode*)malloc(sizeof(BiTNode));
        T->data = ch;
        InitBiTree(T->lchild);
        InitBiTree(T->rchild);
    }
}
 
void LevelOrder(BiTree T){
    LinkQueue Q;
    InitQueue(Q);
    BiTree p;
    EnQueue(Q,T);
    while(!QueueEmpty(Q)){
        DeQueue(Q,p);
        visit(p);
        if(p->lchild!=NULL){
            EnQueue(Q,p->lchild);
        }
        if(p->rchild!=NULL){
            EnQueue(Q,p->rchild);
        }
    }
}
 
void visit(BiTNode* p){
    cout<<p->data<<" ";
}
 
int main(){
 
    
    return 0;
}

5. 中序线索化二叉树

#include<iostream>
 
using namespace std;
 
typedef char ElemType;
 
typedef struct ThreadNode{
    ElemType data;
    struct ThreadNode *lchild,*rchild;
    int ltag,rtag;
}ThreadNode,*ThreadTree;
 
ThreadNode *pre;    //指向当前访问节点的前驱
 
 
void InitTree(ThreadTree& T);//初始化树
void visit(ThreadNode* q);
void InThread(ThreadTree T);//中序遍历二叉树,
void CreatInThread(ThreadTree T);//建立中序线索化二叉树
 
/*--------------------------*/
/*中序线索二叉树中找中序后继*/
ThreadNode* Firstnode(ThreadNode* p);//找中序线索二叉树中中序序列下的第一个节点
ThreadNode* Nextnode(ThreadNode* p);//找中序线索二叉树中节点p在中序序列下的后继
void Inorder(ThreadTree T);//遍历线索二叉树
/*--------------------------*/
 
/*--------------------------*/
/*中序线索二叉树中找中序前驱*/
ThreadNode* Lastnode(ThreadNode* p);//找到以p为根的子树中,最后一个被中序遍历的节点
ThreadNode* Prenode(ThreadNode* p);//在中序线索二叉树中找到节点p的前驱节点
void RevInorder(ThreadTree T);//逆向遍历线索二叉树
/*--------------------------*/
 
//初始化树
void InitTree(ThreadTree& T){
    ElemType ch;
    cin>>ch;
    if(ch=='#'){
        T = NULL;
    }else{
        T = (ThreadNode*)malloc(sizeof(ThreadNode));
        T->data = ch;
        T->ltag = 0;
        T->rtag = 0;
        InitTree(T->lchild);
        InitTree(T->rchild);
    }
 
}
 
void visit(ThreadNode* q){
    if(q->lchild==NULL){        //左子树为空,建立前驱线索
        q->lchild = pre;
        q->ltag =1;
    }
    if(pre!=NULL && pre->rchild == NULL){     //建立前驱节点的后续线索
        pre->rchild = q;
        pre->rtag = 1;
    }
    pre = q;
}
 
//中序遍历二叉树,
void InThread(ThreadTree T){
    if(T!=NULL){
        InThread(T->lchild);
        visit(T);
        InThread(T->rchild);
    }
}
 
//建立中序线索化二叉树
void CreatInThread(ThreadTree T){
    pre = NULL;
    if(T!=NULL){
        InThread(T);            //中序线索化二叉树
        if(pre->rchild == NULL){
            pre->rtag = 1;      //处理遍历的最后一个节点
        }
    }
}
 
/*--------------------------*/
/*中序线索二叉树中找中序后继*/
 
 
//找中序线索二叉树中中序序列下的第一个节点
ThreadNode* Firstnode(ThreadNode* p){
    while(p->ltag==0) p = p->lchild;           //最左下节点(不一定是叶节点)
    return p;
}
 
//找中序线索二叉树中节点p在中序序列下的后继
ThreadNode* Nextnode(ThreadNode* p){
    if(p->rtag == 0) return Firstnode(p->rchild);
    return p->rchild;   //rtag==1直接返回后继线索
}
 
//遍历线索二叉树
void Inorder(ThreadTree T){
    for(ThreadNode* p=Firstnode(T);p!=NULL;p = Nextnode(p)){
        cout<<p->data<<" ";
    }
    cout<<endl;
}
 
 
/*--------------------------*/
 
 
 
/*--------------------------*/
/*中序线索二叉树中找中序前驱*/
 
//找到以p为根的子树中,最后一个被中序遍历的节点
ThreadNode* Lastnode(ThreadNode* p){
    //循环找到最右下节点(不一定是叶节点)
    while(p->rtag == 0) p = p->rchild;
    return p;
}
 
//在中序线索二叉树中找到节点p的前驱节点
ThreadNode* Prenode(ThreadNode* p){
    //左子树中最右下节点
    if(p->ltag == 0) return Lastnode(p->lchild);
    return p->lchild;   //ltag==1直接返回前驱
}
 
//逆向遍历线索二叉树
void RevInorder(ThreadTree T){
    for(ThreadNode* p = Lastnode(T);p!=NULL;p = Prenode(p)){
        cout<<p->data<<" ";
    }
    cout<<endl;
}
/*--------------------------*/
  
int main(){
 
    
    return 0;
}

6. 先序线索化二叉树

#include<iostream>
 
using namespace std;
 
typedef char ElemType;
 
typedef struct ThreadNode{
    ElemType data;
    struct ThreadNode *lchild,*rchild;
    int ltag,rtag;
}ThreadNode,*ThreadTree;
 
ThreadNode *pre;    //指向当前访问节点的前驱
 
 
void InitTree(ThreadTree& T);//初始化树
void visit(ThreadNode* q);
void PreThread(ThreadTree T);//先序遍历二叉树,
void CreatInThread(ThreadTree T);//建立先序线索化二叉树
 
/*--------------------------*/
/*先序线索二叉树中找先序后继*/
ThreadNode* Firstnode(ThreadNode* p);//找先序线索二叉树中先序序列下的第一个节点
ThreadNode* Nextnode(ThreadNode* p);//找先序线索二叉树中节点p在先序序列下的后继
void Preorder(ThreadTree T);//遍历线索二叉树
/*--------------------------*/
 
 
//初始化树
void InitTree(ThreadTree& T){
    ElemType ch;
    cin>>ch;
    if(ch=='#'){
        T = NULL;
    }else{
        T = (ThreadNode*)malloc(sizeof(ThreadNode));
        T->data = ch;
        T->ltag = 0;
        T->rtag = 0;
        InitTree(T->lchild);
        InitTree(T->rchild);
    }
 
}
 
void visit(ThreadNode* q){
    if(q->lchild==NULL){        //左子树为空,建立前驱线索
        q->lchild = pre;
        q->ltag =1;
    }
    if(pre!=NULL && pre->rchild == NULL){     //建立前驱节点的后续线索
        pre->rchild = q;
        pre->rtag = 1;
    }
    pre = q;
}
 
//先序遍历二叉树,
void PreThread(ThreadTree T){
    if(T!=NULL){
        visit(T);
        if(T->ltag!=1)  //lchild不是前驱节点
            PreThread(T->lchild);
        if(T->rtag!=1)  //rchild不是后驱节点,因为回溯回来可能造成死循环
            PreThread(T->rchild);
    }
}
 
//建立先序线索化二叉树
void CreatInThread(ThreadTree T){
    pre = NULL;
    if(T!=NULL){
        PreThread(T);            //先序线索化二叉树
        if(pre->rchild == NULL){
            pre->rtag = 1;      //处理遍历的最后一个节点
        }
    }
}
 
/*--------------------------*/
/*先序线索二叉树中找先序后继*/
 
 
//找先序线索二叉树中节点p在先序序列下的后继
ThreadNode* Nextnode(ThreadNode* p){
    if(p->rtag == 0){
        if(p->lchild!=NULL) return p->lchild;
        return p->rchild;
    }
    return p->rchild;   //rtag==1直接返回后继线索
}
 
//遍历线索二叉树
void Preorder(ThreadTree T){
    for(ThreadNode* p=T;p!=NULL;p = Nextnode(p)){
        cout<<p->data<<" ";
    }
    cout<<endl;
}
 
 
/*--------------------------*/
 
void test(){
    ThreadTree T;
    T =(ThreadNode*)malloc(sizeof(ThreadNode));
    InitTree(T);
    CreatInThread(T);
    Preorder(T);
}
 
int main(){
 
    test();
    return 0;
}

7. 后序线索化二叉树

#include<iostream>
 
using namespace std;
 
typedef char ElemType;
 
typedef struct ThreadNode{
    ElemType data;
    struct ThreadNode *lchild,*rchild;
    int ltag,rtag;
}ThreadNode,*ThreadTree;
 
ThreadNode *pre;    //指向当前访问节点的前驱
 
 
void InitTree(ThreadTree& T);//初始化树
void visit(ThreadNode* q);
void PostThread(ThreadTree T);//后序遍历二叉树,
void CreatInThread(ThreadTree T);//建立后序线索化二叉树
 
/*--------------------------*/
/*后序线索二叉树中找后序前驱*/
ThreadNode* Prenode(ThreadNode* p);//找后序线索二叉树中节点p在后序序列下的前驱
void RevPostorder(ThreadTree T);//逆向遍历线索二叉树
/*--------------------------*/
 
 
//初始化树
void InitTree(ThreadTree& T){
    ElemType ch;
    cin>>ch;
    if(ch=='#'){
        T = NULL;
    }else{
        T = (ThreadNode*)malloc(sizeof(ThreadNode));
        T->data = ch;
        T->ltag = 0;
        T->rtag = 0;
        InitTree(T->lchild);
        InitTree(T->rchild);
    }
 
}
 
void visit(ThreadNode* q){
    if(q->lchild==NULL){        //左子树为空,建立前驱线索
        q->lchild = pre;
        q->ltag =1;
    }
    if(pre!=NULL && pre->rchild == NULL){     //建立前驱节点的后续线索
        pre->rchild = q;
        pre->rtag = 1;
    }
    pre = q;
}
 
//后序遍历二叉树,
void PostThread(ThreadTree T){
    if(T!=NULL){
        PostThread(T->lchild);
        PostThread(T->rchild);
        visit(T);
    }
}
 
//建立后序线索化二叉树
void CreatInThread(ThreadTree T){
    pre = NULL;
    if(T!=NULL){
        PostThread(T);            //后序线索化二叉树
        if(pre->rchild == NULL){
            pre->rtag = 1;      //处理遍历的最后一个节点
        }
    }
}
 
/*--------------------------*/
/*后序线索二叉树中找后序前驱*/
 
 
//找后序线索二叉树中节点p在后序序列下的前驱
ThreadNode* Prenode(ThreadNode* p){
    if(p->ltag == 0){
        if(p->rchild!=NULL) return p->rchild;
        return p->lchild;
    }
    return p->lchild;   //ltag==1直接返回前驱线索
}
 
//逆向遍历线索二叉树
void RevPostorder(ThreadTree T){
    for(ThreadNode* p=T;p!=NULL;p = Prenode(p)){
        cout<<p->data<<" ";
    }
    cout<<endl;
}
 
 
/*--------------------------*/
 
void test(){
    ThreadTree T;
    T =(ThreadNode*)malloc(sizeof(ThreadNode));
    InitTree(T);
    CreatInThread(T);
    RevPostorder(T);
}
 
int main(){
 
    test();
    return 0;
}

8. 先序,中序,后序线索二叉树总结

中序线索二叉树先序线索二叉树后序线索二叉树
找前驱×
找后继×

除非采用暴力或者三叉树才能实现表中打叉的部分

9. 平衡二叉树

/*
这个代码还没完善
*/
#include<iostream>
 
using namespace std;
 
typedef struct BSTNode{
    int key;
    struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;
 
BSTNode *BST_Search(BSTree T,int key);//递归实现查找
BSTNode *BSTSearch(BSTree T,int key);//非递归实现查找
bool BST_Insert(BSTree &T,int k);//递归实现插入
bool BSTInsert(BSTree &T,int k);//非递归实现插入
void Creat_BST(BSTree &T,int str[],int n);//构造二叉树
 
//递归实现
BSTNode *BST_Search(BSTree T,int key){
    while(T!=NULL&&key!=T->key){
        if(key>T->key){
            T = T->rchild;
        }else{
            T = T->lchild;
        }
    }
    return T;
}
 
//非递归实现
BSTNode *BSTSearch(BSTree T,int key){
    if(T==NULL) return NULL;
    if(T->key==key) return T;
    if(key>T->key) return BSTSearch(T->rchild,key);
    if(key<T->key) return BSTSearch(T->lchild,key);
}
 
//递归实现插入
bool BST_Insert(BSTree &T,int k){
    if(T==NULL){
        T = (BSTNode*)malloc(sizeof(BSTNode));
        T->key = k;
        T->lchild = T->rchild = NULL;
        return true;    //插入成功
    }else if(T->key == k){
        return false;   //插入失败
    }else if(key>T->key){
        return BST_Insert(T->rchild,key);
    }else{
        return BST_Insert(T->lchild,key);
    }
}
 
//非递归实现插入
bool BSTInsert(BSTree &T,int k){
    BSTree p = T;
    BSTree pre = NULL;      //p的父节点,方便查找后插入
    while(p!=NULL){
        pre = p;
        if(p->key == key) return false;
        else if(p->key > key){
            p = p->lchild;
        }else{
            p = p->rchild;
        }
    }
    p = (BSTNode*)malloc(sizeof(BSTNode));
    p->key = k;
    p->lchild = p->rchild = NULL;
    if(pre == NULL) T = p;          //树为空
    else if(k<pre->key){
        pre->lchild = p;
    }else{
        pre->rchild = p;
    }
    return true;
}
 
//构造二叉树
void Creat_BST(BSTree &T,int str[],int n){
    T = NULL;
    for(int i=0;i<n;i++){
        BST_Insert(T,str[i]);
    }
}
 
void test(){
 
}
 
 
int main(){
 
    test();
    return 0;
}

转载自王道考研数据结构代码总结

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IoT_H2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值