二叉树的算法——C/java

1.java实现非递归层序遍历

public class Code03_UnRecursiveTraversalBT {

	public static class Node {
		public int value;
		public Node left;
		public Node right;

		public Node(int v) {
			value = v;
		}
	}

	public static void pre(Node head) {
		System.out.print("pre-order: ");
		if (head != null) {
			Stack<Node> stack = new Stack<Node>();
			stack.add(head);
			while (!stack.isEmpty()) {
				head = stack.pop();
				System.out.print(head.value + " ");
				if (head.right != null) {
					stack.push(head.right);
				}
				if (head.left != null) {
					stack.push(head.left);
				}
			}
		}
		System.out.println();
	}

	public static void in(Node cur) {
		System.out.print("in-order: ");
		if (cur != null) {
			Stack<Node> stack = new Stack<Node>();
			while (!stack.isEmpty() || cur != null) {
				if (cur != null) {
					stack.push(cur);
					cur = cur.left;
				} else {
					cur = stack.pop();
					System.out.print(cur.value + " ");
					cur = cur.right;
				}
			}
		}
		System.out.println();
	}

	public static void pos1(Node head) {
		System.out.print("pos-order: ");
		if (head != null) {
			Stack<Node> s1 = new Stack<Node>();
			Stack<Node> s2 = new Stack<Node>();
			s1.push(head);
			while (!s1.isEmpty()) {
				head = s1.pop(); // 头 右 左
				s2.push(head);
				if (head.left != null) {
					s1.push(head.left);
				}
				if (head.right != null) {
					s1.push(head.right);
				}
			}
			// 左 右 头
			while (!s2.isEmpty()) {
				System.out.print(s2.pop().value + " ");
			}
		}
		System.out.println();
	}

	public static void pos2(Node h) {
		System.out.print("pos-order: ");
		if (h != null) {
			Stack<Node> stack = new Stack<Node>();
			stack.push(h);
			Node c = null;
			while (!stack.isEmpty()) {
				c = stack.peek();
				if (c.left != null && h != c.left && h != c.right) {
					stack.push(c.left);
				} else if (c.right != null && h != c.right) {
					stack.push(c.right);
				} else {
					System.out.print(stack.pop().value + " ");
					h = c;
				}
			}
		}
		System.out.println();
	}

	public static void main(String[] args) {
		Node head = new Node(1);
		head.left = new Node(2);
		head.right = new Node(3);
		head.left.left = new Node(4);
		head.left.right = new Node(5);
		head.right.left = new Node(6);
		head.right.right = new Node(7);

		pre(head);
		System.out.println("========");
		in(head);
		System.out.println("========");
		pos1(head);
		System.out.println("========");
		pos2(head);
		System.out.println("========");
	}

}

2.java实现树的最大宽度

public class Code05_TreeMaxWidth {

	public static class Node {
		public int value;
		public Node left;
		public Node right;

		public Node(int data) {
			this.value = data;
		}
	}

	public static int maxWidthUseMap(Node head) {
		if (head == null) {
			return 0;
		}
		Queue<Node> queue = new LinkedList<>();
		queue.add(head);
		// key 在 哪一层,value
		HashMap<Node, Integer> levelMap = new HashMap<>();
		levelMap.put(head, 1);
		int curLevel = 1; // 当前你正在统计哪一层的宽度
		int curLevelNodes = 0; // 当前层curLevel层,宽度目前是多少
		int max = 0;
		while (!queue.isEmpty()) {
			Node cur = queue.poll();
			int curNodeLevel = levelMap.get(cur);
			if (cur.left != null) {
				levelMap.put(cur.left, curNodeLevel + 1);
				queue.add(cur.left);
			}
			if (cur.right != null) {
				levelMap.put(cur.right, curNodeLevel + 1);
				queue.add(cur.right);
			}
			if (curNodeLevel == curLevel) {
				curLevelNodes++;
			} else {
				max = Math.max(max, curLevelNodes);
				curLevel++;
				curLevelNodes = 1;
			}
		}
		max = Math.max(max, curLevelNodes);
		return max;
	}

