数据结构--树(c 代码部分)(王道书、考研适用)

一、结构体声明

1.二叉树的结构体定义

//树结构体定义
typedef char BiElemType;
typedef struct BiTNode{
    BiElemType c;
    struct BiTNode *lchild;
    struct BiTNode *rchild;
}BiTNode,*BiTree;

2.栈,循环队列,链式队列

// 辅助队列结构体定义
typedef struct tag{
    BiTree p;
    struct tag *pnext;
}tag_t,*ptag_t;

//  栈结构体定义
#define MaxSize 100
typedef BiTree elemtype; //栈队列数组指针
typedef struct{
    elemtype data[MaxSize];
    int top;   //指向栈顶元素
 }SqStack;//sequence 顺序
//abcdefghigk
//循环队列结构体定义
#define Maxsize 10
typedef struct {
	elemtype data[Maxsize];
	int front, rear;
	int tag;  
}SqQueue;

3、循环队列代码

//循环队列
void InitQueue(SqQueue &Q) {
	Q.rear = Q.front = 0;
}
bool QueueEmpty(SqQueue Q) {  //队列判空
	if (Q.rear == Q.front)  return true;
	else return  false;
}
bool EnQueue(SqQueue& Q, elemtype x) {
	if ((Q.rear+1)%Maxsize == Q.front)  return false;
	Q.data[Q.rear] = x;
	//循环队列
	Q.rear = (Q.rear + 1) % Maxsize;
	return true;
}
bool DeQueue(SqQueue& Q, elemtype &x) {
	if (Q.rear == Q.front) return false;
	x = Q.data[Q.front];
	Q.front = (Q.front + 1) % Maxsize; return true;
}
bool GetHead(SqQueue& Q, elemtype &x) {
	if (Q.rear == Q.front) return false;
	x = Q.data[Q.front];
	return  true;
}

4.栈代码

//s.top == -1 栈
void InitStack(SqStack &S){
    S.top = -1;
}
bool StackEmpty(SqStack S){
   if(S.top==-1)  return true; //栈空
   else  return false; //不空 
}
bool Push(SqStack &S,elemtype x){
   if(S.top==MaxSize-1)  return false;
   S.data[++S.top] = x;
   return true;
}
bool Pop(SqStack &S,elemtype &x){
   if(S.top==-1) return false;
   x = S.data[S.top--];  return true;
}
bool GetTop(SqStack S,elemtype &x){
   if(S.top==-1) return false;
   x = S.data[S.top]; return true;
}

二、二叉树的遍历

1.先序遍历

void PreOrder(BiTree p){     //深度优先遍历
    if(p!=NULL){
        cout<<p->c<<" ";
        PreOrder(p->lchild); //打印左子树
        PreOrder(p->rchild); //打印右子树
    } 
} 

2.中序遍历

void InOrder(BiTree p){    
    if(p!=NULL){
        InOrder(p->lchild);
        cout<<p->c<<" ";
        InOrder(p->rchild);
    }  
}

3.后序遍历

void PostOrder(BiTree p){
    if(p!=NULL){
       PostOrder(p->lchild);
       PostOrder(p->rchild);
       cout<<p->c<<" ";  
    }
}

4.非递归先序遍历 

void PreOrder2(BiTree p,SqStack &S){
    InitStack(S); BiTree r = p;
    while(r || !StackEmpty(S) ){
        if(r){
            cout << r->c<< " ";
            Push(S,r);
            r = r->lchild;
        }else {
            Pop(S,r);
            r = r->rchild;
        }
    }
}

5.非递归中序遍历

void InOrder2(BiTree p , SqStack &S){
    InitStack(S); BiTree r = p;  // 初始化栈 , 指向根节点
    while(r || !StackEmpty(S)){ // 树空结点  或者栈空
        if(r){                  //压栈  直到左子树为空
            Push(S,r);          
            r = r->lchild ;
        }else {
            Pop(S,r);
            cout << r->c << " ";
            r = r->rchild ; 
        }
    }
}

6.非递归后序遍历

void PostOrder2(BiTree Tr,SqStack &S){
    InitStack(S);
    BiTNode* p = Tr; 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;
            }else{
                Pop(S , p);
                cout<< p->c << " ";
                r = p;
                p = NULL;
            }//else
        }//while
    }
}

7.层次遍历

void Levelorder(BiTree T , SqQueue &Q){
    InitQueue(Q); BiTree p; EnQueue(Q , T);
    while(!QueueEmpty(Q)){
       DeQueue(Q , p); cout<< p->c << " " ;
       if(p->lchild != NULL) EnQueue(Q , p->lchild) ;
       if(p->rchild != NULL) EnQueue(Q , p->rchild);
    }
}

