BJFU|数据结构A(22下)实验4——严蔚敏版教材头歌系统

仅供课外学习使用,任何个人与机构不得利用此文章进行任何形式的作弊。

01基于哈夫曼树的数据压缩算法

#include<iostream>
#include<string.h>
#define MAXSIZE 100
using namespace std;
typedef struct
{//哈夫曼树结点的形式
	int weight;               //结点的权值
	int parent,lchild,rchild;  //结点的双亲、左孩子、右孩子的下标
}HTNode,*HuffmanTree;       //动态分配数组存储哈夫曼树
typedef char **HuffmanCode;   //定义编码表类型
int Search(char a[],char ch)
{//查找数组中字符ch所在的位置,返回数组下标,否则返回-1
	int flag = -1;
	for(int i = 0; i < (int)strlen(a); i++)
	{
		if(a[i] == ch)
		{
			flag = i;
			break;
		}
	}
	return flag;
}
void Sort(char a[],int b[],int len)
{//按ASCII码冒泡排序
	for(int i = 0; i < len; i++)
		for(int j = 0; j < len - i - 1; j++)
		{
			if(a[j] > a[j + 1])
			{
				char ta; int tb;
				ta = a[j + 1];
				a[j + 1] = a[j];
				a[j] = ta;
				tb = b[j + 1];
				b[j + 1] = b[j];
				b[j] = tb;
			}
		}
}
void Select_min(HuffmanTree HT,int n,int &s1,int &s2)
{// 在HT[k](1≤k≤i-1)中选择两个其双亲域为0且权值最小的结点,并返回它们在HT中的序号s1和s2
	int m1 = 10086, m2 = 10086;
	for(int i = 1; i <= n; i++)
	{
		if(HT[i].parent == 0 && m1 > HT[i].weight)
		{
			m2 = m1;
			m1 = HT[i].weight;
			s2 = s1;
			s1 = i;
			continue;
		}
		if(HT[i].parent == 0 && m2 > HT[i].weight)
		{
			m2 = HT[i].weight;
			s2 = i;
			continue;
		}
	}
}
int m;
void CreateHuffmanTree(HuffmanTree &HT,int n,int b[])
{//构造哈夫曼树HT
	if(n <= 1) return;
	m = 2 * n - 1;
	HT = new HTNode[m + 1];
	for(int i = 1; i <= m; i++)
	{
		HT[i].parent = 0;
		HT[i].lchild = 0;
		HT[i].rchild = 0;
	}
	for(int i = 1; i <= n; i++)
	{		
		HT[i].weight = b[i - 1];
	}
	int s1 = 0, s2 = 0;
	for(int i = n + 1; i <= m; i++)
	{
		Select_min(HT, i - 1, s1, s2);
		HT[s1].parent = i;
		HT[s2].parent = i;
		HT[i].lchild = s1;
		HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;
	}
}
void CreateHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)
{//从叶子到根逆向求每个字符的哈夫曼编码,存储在编码表HC中
	HC = new char*[n + 1];
	char* cd = new char[n];
	cd[n - 1] = '\0';
	for(int i = 1; i <= n; i++)
	{
		int start = n - 1;
		int c = i;
		int f = HT[i].parent;
		while(f != 0)
		{
			--start;
			if(HT[f].lchild == c)
				cd[start] = '0';
			else
				cd[start] = '1';
			c = f;
			f = HT[f].parent;
		}
		HC[i] = new char[n - start];
		strcpy(HC[i], &cd[start]);
	}
	delete cd;
}

void CharFrequency(char ch[],char a[],int b[],int &j)
{//统计词频
	for(int i = 0; i < (int)strlen(ch); i++)
	{
		for(int k = 0; k <= 26; k++)
		{
			if(a[k] == ch[i]) 
			{
				b[k]++;
				break;
			}
			if(a[k] == '\0')
			{
				j++;
				a[k] = ch[i];
				b[k]++;
				break;
			}
		}
	}
}