	public static int maxWidthNoMap(Node head) {
		if (head == null) {
			return 0;
		}
		Queue<Node> queue = new LinkedList<>();
		queue.add(head);
		Node curEnd = head; // 当前层,最右节点是谁
		Node nextEnd = null; // 下一层,最右节点是谁
		int max = 0;
		int curLevelNodes = 0; // 当前层的节点数
		while (!queue.isEmpty()) {
			Node cur = queue.poll();
			if (cur.left != null) {
				queue.add(cur.left);
				nextEnd = cur.left;
			}
			if (cur.right != null) {
				queue.add(cur.right);
				nextEnd = cur.right;
			}
			curLevelNodes++;
			if (cur == curEnd) {
				max = Math.max(max, curLevelNodes);
				curLevelNodes = 0;
				curEnd = nextEnd;
			}
		}
		return max;
	}

	// for test
	public static Node generateRandomBST(int maxLevel, int maxValue) {
		return generate(1, maxLevel, maxValue);
	}

	// for test
	public static Node generate(int level, int maxLevel, int maxValue) {
		if (level > maxLevel || Math.random() < 0.5) {
			return null;
		}
		Node head = new Node((int) (Math.random() * maxValue));
		head.left = generate(level + 1, maxLevel, maxValue);
		head.right = generate(level + 1, maxLevel, maxValue);
		return head;
	}

	public static void main(String[] args) {
		int maxLevel = 10;
		int maxValue = 100;
		int testTimes = 1000000;
		for (int i = 0; i < testTimes; i++) {
			Node head = generateRandomBST(maxLevel, maxValue);
			if (maxWidthUseMap(head) != maxWidthNoMap(head)) {
				System.out.println("Oops!");
			}
		}
		System.out.println("finish!");

	}

}

C实现基于递归遍历和高度

用到的库基本库<stdio.h>、需要分配地址空间的库<malloc.h>

    //创建二叉树 
    int createBTNode(BTNode * &BT,char *str,int n)
    //销毁二叉树
    void destroyBTNode(BTNode * &BT)
    //查找结点存在
    BTNode *findBTNode(BTNode * &BT,char ch)
    //求高度
    int BTHeight(BTNode * &BT)
    //输出二叉树
    void displayBTNode(BTNode * &BT)
    //先序遍历
    void preOrder(BTNode * &BT)
    //中序遍历
    void inOrder(BTNode * &BT)
    //后序遍历
    void postOrder(BTNode * &BT)

#include<stdio.h>
#include<malloc.h>