三、二叉树的常用算法

1.自下而上,从右到左的层次遍历

void deLevelOrder(BiTree T , SqQueue &Q , SqStack &S){
    InitQueue(Q); InitStack(S);
    BiTree p; EnQueue(Q , T);
    while(!QueueEmpty(Q)){
        DeQueue(Q , p); Push(S , p);
        if(p->lchild != NULL) EnQueue(Q , p->lchild);
        if(p->rchild != NULL) EnQueue(Q , p->rchild); 
    }
    while(!StackEmpty(S)) {
        Pop(S , p);
        cout<< p->c <<" "; 
    }
    cout<<endl<<endl;
}

2.计算一棵给定二叉树的所有双分支结点数个数

void DoubleNode(BiTree p , int &count){
   if(p != NULL){
        if(p->lchild != NULL && p->rchild != NULL){
           count ++ ; 
        } 
        DoubleNode(p->lchild , count); //打印左子树
        DoubleNode(p->rchild , count); //打印右子树
    } 
}

3.判定给定二叉树是否为完全二叉树

bool IsComplete(BiTree T , SqQueue &Q){
    InitQueue(Q); BiTree p;
    if(!T)  return 1;
    EnQueue(Q , T);
    while(!QueueEmpty(Q)){
        DeQueue(Q , p);
        if(p){
            EnQueue(Q , p->lchild);
            EnQueue(Q , p->rchild); 
        }else {
            while(!QueueEmpty(Q)){
              DeQueue(Q , p);
              if(p) return 0 ;
            }//while
        }
    }
    return 1;
}

4.树b 交换左右子树

void SwapLRChild(BiTree p){
    if(p != NULL){
        BiTree temp = p->lchild;
        p->lchild = p->rchild;
        p->rchild = temp;
        SwapLRChild(p->lchild);
        SwapLRChild(p->rchild);
    }
}

5.先序遍历中第k个结点的值

void KpreOreder(BiTree p , int k){
    if(p!=NULL){
        num++;
        if (num == k) cout<< p->c <<endl;   
        KpreOreder(p->lchild , k); //打印左子树
        KpreOreder(p->rchild , k); //打印右子树
    } 
}

四、汇总

       把所有的代码汇总到一起供参考。还有一部分没写完,这是王道书上的课后题,然后写完了会及时更新。

#include<iostream>
#include<cstring>
using namespace std;
int count = 0; int num = 0;
//树结构体定义
typedef char BiElemType;
typedef struct BiTNode{
    BiElemType c;
    struct BiTNode *lchild;
    struct BiTNode *rchild;
}BiTNode,*BiTree;

// 辅助队列结构体定义
typedef struct tag{
    BiTree p;
    struct tag *pnext;
}tag_t,*ptag_t;

//  栈结构体定义
#define MaxSize 100
typedef BiTree elemtype; //栈队列数组指针
typedef struct{
    elemtype data[MaxSize];
    int top;   //指向栈顶元素
 }SqStack;//sequence 顺序
//abcdefghigk
//循环队列结构体定义
#define Maxsize 10
typedef struct {
	elemtype data[Maxsize];
	int front, rear;
	int tag;  
}SqQueue;

//  辅助队列
/**************************************************/

void testQueue();
void InitQueue(SqQueue &Q);
bool QueueEmpty(SqQueue Q);
bool EnQueue(SqQueue &Q, elemtype x);
bool DeQueue(SqQueue &Q, elemtype &x);

/**************************************************/
//    辅助栈
/**************************************************/

void InitStack(SqStack &S);//创建
bool Push(SqStack &S,elemtype x);//压栈
bool Pop(SqStack &S,elemtype &x);//弹出
bool GetTop(SqStack S,elemtype &x);//读栈顶元素
bool StackEmpty(SqStack S);
bool brackCheck(char str[], int length);

/**************************************************/
//树函数区
void PreOrder(BiTree p); //先序遍历
void InOrder(BiTree p);  //中序遍历
void PostOrder(BiTree p);//后序遍历
void PreOrder2(BiTree p, SqStack &S); //非递归中序遍历
void InOrder2(BiTree p, SqStack &S); //非递归先序遍历
void PostOrder2(BiTree p, SqStack &S ); //非递归先序遍历
void Levelorder(BiTree T , SqQueue &Q); //层序遍历

void deLevelOrder(BiTree T , SqQueue &Q , SqStack &S);//逆向输出层序遍历
void DoubleNode(BiTree p , int &count);
bool IsComplete(BiTree T , SqQueue &Q);
void SwapLRChild(BiTree p);/*树b 交换左右子树*/
void KpreOreder(BiTree p , int k);/*先序遍历中第k个结点的值*/
/**************************************************/

