DS W12

目录

1811 求二叉树最小值_二叉树求最小值_a little funny的博客-CSDN博客

1809 三色二叉树 (7条消息) 洛谷P2585&ZJOI 2006-三色二叉树(树的染色-树形DP)_lonely_wind_的博客-CSDN博客

1802 (7条消息) 动态规划求树的最大连通分支问题_. 输入含有 n 个顶点的加权二叉树 t 和正数 τ,树 t 上每条边的权值都非负,树中顶_hnu哈哈的博客-CSDN博客

1821 判断完全二叉树(顺序存储)_牛客博客 (nowcoder.net)

1801 B - 树与二叉树_b树和二叉树_米诺minoz的博客-CSDN博客

1412 二叉树的繁茂度_Felven的博客-CSDN博客 

1820 C  加分二叉树 - DWVictor - 博客园 (cnblogs.com)

2123 B(广义表生成二叉树)的高度和宽度

1806 C 求二叉树中节点的深度 

1818 A HFM Basic

1818 F HFM coding


1811 求二叉树最小值_二叉树求最小值_a little funny的博客-CSDN博客

C++版本的(DFS)

#include <iostream>
#include <cstring>
#include <stdio.h>

using namespace std;
 
#define MAXN 100100
 
#define Min(a,b) ((a)<(b)?(a):(b))
 
struct Graph {
	int vex, next;
} G[MAXN << 1]; //边存了两遍。
 
int first[MAXN], mn, md;
bool flag[MAXN];
 
void DFS(int pos, int dep) {
	int tot; flag[pos] = true;
	if (dep >= md) {
		if (dep > md) {md = dep; mn = pos;}
		else if (pos < mn) mn = pos;}
	for (tot = first[pos]; tot != -1; tot = G[tot].next) 
		if (!flag[G[tot].vex]) DFS(G[tot].vex, dep + 1);}

 
int main() {
	int n, i, tot, s, e, a;
	while (scanf("%d", &n) != EOF) {
		memset(first, -1, sizeof(first));
		tot = 0;
		for (i = 1; i < n; i++) {
			scanf("%d %d", &s, &e);
			G[tot].vex = e;
			G[tot].next = first[s];
			first[s] = tot++;
			G[tot].vex = s;
			G[tot].next = first[e];
			first[e] = tot++;
		}
		memset(flag, false, sizeof(flag));
		mn = md = -1;
		DFS(1, 0);
		a = mn;
		memset(flag, false, sizeof(flag));
		mn = md = -1;
		DFS(a, 0);
		printf("%d %d\n", Min(a,mn), md + 1);
}}

1809 三色二叉树 (7条消息) 洛谷P2585&ZJOI 2006-三色二叉树(树的染色-树形DP)_lonely_wind_的博客-CSDN博客

#include <bits/stdc++.h>
using namespace std;

#define debug printf("#@$@%\n")
const int mac=5e5+10;

char s[mac];
vector<int>g[mac];
int cnt=0,dp[mac][3];
int dp2[mac][3];

int dfs_wedge(char *s,int fa)
{
    if (!s[0]) return 0;
    int nb=1;
    cnt++;
    if (fa!=-1){
        g[cnt].push_back(fa);
        g[fa].push_back(cnt);
    }
    if (s[0]=='0') return nb;
    int u=cnt;
    nb+=dfs_wedge(s+1,u);
    if (s[0]=='2') nb+=dfs_wedge(s+nb,u);
    return nb;
}

void dfs(int u,int fa)
{
    int v1=0,v2=0;
    for (int i=0; i<g[u].size(); i++){
    	int v=g[u][i];
        if (v==fa) continue;
        dfs(v,u);
        dp[u][1]+=dp[v][0];
        dp2[u][1]+=dp2[v][0];
        if (v1) v2=v;
        else v1=v;
    }
    dp[u][1]++; dp2[u][1]++;
    if (v2) {
        dp2[u][0]=min(dp2[v1][1]+dp2[v2][0],dp2[v1][0]+dp2[v2][1]);
        dp[u][0]=max(dp[v1][0]+dp[v2][0],max(dp[v1][0]+dp[v2][1],dp[v1][1]+dp[v2][0]));
    }
    else if (v1) dp[u][0]=max(dp[v1][0],dp[v1][1]),dp2[u][0]=min(dp2[v1][0],dp2[v1][1]);
}

