树和大量数据处理

1、重建二叉树

根据前序和中序遍历的结果,求后序遍历。

#include <stdio.h>
#include <string.h>

// 在中序序列中找出前序中根的位置
int Find(char in[], char ch, int s, int e)
{
	while(s <= e && in[s] != ch)
	{
		s++;
	}
	return s;
}

void PostTraverse(char pre[], int ps, int pe, char in[], int is, int ie)
{
	int k;
	char c;
	if(is > ie ) return; // 非法子树
	if(is == ie) {printf("%c ", in[is]); return;} // 子树只有一个结点

	// 前序序列中每个节点都是其子树的根结点
	c = pre[ps];
	k = Find(in, c, is, ie); // 在中序序列中找到根结点的位置
	PostTraverse(pre, ps + 1, ps + k - is, in, is, k - 1); // 递归求解左子树
	PostTraverse(pre, ps + k - is + 1, pe, in, k + 1, ie); // 递归求解右子树
	printf("%c ", c); // 输出根结点
}

int main()
{
	char pre[] = "ABCDEGF";
	char in[] = "CBEGDFA";
	PostTraverse(pre, 0, strlen(in) - 1, in, 0, strlen(pre) - 1);
	printf("\n");
	return 0;
}

2、二叉树分层遍历

二叉树的分层遍历可以通过递归实现,但是相对效率较低。访问二叉树第k层结点时,只需要知道第k - 1层结点的信息,加些将k - 1层结点信息保存在数组中,以cur表示当前访问的结点,last表示当前层次的最后一个结点的下一个位置,当cur == last时当前层次访问结束。在访问第k层时,将k + 1的所有结点存入数组,当访问完第k层时,判断是否还存在新的层次可以访问,直到访问完所有层次为止。

#include <iostream>
#include <vector>
#include <string>
using namespace std;

typedef struct BiNode
{
	char data;
	struct BiNode *lchild;
	struct BiNode *rchild;
} BiTree;

/* 创建二叉树, 输入:abc##de#g##f### */
void CreateBiTree(BiTree *&root)
{
	char ch;
	cin >> ch;
	if(ch == '#')
	{
		root = NULL;
	}
	else
	{
		root = new BiNode;
		root->data = ch;
		root->lchild = root->rchild = NULL;
		CreateBiTree(root->lchild);
		CreateBiTree(root->rchild);
	}
}

/* 前序递归遍历 */
void PreOrderTraverse(const BiTree *root)
{
	if(root)
	{
		cout << root->data << " ";
		PreOrderTraverse(root->lchild);
		PreOrderTraverse(root->rchild);
	}
}

void PrintByLevel(BiTree *root)
{
	int cur = 0, last = 1;
	vector<BiTree *> vec;

	if(root == NULL)
		return;

	vec.push_back(root);
	while(cur < vec.size())
	{
		last = vec.size();
		while(cur < last)
		{
			cout << vec[cur]->data << " ";
			if(vec[cur]->lchild)
				vec.push_back(vec[cur]->lchild);
			if(vec[cur]->rchild)
				vec.push_back(vec[cur]->rchild);
			cur++;
		}
		cout << endl << endl;
	}
}

/* 中序递归遍 */
void InOrderTraverse(const BiTree *root)
{
	if(root)
	{
		InOrderTraverse(root->lchild);
		cout << root->data << " ";
		InOrderTraverse(root->rchild);
	}
}

/* 后序递归遍历 */
void PostOrderTraverse(const BiTree *root)
{
	if(root)
	{
		PostOrderTraverse(root->lchild);
		PostOrderTraverse(root->rchild);
		cout << root->data << " ";
	}
}

int main()
{
	BiTree *root;
	CreateBiTree(root);
	/*PreOrderTraverse(root);
	cout << endl;
	InOrderTraverse(root);
	cout << endl;
	PostOrderTraverse(root);
	cout << endl;*/

	PrintByLevel(root);

	return 0;
}

3、给定一个数组,数组中的元素按升序排列,求其中两个元素之和为m的数对

设数组a中的元素为a1,a2,......,an,且a1<a2<......<an。令i = 1, j = n:

如果ai + aj  > m,说明可能存在i < x < j使得ai + ax = m则有j--

如果ai + aj  < m,说明可能存在i < x < j使得ax + aj = m则有i++

如果ai + aj  = m,说明则输出(i, j)

如果i >= j,说明数组中不存在满足条件的数对。

#include <stdio.h>

#define ARRSIZE 10

int main()
{
	int m, i = 0, j = ARRSIZE - 1, n = 0;
	int a[ARRSIZE];

	for(i = 0; i < ARRSIZE; i++)
		scanf("%d", &a[i]);

	scanf("%d", &m);
	i = 0;
	while(i < j)
	{
		if(a[i] + a[j] > m)
			j--;
		else if(a[i] + a[j] < m)
			i++;
		else
		{
			printf("(%d, %d)\n", a[i], a[j]);
			i++; j--; n++;
		}
	}
	if(i == 0)
		printf("没有找到数对(i, j)使得a[i] + a[j] == m");
	
	return 0;
}


4、判断两棵二叉树是否相等

两棵二叉树root1和root2相等有以下两种情况:

1.如果root1和root2都是空树

2.如果root1的左子树与root2的左子树相同且root1的右子树与root2的右子树相同

#include <iostream>
#include <cstdio>
#include <string>
using namespace std;

typedef struct BiNode
{
	char data;
	struct BiNode *lchild;
	struct BiNode *rchild;
} BiTree;

/* 建立二叉树时的输入格式:abc##de#g##f### */
void CreateBiTree(BiTree *&root)
{
	char ch;
	cin >> ch;
	if(ch == '#')
	{
		root = NULL;
	}
	else
	{
		root = new BiNode;
		root->data = ch;
		root->lchild = root->rchild = NULL;
		CreateBiTree(root->lchild);
		CreateBiTree(root->rchild);
	}
}

/* 判断两棵二叉是否相等,相等返回1,否则返回0 */
int EqualTree(BiTree *root1, BiTree *root2)
{
	if(!root1 && !root2)
		return 1;
	if(!root1 || !root2)
		return 0;
	if(root1->data != root2->data)
		return 0;
	if(EqualTree(root1->lchild, root2->lchild) && EqualTree(root1->rchild, root2->rchild))
		return 1;
	return 0;
}

int main()
{
	BiTree *root1, *root2;
	CreateBiTree(root1);
	CreateBiTree(root2);
	if(EqualTree(root1, root2) == 1)
		cout << "equal" << endl;
	else
		cout << "not equal" << endl;

	return 0;
}


5、求大量数据中出现频率最高的k个数

你可能感兴趣的:(c,struct,IE,null)