typedef struct node{
	struct node *lchild;						//指向左孩子节点
	char data;									//数据元素
	struct node *rchild;						//指向右孩子节点 
}BTNode;
int createBTNode(BTNode * &BT,char *str,int n){	
	printf("%d ",n);
	char ch=str[n];								//把第 n 个字符赋给ch,方便后面判断 
	printf("%c \n",ch);
	n=n+1;
	if(ch!='\0'){								//如果 ch 不等于结束符就继续创建,否则就结束 
		if( ch=='#'){							//以 # 号代表 NULL,下面没有了 
			BT = NULL;
		}
		else{
			BT = new BTNode;					//新建一个二叉链 
			BT->data=ch;						//把字符存入二叉链 
			n=createBTNode(BT->lchild,str,n); 	//左递归创建 
			n=createBTNode(BT->rchild,str,n);	//右递归创建 
		}
	}
	return n;									//返回 n,记录字符串使用到哪里了 
}
void destroyBTNode(BTNode * &BT){
	if(BT!=NULL){
		destroyBTNode(BT->lchild);				//左递归释放内存 
		destroyBTNode(BT->rchild);				//右递归释放内存 
		
		/*
			free()释放的是指针指向的内存!注意!释放的是内存,不是指针!这点非常非常重要!
			指针是一个变量,只有程序结束时才被销毁。释放内存空间。 
			原来指向这块空间的指针还是存在!只不过现在指针指向的内容是未定义的。
			因此,释放内存后把指针指向NULL,防止指针在后面不小心又被引用了。非常重要啊这一点!
		*/
		free(BT);
		BT=NULL; 
	}
}
BTNode *findBTNode(BTNode * &BT,char ch){
	if(BT==NULL){								//空,返回为空 NULL 
		return NULL;
	}
	else if(BT->data==ch){						//存在,提示存在并返回数据 
		printf("存在该节点:%c",ch); 
		return BT;
	}
	else{
		BTNode *p;								//定义一个链表指针 
		p=findBTNode(BT->lchild,ch);			//递归查询左子树 
		if(p!=NULL){
			return p;							//左子树已经找到 
		}
		else{
			return findBTNode(BT->rchild,ch);	//递归查询右子树 
		}
	}
}
int BTHeight(BTNode * &BT){
	int lchildh;
	int rchildh;
	int h;
	if(BT==NULL){
		return 0;										//空树高度为0 
	}
	else{
		lchildh=BTHeight(BT->lchild);					//求左子树的高度 
		rchildh=BTHeight(BT->rchild);					//求右子树的高度 
		h=(lchildh>rchildh)?(lchildh+1):(rchildh+1);	//比较左子树和右子树,高度高的再 +1(根节点) 就是树的高度 
		return h;
	}
}
void displayBTNode(BTNode * &BT){
	if(BT!=NULL){
		printf("%c",BT->data);
		if(BT->lchild!=NULL || BT->rchild!=NULL){
			printf("(");
			displayBTNode(BT->lchild);
			printf(",");
			displayBTNode(BT->rchild);
			printf(")");
		}
	}
}
void displayBTNode1(BTNode * &BT){
	if(BT!=NULL){
		printf("%c",BT->data);
		displayBTNode1(BT->lchild);
		displayBTNode1(BT->rchild);
	}
	else{
		printf("#");
	}
}
void preOrder(BTNode * &BT){
    if(BT!=NULL){					//判断不为空 
        printf("%c",BT->data);		//访问根节点
        preOrder(BT->lchild);		//递归,先序遍历左子树 
        preOrder(BT->rchild);		//递归,先序遍历右子树 
    }
}
 void inOrder(BTNode * &BT){
        if(BT!=NULL){
            inOrder(BT->lchild);
            printf("%c",BT->data);
            inOrder(BT->rchild);
        }
    }
void postOrder(BTNode * &BT){
    if(BT!=NULL){
        postOrder(BT->lchild);
        postOrder(BT->rchild);
        printf("%c",BT->data);
    }
}
int main(){
	
	//例子:ABC###D##
	BTNode *BT;
	printf("输入字符串:");
	char *str=(char *)malloc(sizeof(char) * 1024);
	scanf("%s",str); 
    createBTNode(BT,str,0);
    printf("二叉树建立成功\n");
    
	destroyBTNode(BT);
	if(BT==NULL){
		printf("销毁成功\n");
	}
    
//	printf("请输入要查找的节点:");
//	char c='E';
//	printf("%c\n",c); 
//	if(findBTNode(BT,c)==NULL){
//		printf("没有此节点");
//	}
//	printf("\n");
//    
//	int h=BTHeight(BT); 
//	printf("树的高度为:%d",h);
//	printf("\n");
//	
//	printf("二叉树为:"); 
//	displayBTNode(BT);
//	printf("\n");
//	printf("二叉树为:"); 
//	displayBTNode1(BT);
//	printf("\n");
//	
//	printf("先序遍历结果:");
//	preOrder(BT);
//	printf("\n");
//    
//	printf("中序遍历结果:");
//	inOrder(BT);
//	printf("\n");
//    
//	printf("后序遍历结果:");
//	postOrder(BT);
//	printf("\n");
	
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Strive_LiJiaLe

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

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

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

打赏作者

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

抵扣说明:

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

余额充值