int main(int argc, char const *argv[])
{
    scanf ("%s",s+1);
    if (s[1]=='0') {printf("%d %d\n",1,0); return 0;}
    dfs_wedge(s+1,-1);
    int n=strlen(s+1);
    dfs(1,-1);
    printf("%d %d\n",max(dp[1][0],dp[1][1]),min(dp2[1][0],dp2[1][1]));
    return 0;
}

1802 (7条消息) 动态规划求树的最大连通分支问题_. 输入含有 n 个顶点的加权二叉树 t 和正数 τ,树 t 上每条边的权值都非负,树中顶_hnu哈哈的博客-CSDN博客

谢谢,已经被折磨到不想再用标准C写东西了。手写图 链表 树是什么人间疾苦,

既然还要学ACM 为什么数据结构不直接教C++呢

#include <iostream>
#include <vector>
#include <list>
#include <queue>
#include <stack>
using namespace std;
struct node {int w, parent, level, visit;
	node() {w=parent=level=visit=0;}};
 
vector <list<int>> adjList;//邻接链表
vector <node> Node; //结点数组
 stack <int> rank;//分层后结果(栈顶到栈底,层次变低)
 
void bfs(){
	queue<int> q;
	list<int> l;
	list<int>::iterator iter;
	int cur,nxt;
	node son; //第一个节点先进去 
	q.push(1);
	rank.push(1);
	//从第一层开始广度优先遍历 
	while(!q.empty()){
		cur=q.front();//当前要访问的点 
		q.pop();
		l=adjList[cur];//得到当前点的邻接点链表 
		for(iter=l.begin();iter!=l.end();iter++){
		//将邻接点压入等待访问的队列 
			nxt=*iter;
			if(!Node[nxt].visit){
				q.push(nxt);//待访问 
				rank.push(nxt);
				son=Node[nxt];
				son.level=Node[cur].level+1;//确定层次 m
				son.parent=cur;//确定父结点 
				Node[nxt]=son;
			}
		}
		Node[cur].visit=1;//标记 
	} 
} 
 
 
int main(){
	int n,i; cin>>n; 
	adjList.assign(n+1,list<int>());//n+1个链表 
	Node.assign(n+1,node());//n+1个点 
	for(i=1;i<=n;i++) cin>>Node[i].w; //权值
	int l,r; //边
	for(i=0;i<n-1;i++) {cin>>l>>r;
		adjList[l].push_back(r);
		adjList[r].push_back(l);} 
	bfs(); //确定层次和父结点
	
	//动态规划自底向上根据每个节点的权值的正负,决定要不要贡献给父结点 
	int wei,cur,par;
	while(!rank.empty()){
	 	cur=rank.top();
	 	rank.pop();
	 	par=Node[cur].parent;
	 	Node[par].w+=max(0,Node[cur].w);
	} 
	int max=Node[1].w,maxi=1;
	for(i=2;i<=n;i++)
		{if(Node[i].w>max) {max=Node[i].w; maxi=i;}}
	//cout<<"该树的最大连通分支的权值和是:"<<max<<'\n';	
	cout<<max;} 

1821 判断完全二叉树(顺序存储)_牛客博客 (nowcoder.net)

//1821 E 完全二叉树
#include<stdio.h>
int find(int x,int y,int n,int a[],int *p) {int i;
    for(i=1;i<=n;i++){
        if(a[i]==x) {*p=i; return 1;}
        if(a[i]==y) {*p=i; return 0;}}}

int judge(int a[],int n)
    {int i; for(i=1;i<=n;i++) {if(a[i]==0) return 0;} return 1;}
    