int main(){
    SqStack S;SqQueue Q; 
    int k ;
    BiTree pnew;
    BiTree tree = NULL; //tree是指向树根的,代表树
    char c;
    ptag_t phead = NULL,ptail = NULL,listpnew = NULL,pcur=NULL;
    while(scanf("%c",&c)){
         if( c =='\n')   break;
            pnew = (BiTree)calloc(1,sizeof(BiTNode));
            pnew->c = c;
            listpnew = (ptag_t)calloc(1,sizeof(tag_t));
            listpnew->p = pnew;
    
        if(NULL == tree){
            tree = pnew ; //tree 指向树的根节点
            phead = listpnew;//第一个结点即是队列头,也是队列尾。
            ptail = listpnew;
            pcur = listpnew;
            continue;
        }else {
            ptail->pnext = listpnew;
            ptail = listpnew;
            //接下来把b结点放入树中
        
        } 
        if(pcur->p->lchild == NULL) {
            pcur->p->lchild = pnew;//左孩子为空,就放入左孩子
        }
        else if(pcur->p->rchild == NULL){
            pcur->p->rchild = pnew;//右孩子为空,就放入右孩子
            pcur = pcur->pnext; //当前结点左右孩子都有了,pcur就指向下一个结点
        }  
    } 

    /*先序遍历*/
    cout<<"preorder" << "先序遍历" <<endl;
    PreOrder(tree);      cout<<endl;
    /*非递归先序遍历*/
    cout<<"preorder2"<< "非递归先序遍历" <<endl;
    PreOrder2(tree , S);  cout<<endl; cout<<endl;
    
    /*中序遍历*/
    cout<<"inorder" << "中序遍历" <<endl;
    InOrder(tree);       cout<<endl;
    /*非递归中序遍历*/
    cout<<"inorder2"<< "非递归中序遍历" <<endl;
    InOrder2(tree , S);   cout<<endl; cout<<"\n";

    /*后序遍历*/
    cout<<"postorder" << "后序遍历" <<endl;
    PostOrder(tree); cout<<endl;
    /*非递归后序遍历*/
    cout<<"postorder2" << "非递归后序遍历" <<endl;
    PostOrder2(tree , S); cout<<endl; cout<<endl;
    
    /*层序遍历*/
    cout<<"leverorder" << "层序遍历" <<endl;
    Levelorder(tree , Q);cout<<endl; cout<<endl;
    /*逆向输出层序遍历*/
    cout<<"逆向输出层序遍历"<<endl;
    deLevelOrder(tree , Q , S);
   
    /*二叉树双分支结点数*/
    cout<<"二叉树双分支结点数"<<endl;
    DoubleNode(tree , count); cout<< count <<endl;

    /*给定二叉树是否为完全二叉树*/
    cout<<"给定二叉树是否为完全二叉树"<<endl;
    cout<<IsComplete(tree , Q)<<endl;

    /*树b 交换左右子树*/
    // cout<<"交换树b的左右子树"<<endl;
    // SwapLRChild(tree);
    // Levelorder(tree , Q);cout<<endl; cout<<endl;

    /*先序遍历中第k个结点的值*/
    cout<<"第k个结点的值"<<endl;
    KpreOreder(tree , 5); cout<<endl;
    return 0;
}

void PreOrder(BiTree p){     //深度优先遍历
    if(p!=NULL){
        cout<<p->c<<" ";
        PreOrder(p->lchild); //打印左子树
        PreOrder(p->rchild); //打印右子树
    } 
} 
void InOrder(BiTree p){    
    if(p!=NULL){
        InOrder(p->lchild);
        cout<<p->c<<" ";
        InOrder(p->rchild);
    }  
}
void PostOrder(BiTree p){
    if(p!=NULL){
       PostOrder(p->lchild);
       PostOrder(p->rchild);
       cout<<p->c<<" ";  
    }
}
void InOrder2(BiTree p , SqStack &S){
    InitStack(S); BiTree r = p;  // 初始化栈 , 指向根节点
    while(r || !StackEmpty(S)){ // 树空结点  或者栈空
        if(r){                  //压栈  直到左子树为空
            Push(S,r);          
            r = r->lchild ;
        }else {
            Pop(S,r);
            cout << r->c << " ";
            r = r->rchild ; 
        }
    }
}
void PreOrder2(BiTree p,SqStack &S){
    InitStack(S); BiTree r = p;
    while(r || !StackEmpty(S) ){
        if(r){
            cout << r->c<< " ";
            Push(S,r);
            r = r->lchild;
        }else {
            Pop(S,r);
            r = r->rchild;
        }
    }
}
void PostOrder2(BiTree Tr,SqStack &S){
    InitStack(S);
    BiTNode* p = Tr; 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;
            }else{
                Pop(S , p);
                cout<< p->c << " ";
                r = p;
                p = NULL;
            }//else
        }//while
    }
}
void Levelorder(BiTree T , SqQueue &Q){
    InitQueue(Q); BiTree p; EnQueue(Q , T);
    while(!QueueEmpty(Q)){
       DeQueue(Q , p); cout<< p->c << " " ;
       if(p->lchild != NULL) EnQueue(Q , p->lchild) ;
       if(p->rchild != NULL) EnQueue(Q , p->rchild);
    }
}

