数据结构3

A二叉链表存储的二叉树

代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
char array[101];
 
//二叉树结点
typedef struct BiTNode{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
 
//按先序序列创建二叉树
int CreateBiTree(BiTree &T,int &index,int &n){
	if(index >= n){
		return 0;
	}
	//按先序次序输入二叉树中结点的值(一个字符),空格表示空树
	if(array[index] == ' '){
		T = NULL;
		index++;
	}
	else{
		T = (BiTree)malloc(sizeof(BiTNode));
		//生成根结点
		T->data = array[index];
		index++;
		//构造左子树
		CreateBiTree(T->lchild,index,n);
		//构造右子树
		CreateBiTree(T->rchild,index,n);
	}
	return 0;
}
//输出
void Visit(BiTree T){
	printf("%c ",T->data);
}
//先序遍历
void PreOrder(BiTree T){
	if(T != NULL){
		//访问根节点
		Visit(T);
		//访问左子结点
		PreOrder(T->lchild);
		//访问右子结点
		PreOrder(T->rchild);
	}
}
//中序遍历
void InOrder(BiTree T){
	if(T != NULL){
		//访问左子结点
		InOrder(T->lchild);
		//访问根节点
		Visit(T);
		//访问右子结点
		InOrder(T->rchild);
	}
}
//后序遍历
void PostOrder(BiTree T){
	if(T != NULL){
		//访问左子结点
		PostOrder(T->lchild);
		//访问右子结点
		PostOrder(T->rchild);
		//访问根节点
		Visit(T);
	}
}
int main()
{
	int len,index;
	while(gets(array)){
		BiTree T;
		len = strlen(array);
		index = 0;
		//创建二叉树
		CreateBiTree(T,index,len);
		//先序遍历
		PreOrder(T);
		printf("\n");
		//中序遍历
		index = 0;
		InOrder(T);
		printf("\n");
		//中序遍历
		index = 0;
		InOrder(T);
		printf("\n");
	}
    return 0;
}

B最小生成树

代码

#include<stdio.h>
#define N 120
int e[N][N],dis[N],book[N];
int main()
{
	int i,j,k,m,n,min,count=0,sum=0,inf=99999999;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)	
			if(i==j)
				e[i][j]=0;
			else
				e[i][j]=inf;
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
		{
			scanf("%d",&e[i][j]);
			//e[j][i]=e[i][j];
			if(i!=j&&e[i][j]==0)
				e[i][j]=e[j][i]=inf;
		}
	
	for(i=1;i<=n;i++)
		dis[i]=e[1][i];
	book[1]=1;
	count++;
	while(count<n)
	{
		min=inf;
		for(i=1;i<=n;i++)
		{
			if(book[i]==0&&dis[i]<min)
			{
				min=dis[i];
				j=i;
			}
		}
		book[j]=1;
		count++;
		sum=sum+dis[j];
		for(k=1;k<=n;k++)
		{
			if(book[k]==0&&dis[k]>e[j][k])
			dis[k]=e[j][k];
		}
	}
	printf("%d\n",sum);
	return 0;
} 

C哈夫曼树

代码

#include<iostream>
#include<queue>
using namespace std;
priority_queue<int,vector<int>,greater<int> > q; 
int main()
{
	int n;
	while(cin>>n){
		while(!q.empty()){
			q.pop();
		}
		for(int i=0;i<n;i++){
			int x;
			cin>>x;
			q.push(x);
		}
		int ans=0;
		while(q.size()>1){
			int a=q.top();
			q.pop();
			int b=q.top();
			q.pop();
			ans+=a+b;
			q.push(a+b);
		}
		cout<<ans<<endl;
	}
	return 0;
} 

D二叉树问题

代码

#include<iostream>
#include<algorithm>
using namespace std;
int dfs(char*pre,char*mid,int n) 
{
	if(n==0)
	{
		return 0;
	}
	int p;
	for(int i=0;i<n;i++)
	{
		if(pre[0]==mid[i]) 
		{
			p=i;
			break;
		}
	}
	int l=dfs(pre+1,mid,p);
	int r=dfs(pre+p+1,mid+p+1,n-p-1);
	return max(l,r)+1;
}
int main()
{
	int n;
	while(scanf("%d",&n)==1)
	{
		char pre[55],mid[55];
		for(int i=0;i<n;i++)
		{
			cin>>pre[i];
		}
		for(int i=0;i<n;i++)
		{
			cin>>mid[i];
		}
		cout<<dfs(pre,mid,n)<<endl;
	}
	return 0;
}