int main(){
        int n,g; scanf("%d%d",&n,&g);
        int a[10000]={0};//初始化 
        a[1]=g;// 根节点进入数组 
        int x,y,i;
        int p=0,max=1;//max代表数组最大长度 
        for(i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            int flag=find(x,y,max,a,&p);//查找x,y中那个为根 指针带回根的位置 
            if(flag) {a[p*2]=y; if(p*2>max) max=p*2;}
            else {a[p*2+1]=x; if(p*2+1>max) max=p*2+1;}}

        int o=judge(a,max);//判断从a[1]到a[max]是否全为0 
        if(o==0) printf("no\n");
        if(o==1) printf("yes\n");}

广义表表示的二叉树 ★ (7条消息) 按广义表表示二叉树结构生成二叉树链表的算法_二叉树广义表表示_WongKyunban的博客-CSDN博客

1801 B - 树与二叉树_b树和二叉树_米诺minoz的博客-CSDN博客

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

#define BLANK putchar(' ') 
#define RETURN putchar('\n') 
struct CHILD {int l; int r;} child[1001];
typedef struct BiTNode {char data; struct BiTNode *lchild,*rchild;} BiTNode,*BiTree;

void Preorder(BiTree T){
    if(T!=NULL) {
        printf("%c",T->data);
        Preorder(T->lchild);
        Preorder(T->rchild);}}

void Inorder(BiTree T){
    if(T!=NULL) {
        Inorder(T->lchild);
        printf("%c",T->data);
        Inorder(T->rchild);}}

void Postorder(BiTree T){
    if(T!=NULL) {
        Postorder(T->lchild);
        Postorder(T->rchild);
        printf("%c",T->data);}}

int main() {
    int n,i,m,flag=0; char c;  BiTree node[1001];
    scanf("%d",&n); 
	while(n--)
	{
        BiTree T; flag++; scanf("%d",&m); getchar();
        for(i=1;i<=m;i++){
            c=getchar(); scanf("%d %d",&child[i].l,&child[i].r);
            getchar(); //%c %d %d fflush(stdin); 
            node[i]=(BiTree)malloc(sizeof(BiTNode));
            node[i]->data=c;
        }
        T=node[1];
        for(i=1;i<=m;i++)
        {
            if(child[i].l) node[i]->lchild=node[child[i].l];
            else node[i]->lchild=NULL;
            if(child[i].r) node[i]->rchild=node[child[i].r];
            else node[i]->rchild=NULL;
        }
        printf("Case %d:\n",flag);
        Preorder(T); RETURN;
        Inorder(T); RETURN;
        Postorder(T); RETURN;
    }
}

1412 二叉树的繁茂度_Felven的博客-CSDN博客 

#include <stdio.h>
#include <string.h>
int main(){char s[1000];
	int i, up, sum, max, number, length, a[100]; 
	scanf("%d",&number); while(number--)
	{
		up = max = sum =  0;
		memset(a, 0, sizeof(a));
		scanf("%s",&s); length=strlen(s);
		for(i=0;i<length;i++)
		{
			if(s[i]!='(' && s[i]!=')' && s[i]!=',') a[up]++;
			if(s[i]=='(') {up++; max++;}
			if(s[i]==')') up--;
		}
 
		for(i=0;i<=max;i++) sum+=a[i]*i;
		printf("%d\n",sum);
}}

1820 C  加分二叉树 - DWVictor - 博客园 (cnblogs.com)

需要调整一下格式(末尾无空格),用退格键不行\b,还是要用count==n?判断


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

int n,v[39],f[47][47],i,j,k,root[49][49];

int count=1;

void print(int l,int r){
    if(l>r)return;
    if(l==r){
	if(count==n) printf("%d",l); 
	else printf("%d ",l); 
	count++; return;}
	
	if(count==n) printf("%d",root[l][r]); 
    else printf("%d ",root[l][r]); 
	count++;
    print(l,root[l][r]-1);
    print(root[l][r]+1,r);
}
int main() {
    scanf("%d",&n);
    for( i=1; i<=n; i++) scanf("%d",&v[i]);
    for(i=1; i<=n; i++) {f[i][i]=v[i];f[i][i-1]=1;}
    for(i=n; i>=1; i--)
        for(j=i+1; j<=n; j++)
            for(k=i; k<=j; k++) {
                if(f[i][j]<(f[i][k-1]*f[k+1][j]+f[k][k])) {
                    f[i][j]=f[i][k-1]*f[k+1][j]+f[k][k];
                    root[i][j]=k;
                }
            }
    printf("%d\n",f[1][n]);
    print(1,n);
    return 0;
}