//自下而上,从右到左的层次遍历算法
void deLevelOrder(BiTree T , SqQueue &Q , SqStack &S){
    InitQueue(Q); InitStack(S);
    BiTree p; EnQueue(Q , T);
    while(!QueueEmpty(Q)){
        DeQueue(Q , p); Push(S , p);
        if(p->lchild != NULL) EnQueue(Q , p->lchild);
        if(p->rchild != NULL) EnQueue(Q , p->rchild); 
    }
    while(!StackEmpty(S)) {
        Pop(S , p);
        cout<< p->c <<" "; 
    }
    cout<<endl<<endl;
}
//非递归算法求二叉树高度
void BTreeHigh(BiTree T );
//计算一棵给定二叉树的所有双分支结点数个数
void DoubleNode(BiTree p , int &count){
   if(p != NULL){
        if(p->lchild != NULL && p->rchild != NULL){
           count ++ ; 
        } 
        DoubleNode(p->lchild , count); //打印左子树
        DoubleNode(p->rchild , count); //打印右子树
    } 
}
//判定给定二叉树是否为完全二叉树
bool IsComplete(BiTree T , SqQueue &Q){
    InitQueue(Q); BiTree p;
    if(!T)  return 1;
    EnQueue(Q , T);
    while(!QueueEmpty(Q)){
        DeQueue(Q , p);
        if(p){
            EnQueue(Q , p->lchild);
            EnQueue(Q , p->rchild); 
        }else {
            while(!QueueEmpty(Q)){
              DeQueue(Q , p);
              if(p) return 0 ;
            }//while
        }
    }
    return 1;
}
/*树b 交换左右子树*/
void SwapLRChild(BiTree p){
    if(p != NULL){
        BiTree temp = p->lchild;
        p->lchild = p->rchild;
        p->rchild = temp;
        SwapLRChild(p->lchild);
        SwapLRChild(p->rchild);
    }
}
/*先序遍历中第k个结点的值*/
void KpreOreder(BiTree p , int k){
    if(p!=NULL){
        num++;
        if (num == k) cout<< p->c <<endl;   
        KpreOreder(p->lchild , k); //打印左子树
        KpreOreder(p->rchild , k); //打印右子树
    } 
}

/*2017统考真题*/
void InOrder(BiTree p){
    
}





//s.top == -1 栈
void InitStack(SqStack &S){
    S.top = -1;
}
bool StackEmpty(SqStack S){
   if(S.top==-1)  return true; //栈空
   else  return false; //不空 
}
bool Push(SqStack &S,elemtype x){
   if(S.top==MaxSize-1)  return false;
   S.data[++S.top] = x;
   return true;
}
bool Pop(SqStack &S,elemtype &x){
   if(S.top==-1) return false;
   x = S.data[S.top--];  return true;
}
bool GetTop(SqStack S,elemtype &x){
   if(S.top==-1) return false;
   x = S.data[S.top]; return true;
}

//循环队列
void InitQueue(SqQueue &Q) {
	Q.rear = Q.front = 0;
}
bool QueueEmpty(SqQueue Q) {  //队列判空
	if (Q.rear == Q.front)  return true;
	else return  false;
}
bool EnQueue(SqQueue& Q, elemtype x) {
	if ((Q.rear+1)%Maxsize == Q.front)  return false;
	Q.data[Q.rear] = x;
	//循环队列
	Q.rear = (Q.rear + 1) % Maxsize;
	return true;
}
bool DeQueue(SqQueue& Q, elemtype &x) {
	if (Q.rear == Q.front) return false;
	x = Q.data[Q.front];
	Q.front = (Q.front + 1) % Maxsize; return true;
}
bool GetHead(SqQueue& Q, elemtype &x) {
	if (Q.rear == Q.front) return false;
	x = Q.data[Q.front];
	return  true;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值