void PrintHT(HuffmanTree HT)
{//输出哈夫曼树的存储结构的终态
	for(int i = 1; i <= m; i++)
		cout << i << " " << HT[i].weight << " " << HT[i].parent << " " << HT[i].lchild << " " << HT[i].rchild << endl;
}
void PrintHC(HuffmanCode HC,char a[],int j)
{//输出每个字符的哈夫曼编码
	for(int i = 1; i <= j; i++)
	{
		if(i != 1)
			cout << " "; 
		cout << a[i - 1] << ":" << HC[i];
	}
	cout << endl;
}

int main()
{
	char ch[MAXSIZE];
	int i,j;
	while(cin>>ch)
	{
		if(ch[0]=='0') break;
		HuffmanTree HT;
		char a[MAXSIZE]={'\0'};
		int b[MAXSIZE]={0};
		j=0;      //j统计不同字符的数量
		CharFrequency(ch,a,b,j);   //统计词频
		Sort(a,b,j);     //按ASCII码冒泡排序
		for(i=0;a[i]!='\0';i++)   //输出统计出来的字符和出现频率
		{
			if(a[i+1]!='\0')
				cout<<a[i]<<":"<<b[i]<<" ";
			else
				cout<<a[i]<<":"<<b[i]<<endl;
		}
		//构造哈夫曼树
		CreateHuffmanTree(HT,i,b);    //构造哈夫曼树HT
		PrintHT(HT);      //输出哈夫曼树的存储结构的终态
		//哈夫曼编码
		HuffmanCode HC;    //编码表HC
		CreateHuffmanCode(HT,HC,j);
		PrintHC(HC,a,j);    //输出每个字符的哈夫曼编码
		int k;
		for(i=0;ch[i]!='\0';i++)    //输出编码后的字符串
		{
			for(k=0;k<j;k++)
			{
				if(ch[i]==a[k])
					cout<<HC[k+1];
			}
		}
		cout<<endl;
		cout<<ch<<endl;//输出解码后的字符串(与输入的字符串相同)
	}
	return 0;
}

02基于二叉链表的树结构相等的判断

#include<iostream>
using namespace std;
typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T,char S[],int &i)
{先序建立二叉树
	if(S[i] == '0') 
		T = NULL;
	else
	{
		T = new BiTNode;
		T->data = S[i];
		CreateBiTree(T->lchild, S, ++i);
		CreateBiTree(T->rchild, S, ++i);
	}
}
int Compare(BiTree T1,BiTree T2)
{//判断两棵二叉树是否相等,不相等返回0,相等返回1	
	if(!T1 && !T2)
		return 1;
	if((T1 && !T2) || (!T1 && T2))
		return 0;
	if(T1 && T2)
	{
		if(T1->data != T2->data)
			return 0;
		else
		{
			int a = Compare(T1->lchild, T2->lchild);
			int b = Compare(T1->rchild, T2->rchild);
			return (a && b);
		}
	}
}

int main()
{
	char S1[100],S2[100];
	while(cin>>S1&&S1[0]!='0')
	{
		cin>>S2;
		int i=-1,j=-1;
	  	BiTree T1,T2;
		CreateBiTree(T1,S1,++i);
		CreateBiTree(T2,S2,++j);
		if(!Compare(T1,T2))
			cout<<"NO"<<endl;
		else
			cout<<"YES"<<endl;
	}
	return 0;
}
 

03基于二叉链表的二叉树左右孩子的交换