2123 B(广义表生成二叉树)的高度和宽度

按广义表表示二叉树结构生成二叉树链表的算法_二叉树广义表表示_WongKyunban的博客-CSDN博客

A(B(,D(E,F)),C)

这里把 *str 换成 str[N] 了,如果不用这个的话 gets(str); 会出错

参考了下面这篇文章里的递归方法求解深度。容易出错的地方是n级指针,需要不断调……

(1条消息) 【二叉树基础】求二叉树的宽度_二叉树宽度算法_晚鹌鹑蛋的博客-CSDN博客

 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 40

// 定义节点
typedef struct Node{
	char data;
    struct Node* lchild;
	struct Node* rchild;
} Binode;	

// 根据广义表表示二叉树结构来创建二叉树链表
Binode* createTree(char str[]){
	Binode *st[100]; // 用指针数组st存放双亲节点
	Binode *p = NULL; // 用来一生成节点时用的
	Binode *b = NULL; // 二叉树链表的头节点
	int top = -1,key,j=0;
	char ch = str[j];
	while(ch != '\0'){
        // 在遍历广义表表示二叉树结构过程中,会遇到'(',',',')'和字母
		switch(ch){
			// 遇到'(',就是左子树,将key标记为1,以作记录,将当前节点记录到栈st中
			case '(': top++; st[top] = p; key = 1; break; case ',': key = 2; break; // 遇到',',就是右子树,将key标记为1,以作记录
			case ')': top--; break;  // 遇到')',说明此子树已遍历完成,要返回到上一个双亲节点,准备遍历双亲节点的另一棵子树
			default : // 遇到节点,为节点申请内存,并初始化节点
				p = (Binode*)malloc(sizeof(Binode));
				p->data = ch;
				p->lchild = p->rchild = NULL;
				// 记录头结点
				if(b == NULL) b = p;
				else {// 如果是非头结点,那么就根据key的值,将节点添加到双亲节点的子树上去
					switch(key){
						case 1: st[top]->lchild = p; break;
						case 2: st[top]->rchild = p; break;}}}
		j++; ch = str[j];}
	return b;} // 返回头结点

void PreOrder(Binode *t){
if(t){	putchar(t->data);
		PreOrder(t->lchild);
		PreOrder(t->rchild);}}

//返回二叉树t的深度(高度)
int BitreeDepth(Binode *t){
	int m, n;
	if (t == NULL) return 0;				//若是空树,深度为0,递归结束
	m = BitreeDepth(t->lchild);				//递归计算左子树的深度m
	n = BitreeDepth(t->rchild);	
	return (m>n? m+1: n+1);	}

int BitreeWidth(Binode *t, int k, int width[], int *max){
	if (t == NULL) return 0;
	width[k]++;
	*max = *max > width[k]? *max : width[k];
	BitreeWidth(t->lchild, k+1, width, max);
	BitreeWidth(t->rchild, k+1, width, max);
}

int main(){
	char str[N]; gets(str); //A(B(,D(E,F)),C)
	Binode* t= createTree(str);
	int max=0; int width[10]={0};
	printf("%d ", BitreeDepth(t));
	BitreeWidth(t,1,width,&max);
	printf("%d",max);
}

1806 C 求二叉树中节点的深度 

销毁树之后再生成就会出错,是因为没有分配空间,并且有缓冲区的影响,加这两句:

getchar(); /* 清除缓冲区 */  t=(BiNODE *)malloc(sizeof(BiNODE)); /* 初始化根节点 */

就可以解决多次生成销毁树带来的内存出错问题

比较坑,还好之前在王老师那道题碰到过销毁链表就出错的问题,

而且这个不检查、不报错,就更加坑了


