【数据结构】二叉树的多种功能(创建、求xx、遍历非递归、线索化遍历、哈夫曼树和编码)

1.利用二叉树字符串“A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))”创建二叉树的二叉链式存储结构;

2.输出该二叉树;

3.输出‘H’节点的左、右孩子结点值;

4.输出该二叉树的结点个数、叶子结点个数、二叉树的度和高度;

#include <iostream>
using namespace std;

int num=0;
int lnum = 0;
int wnum = 0;

struct Node
{
	char data;
	struct Node* left;
	struct Node* right;
};

bool search(Node* root, char data)//搜索结点的左右孩子
{
	if (root == NULL)
	{
		return 0;
	}
	else if (root->data == data)
	{
		cout << root->data << "的左子树是:" << root->left->data << endl;
		cout << root->data << "的右子树是:" << root->right->data << endl;
	}
	else
	{
		search(root->left, data) || search(root->right, data);
	}
}

void nodenum(Node* root)//结点数量
{
	if (root != NULL)
	{
		num++;
		nodenum(root->left);
		nodenum(root->right);
	}
}

void leafnum(Node* root)//叶子数量
{
	if (root != NULL && root->left == NULL && root->right == NULL)
	{
		lnum++;
	}
	else if (root != NULL)
	{
		leafnum(root->left);
		leafnum(root->right);
	}
}

int get_height(Node* root)//求高度
{
	if (root == NULL)
	{
		return 0;
	}
	else
	{
		int left_h = get_height(root->left);
		int right_h = get_height(root->right);
		int max = left_h;
		if (right_h > max)
		{
			max = right_h;
		}
		return max + 1;
	}
}

void waynum(Node* root)//二叉树的度
{
	if (wnum == 2) return;
	else if (root != NULL && root->left && root->right)
	{
		wnum = 2;
	}
	else if (root->left || root->right)
	{
		if (wnum <= 1)
		{
			wnum = 1;
		}
		if (root->left) waynum(root->left);
		if (root->right) waynum(root->right);
	}
}

void preorder(Node* root)//先序遍历
{
	if (root != NULL)
	{
		cout << root->data <<" ";
		preorder(root->left);
		preorder(root->right);
	}
}


void create(Node*& head, string s)
{
	static int i = 0;
	while (i < s.size())
	{
		if (s[i]>='A'&&s[i]<='Z'&&head == NULL)
		{
			head = new Node;
			head->data = s[i];
			head->left = NULL;
			head->right = NULL;
			i++;
		}
		else if (s[i] >= 'A' && s[i] <= 'Z' && head != NULL)
		{
			create(head->right, s);
		}
		else if (s[i] == '(')
		{
			i++;
			create(head->left, s);
		}
		else if (s[i] == ',')
		{
			i++;
			return;
		}
		else if (s[i] == ')')
		{
			i++;
			return;
		}
	}
}


int main()
{
	string s = "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))";
	Node* root = NULL;
	create(root, s);

	cout << "该二叉树为:" << endl;
	preorder(root);
	cout << endl;

	int h = get_height(root);
	cout << "高度为:" << h << endl;

	search(root, 'H');//输出'H'结点的左右孩子

	nodenum(root);//结点个数
	cout << "结点个数为:" << num << endl;

	leafnum(root);//叶子数量
	cout << "叶子数量为:" << lnum << endl;

	waynum(root);//二叉树的度
	cout << "该二叉树的度为:" << wnum << endl;
}

实现上述二叉树的先序、中序和后序遍历的递归和非递归算法

#include <iostream>
#include<stack>
using namespace std;

int num = 0;
int lnum = 0;
int wnum = 0;

struct Node
{
	char data;
	struct Node* left;
	struct Node* right;
};


void preorder(Node* root)//先序遍历递归
{
	if (root != NULL)
	{
		cout << root->data << " ";
		preorder(root->left);
		preorder(root->right);
	}
}

void preorder1(Node* root)//先序遍历非递归
{
	stack<Node*>s;
	Node* p = root;
	while (p != NULL || !s.empty())
	{
		while (p != NULL)//沿着左支走到底,用栈记录走过的路线
		{
			cout << p->data << " ";
			s.push(p);
			p = p->left;
		}
		//当左边走到尽头时,若栈里面还有结点,则退栈,后退到根结点,并进入右支
		if (!s.empty())
		{
			p = s.top();
			s.pop();
			p = p->right;
		} 
	}
}