#include<iostream>
#include<cstring>
using namespace std;
typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T,char S[],int &i)
{//先序建立二叉树
	if(S[i] == '0') 
		T = NULL;
	else
	{
		T = new BiTNode;
		T->data = S[i];
		CreateBiTree(T->lchild, S, ++i);
		CreateBiTree(T->rchild, S, ++i);
	}
}
void ChangeRL(BiTree &T)
{//二叉树左右孩子的交换
	if(T && (T->lchild || T->rchild))
	{
		BiTree t = new BiTNode;
		t = T->rchild;
		T->rchild = T->lchild;
		T->lchild = t;
		ChangeRL(T->lchild);
		ChangeRL(T->rchild);
	}
}
void PreOrderTraverse(BiTree T)
{//先序遍历
	if(T)
	{
		cout << T->data;
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	}
}

int main()
{
	char S[100];
	while(cin>>S)
    {
        if(strcmp(S,"0")==0) break;
		int i=-1;
	  	BiTree T;
		CreateBiTree(T,S,++i);
		ChangeRL(T);
		PreOrderTraverse(T);
		cout<<endl;
	}
	return 0;
}

04基于二叉链表的二叉树的双序遍历

#include<iostream>
#include <string.h>
using namespace std;
typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T,char S[],int &i)
{//先序建立二叉树
	if(S[i] == '0') 
		T = NULL;
	else
	{
		T = new BiTNode;
		T->data = S[i];
		CreateBiTree(T->lchild, S, ++i);
		CreateBiTree(T->rchild, S, ++i);
	}
}
void DoubleTraverse(BiTree T)
{//双序遍历二叉树T的递归算法
	if(T)
	{
		cout << T->data;
		DoubleTraverse(T->lchild);
		cout << T->data;
		DoubleTraverse(T->rchild);
	}
}

int main()
{
	char S[100];
	while(cin>>S)
    {
        if(strcmp(S,"0")==0) break;
        int i=-1;
	  	BiTree T;
		CreateBiTree(T,S,++i);
		DoubleTraverse(T);
		cout<<endl;
	}
	return 0;
}

05基于二叉链表的二叉树最大宽度的计算

#include <iostream>
#include <string.h>
using namespace std;

typedef struct BiTNode
{
    char data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

BiTree CreateBiTree(int &pos, char *str)
{// 先序建立二叉树
	BiTree T;
	if(str[pos] == '0')
		T = NULL;
	else
	{
		T = new BiTNode;
		T->data = str[pos];
		T->lchild = CreateBiTree(++pos, str);
		T->rchild = CreateBiTree(++pos, str);
	}
	return T;
}

int Width(BiTree T)
{// 求二叉树T最大宽度
	if(!T)
		return 0;
	BiTree B[1000];
	int front = 1, rear = 1, last = 1, width = 0, maxw = 0;
	B[rear] = T;
	while(front <= last)
	{
		width++;
		BiTree t = B[front++];
		if(t->lchild)
			B[++rear] = t->lchild;
		if(t->rchild)
			B[++rear] = t->rchild;
		if(front > last)
		{
			last = rear;
			if(maxw < width)
				maxw = width;
			width = 0;
		}
	}
	return maxw;
}

int main()
{
    char str[1000];
    while(cin>>str)
    {
        if(strcmp(str,"0")==0) break;
        int pos=0;                         // 标记字符串处理位置
        BiTree root=CreateBiTree(pos,str);
        cout<<Width(root)<<endl;
    }
    return 0;
}

06基于二叉链表的二叉树最长路径的求解

 #include<iostream>
#define MAXSIZE 100
using namespace std;
typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T,char S[],int &i)
{//先序建立二叉树
	if(S[i] == '0') 
		T = NULL;
	else
	{
		T = new BiTNode;
		T->data = S[i];
		CreateBiTree(T->lchild, S, ++i);
		CreateBiTree(T->rchild, S, ++i);
	}
}
int len;
void LongestPath(BiTree T,BiTree l[],int &longest)
{//二叉树最长路径的求解
	if(T)
	{
		len++;
		if(!T->lchild && !T->rchild)
		{
			if(longest < len)
			{
				longest = len;
				l[len] = T;
				len--;
				return ;
			}
		}
		else if(T->lchild)
		{
			LongestPath(T->lchild, l, longest);
			if(l[len + 1]->data == T->lchild->data)
				l[len] = T;
		}
		else if(T->rchild)
		{
			LongestPath(T->rchild, l, longest);
			if(l[len + 1]->data == T->rchild->data)
				l[len] = T;
		}
	}
	len--;
}