//1806 C 求二叉树中节点的深度
#include <stdio.h>
#include <stdlib.h>
typedef enum {FALSE, TRUE} Boolean;		//重命名枚举类型,枚举值为FALSE(0)和TRUE(1)
typedef char ElementType;					//定义二叉树结点的数据类型为字符型
ElementType ERROR = -1;					//特殊错误标志,须是正常的结点元素不可能取到的值
typedef struct BiNode {ElementType data; struct BiNode *lchild, *rchild;} BiNODE, *BiTree;

//访问二叉树结点函数,输出结点值
void PrintElement(ElementType e) {putchar(e);} //putchar(' ');

//先序遍历二叉树,其中形参Visit为指向函数的指针,实参为函数名
void PreOrderTraverse(BiTree t, void (*Visit)(ElementType))
{
	if (t)									//若二叉树为空,则空操作返回
	{
		(*Visit)(t->data);						//访问根结点,*Visit是调用实参传进来的函数
		PreOrderTraverse(t->lchild, Visit);		//递归先序遍历左子树
		PreOrderTraverse(t->rchild, Visit);		//递归先序遍历右子树
	}
}

//构造空的二叉树
void InitBiTree(BiTree *t) {*t = NULL;} //树的根结点置为空


//前序输入二叉树中结点的值构造二叉树
void CreateBiTree(BiTree *t)
{ 
	//先创建根结点,再递归地创建左子树,之后递归地创建右子树。#表示空树。
	//思考下:键盘输入abd#g###ce##f##[回车键]创建的二叉树。
	//思考下:键盘输入abd g   ce  f  [回车键]创建的二叉树。
	ElementType ch; ch = getchar();						//从键盘输入字符,该字符是二叉树中结点的值
	if (ch == ' ') *t = NULL;				//输入' '代表空树,递归的终止条件,即递归出口
	else
	{
		//生成根结点
		*t = (BiNODE *)malloc(sizeof(BiNODE));
		if (!*t) exit(1);					//根结点空间分配失败,退出程序
		(*t)->data = ch;					//根结点的数据域赋值
		CreateBiTree(&(*t)->lchild);		//递归构造左子树
		CreateBiTree(&(*t)->rchild);		//递归构造右子树
	}
}

//采用递归算法销毁根结点为root的二叉树
void DestoryBiTree(BiTree *t)
{
	if (*t && (*t)->lchild)					//若结点*t存在左子树
		DestoryBiTree(&(*t)->lchild);		//递归销毁*t的左子树
	if (*t && (*t)->rchild)					//若结点*t存在右子树	
		DestoryBiTree(&(*t)->rchild);		//递归销毁*t的右子树
	free(*t);							//释放当前结点空间
	*t = NULL;						//结点删除之后,*t一定要置为空,这很重要
}
//判断二叉树t是否为空树
Boolean IsEmpty(BiTree t)
{
	if (!t) return TRUE;					//若t为空二叉树,返回TRUE
	else return FALSE;					//否则返回FALSE
}
//返回二叉树t的深度(高度)
int BiTreeDepth(BiTree t)
{
	int m, n;
	if (t == NULL) return 0;				//若是空树,深度为0,递归结束
	m = BiTreeDepth(t->lchild);				//递归计算左子树的深度m
	n = BiTreeDepth(t->rchild);				//递归计算右子树的深度n
	if (m > n) return m + 1;				//二叉树的深度为左右子树深度较大者+1
	else return n + 1;
}

int Maxlen(BiTree t, int *len){
	if(!t) return 0;
	int L = Maxlen(t->lchild, len);
	int R = Maxlen(t->rchild, len);
	*len = *len > L+R ? *len : L+R;
	int max= L>R? L:R;
	return 1+max;
}

BiNODE* Root(BiTree t) {return t;}

//返回二叉树t中结点p的值
ElementType Value(BiNODE *p) {
	if (p) return p->data; else return ERROR;}

void Assign(BiNODE *p, ElementType e) {if (p) p->data = e;}

//根据LR为0或1,插入非空二叉树C为二叉树T中p所指结点的左或右子树,p所指结点的原有左或右子树则成为C的右子树。其中,非空树C和树T不相交且右子树为空
void InsertChild(BiNODE *p, int LR, BiTree c){
     if (c == NULL) return;					//如果c是空树,返回
     if (LR == 0) {c->rchild = p->lchild; p->lchild = c;}
else if (LR == 1) {c->rchild = p->rchild; p->rchild = c;}}

