C++实现二叉树及其线索化和遍历

/*
 * BiTree.h
 *
 *  Created on: Oct 17, 2015
 *      Author: chris
 */

#ifndef BITREE_H_
#define BITREE_H_

#include<iostream>

typedef int ElemType;

struct BTNode {
	ElemType data;
	BTNode *lchild, *rchild;
	BTNode *pre, *next;

	BTNode(): lchild(NULL), rchild(NULL),
			pre(NULL), next(NULL) {}
};

typedef BTNode* BiTree;

bool BiTreeCreate(BiTree & T);
void BiTreeDestroy(BiTree & T);

bool BiTreePreOrderTraverse(BiTree T, bool (*visit)(ElemType &));
bool BiTreeInOrderTraverse(BiTree T, bool (*visit)(ElemType &));
bool BiTreePostOrderTraverse(BiTree T, bool (*visit)(ElemType &));
bool BiTreeLevelOrderTraverse(BiTree T, bool (*visit)(ElemType &));

void BiTreePreOrderThreading(BiTree T);
void BiTreeInOrderThreading(BiTree T);
void BiTreePostOrderThreading(BiTree T);
void BiTreeLevelOrderThreading(BiTree T);

void BiTreeWalkThrough(BiTree T);
void BiTreeDisplay(BiTree T);

#endif /* BITREE_H_ */



/*
 * BiTree.cpp
 *
 *  Created on: Oct 17, 2015
 *      Author: chris
 */

#include<iostream>
#include"BiTree.h"

using namespace std;

bool BiTreeCreate(BiTree & T)
{
	static int depth = 0;

	if(!T)  {
		T = new BTNode;
		if(!T) return false;

		cout << "Now: " << (void*)&T << ";  Depth: " << depth << ";  Value: " << T->data << endl;
    	cout << "Left: " << (void*)T->lchild << ";  Right: " << (void*)T->rchild << endl;

		cout << "Value: "; cout.flush();
		cin >> T->data;
	}

	++depth;
	while(true) {
	    int choice = 0;
	    do{
	    	cout << "Now: " << (void*)&T << ";  Depth: " << depth << ";  Value: " << T->data << endl;
	    	cout << "Left: " << (void*)T->lchild << ";  Right: " << (void*)T->rchild << endl;
		    cout << "1: lchild; 2: rchild; 3: back" << endl;
		    cin >> choice;

		    if( choice >= 1 && choice <= 3);
		    	break;
	    }while(true);

	    if(choice == 3)
	    	break;
	    else if(choice == 1) {
	    	BiTreeCreate(T->lchild);
	    }
	    else if(choice == 2) {
	    	BiTreeCreate(T->rchild);
	    }//endif
	}//endw

	--depth;
	return true;
}

void BiTreeDestroy(BiTree & T)
{
	if(T->lchild)
		BiTreeDestroy(T->lchild);
	if(T->rchild)
		BiTreeDestroy(T->rchild);
	delete T;
	T = NULL;
}

bool BiTreePreOrderTraverse(BiTree T, bool (*visit)(ElemType &))
{
	if(!T) return true;
	if(visit(T->data))
		if(BiTreePreOrderTraverse(T, visit))
			if(BiTreePreOrderTraverse(T, visit))
				return true;
	return false;
}

bool BiTreeInOrderTraverse(BiTree T, bool (*visit)(ElemType &))
{
	if(!T) return true;
	if(BiTreeInOrderTraverse(T, visit))
		if(visit(T->data))
			if(BiTreeInOrderTraverse(T, visit))
				return true;
	return false;
}

bool BiTreePostOrderTraverse(BiTree T, bool (*visit)(ElemType &))
{
	if(!T) return true;
	if(BiTreePostOrderTraverse(T, visit))
		if(BiTreePostOrderTraverse(T, visit))
			if(visit(T->data))
				return true;
	return false;
}

bool BiTreeLevelOrderTraverse(BiTree T, bool (*visit)(ElemType &))
{   // bfs
	if(!T) return true;

    const int MAXQSIZ = 512;
    BTNode* queue[MAXQSIZ];
    int front = 0, rear = 0;

    queue[rear++] = T;
    while(front != rear) {
    	//dequeue
    	BTNode * pcur = queue[front];
	    front = (front + 1)%MAXQSIZ;

	    if(!visit(pcur->data))
	    	return false;

	    //enqueue
	    if(pcur->lchild) {
	    	if((rear + 1) % MAXQSIZ == front) {
	    		cerr << "Overflow" << endl;
	    		return false;
	    	}
	    	queue[rear] = pcur->lchild;
	    	rear = (rear + 1) % MAXQSIZ;
	    }
	    if(pcur->rchild) {
	    	if((rear + 1) % MAXQSIZ == front) {
	    		cerr << "Overflow" << endl;
	    		return false;
	    	}
	    	queue[rear] = pcur->rchild;
	    	rear = (rear + 1) % MAXQSIZ;
	    }
    }//endw
}

void BiTreePreOrderThreading(BiTree T)
{
	if(!T) return;
	static int depth = 0;
	static BTNode* pre = NULL;

	++depth;
	if(pre) {
		pre->next = T;
		T->pre = pre;
	}
	pre = T;
	BiTreePreOrderThreading(T->lchild);
	BiTreePreOrderThreading(T->rchild);

	--depth;
	if(depth == 0) {
		T->pre = pre;
		pre->next = T;

		pre = NULL;
	}
}