int main()
{
	char S[100];
	while(cin>>S&&S[0]!='0')
	{
		int i=-1;
		BiTree T;
        BiTree l[MAXSIZE];
        int longest=0;
		CreateBiTree(T,S,++i);
		LongestPath(T,l,longest);
        cout<<longest<<endl;
       for(int k=1;k<=longest;k++)
          cout<<l[k]->data;
       cout<<endl;
	}
	return 0;
}

07基于二叉链表的二叉树叶子结点到根结点的路径的求解

#include<iostream>
using namespace std;
typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T,char S[],int &i)
{//先序建立二叉树
	if(S[i] == '0') 
		T = NULL;
	else
	{
		T = new BiTNode;
		T->data = S[i];
		CreateBiTree(T->lchild, S, ++i);
		CreateBiTree(T->rchild, S, ++i);
	}	
}
void AllPath(BiTree T,char path[],int pathlen)
{//二叉树叶子结点到根结点的路径的求解
	if(T)
	{
		if(!T->lchild && !T->rchild)
		{
			path[pathlen] = T->data;
			for(int i = pathlen; i >= 0; i--)
				cout << path[i];
			cout << endl;
		}
		else
		{
			path[pathlen] = T->data;
			pathlen++;
			AllPath(T->lchild, path, pathlen);
			AllPath(T->rchild, path, pathlen);
			pathlen--;
		}
	} 
}

char path[100];  //路径数组,存储路径上每个结点的值

int main()
{
	char S[100];
	while(cin>>S&&S[0]!='0')
	{
		int i=-1;
		BiTree T;
		CreateBiTree(T,S,++i);
		int pathlen=0;         //初始化路径到根结点的长度为0
        AllPath(T,path,pathlen);
	}
	return 0;
}

08基于二叉链表的二叉树的遍历

#include<iostream>
#include<string.h>
using namespace std;
typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T,char S[],int &i)
{//先序建立二叉树
	if(S[i] == '0') 
		T = NULL;
	else
	{
		T = new BiTNode;
		T->data = S[i];
		CreateBiTree(T->lchild, S, ++i);
		CreateBiTree(T->rchild, S, ++i);
	}
}
void PreOrderTraverse(BiTree T)
{//二叉树的先序遍历
	if(T)
	{
		cout << T->data;
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	}
}

void InOrderTraverse(BiTree T)
{//二叉树的中序遍历
	if(T)
	{
		InOrderTraverse(T->lchild);
		cout << T->data;
		InOrderTraverse(T->rchild);
	}
}
void PostOrderTraverse(BiTree T)
{//二叉树的后序遍历
	if(T)
	{
		PostOrderTraverse(T->lchild);
		PostOrderTraverse(T->rchild);
		cout << T->data;
	}
}
int flag;

int main()
{
	char S[100];
	while(cin>>S)
	{
		if(strcmp(S,"0")==0) break;
		int i=-1;
	  	BiTree T;
		CreateBiTree(T,S,++i);
		PreOrderTraverse(T);
		cout<<endl;
  	    InOrderTraverse(T);
		cout<<endl;
		PostOrderTraverse(T);
		cout<<endl;
	}
	return 0;
}

09基于二叉链表的二叉树结点个数的统计

#include<iostream>
#include<string.h>
using namespace std;

typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T,char S[],int &i)
{//先序建立二叉树
	if(S[i] == '0') 
		T = NULL;
	else
	{
		T = new BiTNode;
		T->data = S[i];
		CreateBiTree(T->lchild, S, ++i);
		CreateBiTree(T->rchild, S, ++i);
	}
}
void Count(BiTree T,int &a,int &b,int &c)
{//二叉树结点个数的统计
	if(T)
	{
		if(T->lchild && T->rchild)
			c++;//2
		else if((!T->lchild && T->rchild) || (T->lchild && !T->rchild))
			b++;//1
		else if(!T->lchild && !T->rchild)
			a++;//0
		Count(T->lchild, a, b, c);
		Count(T->rchild, a, b, c);	
	}
}

int main()
{
	
	char S[100];
	while(cin>>S)
	{
	    if(strcmp(S,"0")==0) break;
		int a=0,b=0,c=0;
      	int i=-1;
	  	BiTree T;
		CreateBiTree(T,S,++i);
		Count(T,a,b,c);
		cout<<a<<" "<<b<<" "<<c<<endl;
	}
	return 0;
}

10基于二叉链表的二叉树高度的计算

#include<iostream>
#include <string.h>
using namespace std;
typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T,char S[],int &i)
{//先序建立二叉树
	if(S[i] == '0') 
		T = NULL;
	else
	{
		T = new BiTNode;
		T->data = S[i];
		CreateBiTree(T->lchild, S, ++i);
		CreateBiTree(T->rchild, S, ++i);
	}
}
int Depth(BiTree T)
{//二叉树高度的计算
	if(!T)
		return 0;
	int ll = Depth(T->lchild);
	int lr = Depth(T->rchild);
	if(ll >= lr) return ll + 1;
	else return lr + 1;
}

int main()
{
	char S[100];
	while(cin>>S)
	{
	    if(strcmp(S,"0")==0) break;
		int i=-1;
	  	BiTree T;
		CreateBiTree(T,S,++i);
		cout<<Depth(T)<<endl;
	}
	return 0;
}

11基于二叉树的表达式求值

#include<iostream>
#include<cstring>
#define MAXSIZE 100
using namespace std;
typedef struct BiTNode
{//二叉树的双链表存储表示
	double data;          //结点数据域
	bool ischaracter;      //判断结点是否为字符
	struct BiTNode *lchild,*rchild;    //左右孩子指针
}BiTNode,*BiTree;
typedef struct
{//字符栈的存储结构
	char *base;     //栈底指针
	char *top;       //栈顶指针
	int stacksize;   //栈可用的最大容量
}SqStack1;
typedef struct
{//结点栈的存储结构
	BiTree *base;
	BiTree *top;
	int stacksize;
}SqStack2;
void InitStack1(SqStack1 &s)
{//字符栈的初始化
	s.base = new char[MAXSIZE];
	if(!s.base) exit(-1);
	s.top = s.base;
	s.stacksize = MAXSIZE;
}
void InitStack2(SqStack2 &s)
{//结点栈的初始化
	s.base = new BiTree[MAXSIZE];
	if(!s.base) exit(-1);
	s.top = s.base;
	s.stacksize = MAXSIZE;	
}
void Push1(SqStack1 &s,char ch)
{//字符入栈操作
	if(s.top - s.base == s.stacksize) exit(-1);
	*s.top++ = ch;	
}
void Push2(SqStack2 &s,BiTree t)
{//结点入栈操作
	if(s.top - s.base == s.stacksize) exit(-1);
	*s.top++ = t;	
}