void inorder(Node* root)//中序遍历递归
{
	if (root != NULL)
	{
		inorder(root->left);
		cout << root->data << " ";
		inorder(root->right);
	}
}

void inorder1(Node* root)//中序遍历非递归
{
	stack<Node*>s;
	Node* p = root;
	while (p != NULL || !s.empty())
	{
		while (p != NULL)
		{
			s.push(p);
			p = p->left;
		}
		if (!s.empty())
		{
			p = s.top();
			s.pop();
			cout << p->data << " ";
			p = p->right;
		}
	}
}


void postorder(Node* root)//后序遍历递归
{
	if (root != NULL)
	{
		postorder(root->left);
		postorder(root->right);
		cout << root->data << " ";
	}
}

void postorder1(Node* root)//后序遍历非递归
{
	stack<Node*>s;
	Node* p = root;
	Node *r = NULL;
	while (p != NULL || !s.empty())
	{
		if (p != NULL)
		{
			s.push(p);
			p = p->left;
		}
		else
		{
			p = s.top();
			if (p->right != NULL && p->right != r)//右子树存在,未被访问
			{
				p = p->right;
			}
			else
			{
				s.pop();
				cout << p->data<<" ";
				r = p;//记录访问过的结点
				p = NULL;//重置
				
			}
		}
	}
}

void create(Node*& head, string s)
{
	static int i = 0;
	while (i < s.size())
	{
		if (s[i] >= 'A' && s[i] <= 'Z' && head == NULL)
		{
			head = new Node;
			head->data = s[i];
			head->left = NULL;
			head->right = NULL;
			i++;
		}
		else if (s[i] >= 'A' && s[i] <= 'Z' && head != NULL)
		{
			create(head->right, s);
		}
		else if (s[i] == '(')
		{
			i++;
			create(head->left, s);
		}
		else if (s[i] == ',')
		{
			i++;
			return;
		}
		else if (s[i] == ')')
		{
			i++;
			return;
		}
	}
}


int main()
{
	string s = "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))";
	Node* root = NULL;
	create(root, s);

	cout << "先序遍历:" << endl;
	preorder(root);cout << endl;
	preorder1(root);cout << endl;
	cout << "---------------------------"<<endl;
	cout << "中序遍历:" << endl;
	inorder(root);cout << endl;
	inorder1(root);cout << endl;
	cout << "---------------------------" << endl;
	cout << "后序遍历:" << endl;
	postorder(root);cout << endl;
	postorder1(root);cout << endl;

}

中序线索化上述二叉树并找出根结点的前驱和后继。

#include <iostream>
#include<stack>
using namespace std;

int num = 0;
int lnum = 0;
int wnum = 0;

struct Node
{
	char data;
	struct Node* left;
	struct Node* right;
	int ltag = 0;
	int rtag = 0;
};

void show(Node* root)
{
	cout << "字母" << root->data;
	if (root->ltag == 1)
	{
		cout << "的前驱为:" << root->left->data;
	}
	else
	{
		Node* temp = root->left;
		while (temp->rtag == 0)
		{
			temp = temp->right;
		}
		cout << "的前驱为:" << temp->data;
	}
	if (root->rtag == 1)
	{
		cout << ",后继为:" << root->right->data << endl;
	}
	else
	{
		Node* temp = root->right;
		while (temp->ltag == 0)
		{
			temp = temp->left;
		}
		cout << ",后继为:" << temp->data << endl;
	}
}

void inTherad(Node* root, Node*& pre)
{
	if (root != NULL)
	{
		inTherad(root->left, pre);
		if (root->left == NULL)
		{
			root->left = pre;
			root->ltag = 1;
		}
		if (pre != NULL && pre->right == NULL)
		{
			pre->right = root;
			pre->rtag = 1;
		}
		pre = root;
		inTherad(root->right, pre);
	}
}

void create(Node*& head, string s)
{
	static int i = 0;
	while (i < s.size())
	{
		if (s[i] >= 'A' && s[i] <= 'Z' && head == NULL)
		{
			head = new Node;
			head->data = s[i];
			head->left = NULL;
			head->right = NULL;
			i++;
		}
		else if (s[i] >= 'A' && s[i] <= 'Z' && head != NULL)
		{
			create(head->right, s);
		}
		else if (s[i] == '(')
		{
			i++;
			create(head->left, s);
		}
		else if (s[i] == ',')
		{
			i++;
			return;
		}
		else if (s[i] == ')')
		{
			i++;
			return;
		}
	}
}