void BiTreeInOrderThreading(BiTree T)
{
	if(!T) return;
	static int depth = 0;
	static BTNode* pre = NULL;

	++depth;
	BiTreeInOrderThreading(T->lchild);
	if(pre) {
		pre->next = T;
		T->pre = pre;
	}
	pre = T;
	BiTreeInOrderThreading(T->rchild);
	--depth;

	if(depth == 0) {
		BTNode *pcur = T;
		while(pcur->lchild)
			pcur = pcur->lchild;
		pcur->pre = pre;
		pre->next = pcur;

		pre = NULL;
	}
}

void BiTreePostOrderThreading(BiTree T)
{
	if(!T) return;
	static int depth = 0;
	static BTNode* pre = NULL;

	++depth;
	BiTreePostOrderThreading(T->lchild);
	BiTreePostOrderThreading(T->rchild);
	if(pre) {
		pre->next = T;
		T->pre = pre;
	}
	pre = T;
	--depth;

	if(depth == 0) {
		BTNode * pcur = T;
		while(pcur->lchild)
			pcur = pcur->lchild;
		pcur->pre = pre;
		pre->next = pcur;

		pre = NULL;
	}
}

void BiTreeLevelOrderThreading(BiTree T)
{
	if(!T) return;

	BTNode * pre = NULL;

	const int MAXQSIZ = 512;
	BTNode* queue[MAXQSIZ];
	int front = 0, rear = 0;

	queue[rear++] = T;
	while(front != rear) {
   	    //dequeue
   	    BTNode * pcur = queue[front];
        front = (front + 1)%MAXQSIZ;

        if(pre) {
    	    pre->next = pcur;
    	    pcur->pre = pre;
        }
        pre = pcur;

        //enqueue
        if(pcur->lchild) {
    	    if((rear + 1) % MAXQSIZ == front) {
    		    cerr << "Overflow" << endl;
    		    return;
    	    }

    	    queue[rear] = pcur->lchild;
    	    rear = (rear + 1) % MAXQSIZ;
        }
        if(pcur->rchild) {
    	    if((rear + 1) % MAXQSIZ == front) {
    		    cerr << "Overflow" << endl;
    		    return;
    	    }
            queue[rear] = pcur->rchild;
	    	rear = (rear + 1) % MAXQSIZ;
	    }
    }//endw

	T->pre = pre;
	pre->next = T;
}

void BiTreeWalkThrough(BiTree T)
{
	if(!T) {
		cout << "Empty!" << endl;
		return;
	}

	BiTree subT = T;
	while(true) {
		cout << "Now: " << (void*)subT
				<< "; Data: " << subT->data << ";" << endl;
		cout << "Left: " << (void*)subT->lchild
				<< "; Right: " << (void*)subT->rchild << ";"
				<< " Pre: " << (void*)subT->pre << "; Next: " << (void*)subT->next << endl;

		int ans = 0;
		do{
		    cout << "1: to left; 2: to right; 3: to pre; 4: to next; 5: root; 6: stop" << endl;
		    cin >> ans;
		    if(ans >= 1 && ans <= 6)
		    	break;
		}while(true);

		if(ans == 1) {
			if(T->lchild)
				subT = subT->lchild;
			else
				cout << "Empty" << endl;
		}
		else if(ans == 2) {
			if(T->rchild)
				subT = subT->rchild;
			else
			    cout << "Empty" << endl;
		}
		else if(ans == 3) {
			if(T->pre)
				subT = subT->pre;
			else
				cout << "Empty" << endl;
		}
		else if(ans == 4) {
			if(T->next)
				subT = subT->next;
			else
				cout << "Empty" << endl;
		}
		else if(ans == 5){
			subT = T;
		}
		else
			break;
	}//endw
}

void BiTreeDisplay(BiTree T)
{
	if(!T) return;

	cout << " " << T->data;
	if(T->lchild || T->rchild)
	    cout << ":";
	else
		cout << " ";

	if(T->lchild) {
	    cout << "L(";
	    BiTreeDisplay(T->lchild);
	    cout << ")";
	}

	if(T->lchild && T->rchild)
		cout << "--";

	if(T->rchild) {
	    cout << "R(";
	    BiTreeDisplay(T->rchild);
	    cout << "); ";
	}

	cout.flush();
}





/*
 * Main.cpp
 *
 *  Created on: Oct 17, 2015
 *      Author: chris
 */

#include<iostream>
#include"BiTree.h"

using namespace std;

int main(void)
{
	BiTree bt = NULL;
	BiTreeCreate(bt);
	BiTreeDisplay(bt);
	cout << endl;

	cout << "PreOrder" << endl;
	BiTreePreOrderThreading(bt);
	BiTreeWalkThrough(bt);

	cout << "InOrder" << endl;
	BiTreeInOrderThreading(bt);
	BiTreeWalkThrough(bt);

	cout << "PostOrder" << endl;
	BiTreePostOrderThreading(bt);
	BiTreeWalkThrough(bt);

	cout << "LevelOrder" << endl;
	BiTreeLevelOrderThreading(bt);
	BiTreeWalkThrough(bt);

	BiTreeDestroy(bt);
	system("pause");
	return 0;
}




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值