void Pop1(SqStack1 &s,char &ch)
{//字符出栈操作
	ch = *--s.top;	
}
void Pop2(SqStack2 &s,BiTree &t)
{//结点出栈操作
	t = *--s.top;	
}
char GetTop(SqStack1 s)
{//取字符栈的栈顶元素
	return *(s.top - 1);
}
bool EmptyStack(SqStack1 s)
{//栈的判空操作
	if(s.top == s.base)
		return true;
	else
		return false;
}
char Precede(char a,char b)
{//判断符号的优先级
	switch (a) 
	{
		case '+':
		case '-':
			switch (b) 
			{
				case '+':
				case '-':
				case ')':
				case '=':
					return '>';
					break;
				case '*':
				case '/':
				case '(':
					return '<';
					break;
			}
			break;
		case '*':
		case '/':
			switch (b) 
			{
				case '+':
				case '-':
				case '*':
				case '/':
				case ')':
				case '=':
					return '>';
					break;
				case '(':
					return '<';
					break;
			}
			break;		
		case '(':
			switch (b) 
			{
				case '+':
				case '-':
				case '*':
				case '/':
				case '(':
					return '<';
					break;
				case ')':
					return '=';
					break;
			}
			break;
		case ')':
			switch (b) 
			{
				case '+':
				case '-':
				case '*':
				case '/':
				case ')':
				case '=':
					return '>';
					break;
			}
			break;	
		case '=':
			switch (b) 
			{
				case '+':
				case '-':
				case '*':
				case '/':
				case '(':
					return '<';
					break;
				case '=':
					return '=';
					break;
			}
			break;
	}
	return -1;
}
double Operate(double a,char ch,double b)
{//运算操作,返回相应的数值结果
    switch (ch) 
	{
		case '+':
			return a + b;
			break;
		case '-':
			return a - b;
			break;
		case '*':
			return a * b;
			break;
		case '/':
			if(b == 0) return -1;
			return a / b;
			break;			
		default:
			return -1;
			break;
	}   
}
bool IsCharacter(char ch)
{//判断ch是否为+、-、*、/、(、)、= 这类的字符,是则返回true
	bool flag = false;
	if(ch == '+' || ch == '-')
		flag = true;
	if(ch == '*' || ch == '/')
		flag = true;
	if(ch == '(' || ch == ')' || ch == '=')
		flag = true;	
	return flag;
}
double InOrder(BiTree T)
{//中序遍历二叉树并求表达式的值
	if(!T)
		return 0;
	if(!T->lchild && !T->rchild)
		return T->data;
	else
	{
		int lv = 0, rv = 0;
		lv = InOrder(T->lchild);
		rv = InOrder(T->rchild);
		return Operate(lv, T->data, rv);
		
	}
}
void CreateBT(char ch[],BiTree &t,SqStack1 optr,SqStack2 expt)
{//创建二叉树
	for(int i = 0; i < (int)strlen(ch);)
	{
		if(!IsCharacter(ch[i]))
		{
			BiTree T = new BiTNode;
			T->data = ch[i] - '0';
			T->ischaracter = 0;
			T->lchild = NULL;
			T->rchild = NULL;
			Push2(expt, T);
			i++;
		}
		else
		{
			char sb;
			switch (Precede(GetTop(optr), ch[i])) 
			{
				case '<':
					Push1(optr, ch[i++]);
					break;
				case '=':
					Pop1(optr, sb);
					i++;
					break;
				case '>':
					GetTop(optr);
					Pop1(optr, sb);
					BiTree rc;
					Pop2(expt, rc);
					BiTree lc;
					Pop2(expt, lc);
					BiTree rt = new BiTNode;
					rt->data = sb;
					rt->ischaracter = 1;
					rt->lchild = lc;
					rt->rchild = rc;
					Push2(expt, rt);
					break;
			}
			
		}
	}
	Pop2(expt, t);
}

int main()
{
	char ch[MAXSIZE];
	while(cin>>ch)
	{
		if(ch[0]=='=') break;
		BiTree t;
		SqStack1 optr;      //运算符栈optr
		SqStack2 expt;        //数字栈expt
		InitStack1(optr);     //初始化栈
		InitStack2(expt);     //初始化栈
		Push1(optr,'=');    //先在运算符栈底放入一个'='
		CreateBT(ch,t,optr,expt);       //创建二叉树
		double answer=InOrder(t);
		cout<<answer<<endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

CresCent_Charles

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

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

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

打赏作者

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

抵扣说明:

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

余额充值