int main()
{
	string s = "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))";
	Node* root = NULL;
	Node* pre = NULL;
	create(root, s);
	inTherad(root, pre);
    show(root);

}

统计下面一段英文的不同字符个数和每个字符的出现频率,利用统计数据构造构造哈夫曼树和哈夫曼编码

The Chinese official said he viewed the Trump Presidency not as an aberration but as the product of a failing political system. This jibes with other accounts. The Chinese leadership believes that the United States, and Western democracies in general, haven’t risen to the challenge of a globalized economy, which necessitates big changes in production patterns, as well as major upgrades in education and public infrastructure. In Trump and Trumpism, the Chinese see an inevitable backlash to this failure.

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

string s = "The Chinese official said he viewed the Trump Presidency not as an aberration but as the product of a failing political system. This jibes with other accounts. The Chinese leadership believes that the United States, and Western democracies in general, haven't risen to the challenge of a globalized economy, which necessitates big changes in production patterns, as well as major upgrades in education and public infrastructure. In Trump and Trumpism, the Chinese see an inevitable backlash to this failure.";

struct Node
{
	double data;
	char ch;
	struct Node* left;
	struct Node* right;
	int parent = 0;
	string code = "";

	Node(char ch1, double data1)
	{
		ch = ch1;
		data = data1;
		left = NULL;
		right = NULL;
		parent = 0;
		code = "";
		
	};
};

void create(map<char, int>& m, vector<Node*>& v)
{
	for (int i = 0; i < s.size(); i++)
	{
		if ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z'))
		{
			if (m.count(s[i]) > 0)
			{
				m[s[i]]++;
			}
			else
			{
				m.insert(pair<char, int>(s[i], 1));
			}
		}
	}
	int total = 0;
	map<char, int>::iterator iter;
	for (iter = m.begin();iter != m.end();iter++)
	{
		total += iter->second;
	}
	for (iter = m.begin();iter != m.end();iter++)
	{
		double times = iter->second;
		double rate = times / total;
		Node* temp = new Node(iter->first, rate);
		v.push_back(temp);
	}
}

void search(vector<Node*>& v, int* p1, int* p2)
{
	int i;
	for (i = 0;i < v.size() && v[i]->parent != 0;i++)
	{
		;
	}
	*p1 = i;
	for (i;i < v.size();i++)
	{
		if (v[i]->parent == 0 && v[i]->data < v[*p1]->data)
		{
			*p1 = i;
		}
	}
	for (i = 0;i < v.size();++i)
	{
		if (v[i]->parent == 0 && i != *p1)
		{
			break;
		}
	}
	*p2 = i;
	for (i;i < v.size();i++)
	{
		if (v[i]->parent == 0 && v[i]->data < v[*p2]->data && i != *p1)
			*p2 = i;
	}
}

bool judge(vector<Node*>& v)
{
	for (int i = 0;i < v.size();i++)
	{
		if (v[i]->parent == 0)
		{
			return false;
		}
	}
	return true;
}

void createhuffman(vector<Node*>v, Node*& root)
{
	int p1, p2;
	Node* head = NULL;
	while (1)
	{
		search(v, &p1, &p2);
		v[p1]->parent = 1;
		v[p2]->parent = 1;
		Node* parent = new Node(' ', v[p1]->data + v[p2]->data);
		parent->left = v[p1];
		parent->right = v[p2];
		head = parent;
		if (!judge(v))
		{
			v.push_back(parent);
		}
		else
			break;
	}
	root = head;
}

void coding(Node* root, string s)
{
	if (root == NULL)
	{
		return;
	}
	root->code = s;
	coding(root->left, s + "0");
	coding(root->right, s + "1");
}
int main()
{
	map<char, int>m;
	vector<Node*> v;
	create(m, v);
	Node* root = NULL;
	createhuffman(v, root);
	coding(root, "");
	for (int i = 0;i < v.size();i++)
	{
		cout << v[i]->ch << "的频率为:" << v[i]->data << ",哈夫曼编码为:" << v[i]->code << endl;
	}
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值