E完全二叉树

题目描述

给定一棵树,你应该指出它是否是一个完全二叉树。 对于每种情况,第一行给出正整数N(≤20),它是树中节点的总数(节点从0到N-1编号)。 然后是N行,第i行对应一个节点i,并给出节点i左右子节点的索引。 如果孩子不存在,则 - 将被置于该位置。 对于每种情况,如果树是完全二叉树,则在一行中打印YES和层序遍历的最后一个节点的索引,或者如果不是,则打印NO和根的索引。 必须有一个空格分隔单词和数字。

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 30;
int n;
int l[N], r[N];
bool hf[N];
int maxCur = -1, nodeId;

void dfs(int u, int cur)
{
    if(cur > maxCur)
    {
        maxCur = cur;
        nodeId = u;
    }
    if(l[u] != -1) dfs(l[u], 2 * cur);
    if(r[u] != -1) dfs(r[u], 2 * cur + 1);
}

int main()
{
    cin >> n;
    for(int i = 0; i < n; i++)
    {
        string a, b;
        cin >> a >> b;
        if(a != "-")
        {
            l[i] = stoi(a);
            hf[stoi(a)] = true;
        }
        else l[i] = -1;
        if(b != "-")
        {
            r[i] = stoi(b);
            hf[stoi(b)] = true;
        }
        else r[i] = -1;
    }
    int root = 0;
    while(hf[root]) root ++;

    dfs(root, 1);
    
    if(maxCur == n)
        cout << "YES" << ' ' << nodeId << endl;
    else
        cout << "NO" << ' ' << root << endl;
}

F树的遍历

题目描述

假设二叉树中的所有键值都是不同的正整数。唯一的二元树可以通过给定的后序和顺序遍历序列,或前序和顺序遍历序列来确定。但是,如果仅给出后序和前序遍历序列,则相应的树可能不再是唯一的。

现在给出一对后序和前序遍历序列,您应该输出树的相应的中序遍历序列。如果树不是唯一的,只需输出其中任何一个。

每个输入文件包含一个测试用例。对于每种情况,第一行给出正整数N(≤30),即二叉树中的节点总数。第二行给出预订序列,第三行给出后序序列。一行中的所有数字都用空格分隔。

对于每个测试用例,如果树是唯一的,则首先是行中的printf,否则是否。然后在下一行中打印相应二叉树的中序遍历序列。如果解决方案不是唯一的,那么任何答案都可以。保证至少存在一种解决方案。一行中的所有数字必须用一个空格分隔,并且行的末尾不能有额外的空格。

代码

#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;

vector<int> preOrder;
vector<int> postOrder;
vector<int> result;

bool unique = true;

class binNode {
public:
    int data;
    binNode* lchild;
    binNode* rchild;
};

binNode* buildTree(int preL, int preR, int postL, int postR) {
	if (preL > preR) return 0;//退出条件
	int root = preL;
	binNode* node = new binNode;
	node->data = postOrder[postR];
	node->lchild = 0;
	node->rchild = 0;
	if (postR != postL) {//当只有一个元素的时候不需要进行子树迭代操作
		while (postOrder[postR - 1] != preOrder[root]) root++;
		if (root == preL + 1) unique = false;//当并排时设置成false
		node->lchild = buildTree(preL + 1, root - 1, postL, postL + root - preL - 2);
		node->rchild = buildTree(root, preR, postL + root - preL - 1, postR - 1);
	}

	return node;
}

void inTravel(binNode* tree) {
    if (tree->lchild != NULL) inTravel(tree->lchild);
    result.push_back(tree->data);
    if (tree->rchild != NULL) inTravel(tree->rchild);
}

int main()
{
    int n;
    cin >> n;
    int num;
    for (int i = 0; i < n; i++) {
        cin >> num;
        preOrder.push_back(num);
    }
    for (int i = 0; i < n; i++) {
        cin >> num;
        postOrder.push_back(num);
    }
    binNode* tree = buildTree(0, n - 1, 0, n - 1);
    if (unique) {
        cout << "Yes" << endl;
    }
    else {
        cout << "No" << endl;
    }
    inTravel(tree);
    for (int i = 0; i < n; i++) {
        cout << result[i];
        if (i + 1 != n) cout << " ";
    }
    cout << endl;//貌似得加个换行,我也不太清楚为什么,不然格式错误
}


  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值