//根据LR为0或1,删除二叉树T中p所指结点的左或右子树
void DeleteChild(BiNODE *p, int LR)		{
     if (LR == 0) if (p) DestoryBiTree(&p->lchild);
else if (LR == 1) if (p) DestoryBiTree(&p->rchild);}

//复制二叉树
BiTree CopyBiTree(BiTree t){
	BiNODE *pNew; if (!t) return NULL;
	pNew = (BiNODE *)malloc(sizeof(BiNODE));
	pNew->data = t->data;					//复制根结点的数据域
	pNew->lchild = CopyBiTree(t->lchild);		//递归复制左子树
	pNew->rchild = CopyBiTree(t->rchild);		//递归复制右子树
	return pNew;}
	
//判断两棵树是否相等
Boolean BiTreeCmp(BiTree t1, BiTree t2){
	if (!t1 && !t2) return TRUE;				//若t1和t2皆为空树,则返回TRUE
	//若t1和t2皆为非空树,则先比较根结点值,再递归比较左右子树
	else if (t1 && t2 && (t1->data == t2->data) && BiTreeCmp(t1->lchild, t2->lchild) && BiTreeCmp(t1->rchild, t2->rchild)) return TRUE;
	else return FALSE;					//其他情况,则返回FALSE
}

int main(){
	int times; char c; scanf("%d%c",&times,&c);
	while(times--){ 
	BiTree t; InitBiTree(&t); CreateBiTree(&t);					//构造二叉树t1
	int len=0; printf("%d\n", Maxlen(t,&len));
	DestoryBiTree(&t); getchar(); t=(BiNODE *)malloc(sizeof(BiNODE));
}}

1818 A HFM Basic

2275 F 简单哈夫曼树 :加一个while(times--){exec();}

这篇实在是太6了……多个愿望一次满足。加了void*指针类型强制转换不然gcc可能会编译失败。

哈夫曼树遍历求WPL和哈夫曼编码C语言--For初学者_哈夫曼树wpl c语言_a_52hz的博客-CSDN博客

#include <stdio.h>
#include <stdlib.h>
#define MAX 20

typedef struct node
{
    int weight;
    struct node *lchild,*rchild;
    struct node *next;
}HuffNode;


void HuffTree(HuffNode **);
void CreatUpLink(HuffNode **,int);
void InitLink(HuffNode**);
void PrintNode(HuffNode**);
void PrePrint(HuffNode *);
int CalcWPL(HuffNode *,int);
void HuffCode(HuffNode *,int);
int main(){
    int wpl = 0; HuffNode *huff;
    int n; scanf("%d",&n);
    CreatUpLink(&huff,n);
    //PrintNode(&huff);
    HuffTree(&huff);
    //printf("\nPreorder :\n");
    //PrePrint(huff);
    wpl = CalcWPL(huff,0);
    printf("%d",wpl);
    //printf("\n\nWPL = %d\n",wpl);
    //printf("\nHuffCode:\n");
    //HuffCode(huff,0);
    //return 0;
}

int CalcWPL(HuffNode *huff,int wpl){
    HuffNode *p = huff; if(!p) return 0; else {
    if(!p->rchild&&!p->rchild) return p -> weight*wpl;
        else return CalcWPL(p->lchild,wpl+1) + CalcWPL(p->rchild,wpl+1);}}

void HuffCode(HuffNode *huff,int len){
    HuffNode *p = huff;
    static int a[MAX];
    int i;
    if(p){
        if(!p->lchild && !p->rchild){
            printf("%d:",p->weight);
            for(i = 0;i< len;i++) printf("%d",a[i]);
            printf("\n");}
        else {a[len] = 0; HuffCode(p->lchild,len+1);
              a[len] = 1; HuffCode(p->rchild,len+1);}}}

void PrePrint(HuffNode *huff){
    HuffNode *p = huff;
    if(p){
        printf("%d\t",p->weight);
        PrePrint(p->lchild);
        PrePrint(p->rchild);}}

void PrintNode(HuffNode **huff){
    HuffNode *p = (*huff);
    while(p) {printf("%d ",p->weight); p = p->next;}
    putchar('\n');}
    
void InitLink(HuffNode **huff){(*huff) = NULL;}

void CreatUpLink(HuffNode **huff,int n){
    HuffNode *pre,*p ,*s,*head = (*huff);
    int x; scanf("%d",&x);
    s =  (HuffNode *)malloc(sizeof(HuffNode));
    s -> lchild = NULL;
    s -> rchild = NULL;
    s -> weight = x;
    s -> next = NULL;
    head = s;
    n--; while(n--){
        pre = p = head;
        scanf("%d",&x);
        s =  (HuffNode *)malloc(sizeof(HuffNode));
        s->lchild = NULL;
        s->rchild = NULL;
        s->weight = x;
        if(p->weight > x) {s-> next = p; head = s;}
        else{
            while(p && p->weight < x)
                {pre = p; p = p->next;}
                s -> next = pre->next;
                pre -> next = s;}}
    (*huff) = head;}
    
void HuffTree(HuffNode **huff){
    HuffNode *pn1 ,*pn2 ,*p = *huff,*s = NULL,*q = NULL,*pre = NULL,*pr = NULL;
    if(!p->next) return ;
    while(p){
        pn1 = p ;
        pn2 = pn1 -> next;
        pre = q = pn2 -> next ;
        s = (HuffNode *)malloc(sizeof(HuffNode));
        s -> lchild = pn1;
        s -> rchild = pn2;
        s -> weight = pn1 -> weight + pn2 -> weight;
        s ->next = NULL;
      if(!pn2 -> next){
          s->next = NULL;
          pn2->next = s;
          (*huff) = s;
          return;
      }
        if(pn2 -> next -> weight > s->weight)
        {
            s -> next = pn2 -> next;
            pn2 ->next = s;
        }
        else
        {
            while(q && q->weight < s -> weight)
                {
                    pre = q;
                    q = q->next;
                }
                s -> next = pre->next;
                pre -> next = s;
        }
        pr = pn2;
        p = pn2 -> next;
    }
    (*huff) = pr;
}

1818 F HFM coding

思路和教材上是一样的,就是没有读清楚题目

(每行第一个是元素个数,不是用~scanf扫描)

(6条消息) TOJ 1225 数据结构练习题——Huffman Coding_1225: 数据结构练习题――哈夫曼编码_芋智波佐助的博客-CSDN博客

//1818 F Huffman Coding
#include<stdio.h>
#define inf 0x7ffff;
struct node {int w,parent,lchild,rchild;} tree[202];
struct code {int start; int d[10];} huff[202];
int n;

void creat(){
	int i,j,m,w1,w2,w,x,y; m=2*n-1;
	for(i=1;i<=m;i++) tree[i].parent=tree[i].lchild=tree[i].rchild=0;
	for(i=n+1;i<=m;i++)
	{
		w1=w2=inf; x=y=0;
		for(j=1;j<i;j++){
			if(!tree[j].parent){
				if(w1>tree[j].w) {w2=w1; y=x; w1=tree[j].w; x=j;}
		  else  if(w2>tree[j].w) {y=j; w2=tree[j].w;}}}
		tree[i].w=w1+w2;
		tree[x].parent=tree[y].parent=i;
		tree[i].lchild=x;
		tree[i].rchild=y;}}

void creat_huff(){
	int i,c,f;
	for(i=1;i<=n;i++){
		huff[i].start=n;
		for(c=i,f=tree[i].parent;f;c=f,f=tree[f].parent)
		   {if(c==tree[f].lchild) huff[i].d[huff[i].start--]=0;
			else huff[i].d[huff[i].start--]=1;}}}
 
main(){int t,x,i; scanf("%d",&t);while(t--){	
	scanf("%d",&n);
	for(i=1;i<=n;i++) scanf("%d",&tree[i].w);
	creat(); creat_huff();
	double sum=0.0;
	for(i=1;i<=n;i++) sum+=n-huff[i].start; 
	sum/=n; printf("%.3f\n",sum);}}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值