图:
Tree Traversals Again:
有序二叉树遍历可以通过堆栈以非递归方式实现。例如,假设遍历6节点二叉树(键的编号从1到6)时,堆栈操作为:push(1);push(2);push(3);pop();pop();push(4);pop();pop();push(5);push(6);pop();pop()。然后,可以从这个操作序列生成一个唯一的二叉树(如图1所示)。你的任务是给出这个树的后序遍历序列。
每个输入文件包含一个测试用例。对于每种情况,第一行包含一个正整数N(≤30),它是树中节点的总数(因此节点的编号从1到N)。接下来是2N行,每行描述一个堆栈操作,格式为:“Push X”,其中X是被推送到堆栈上的节点的索引;或“Pop”,意思是从堆栈中弹出一个节点。
对于每个测试用例,在一行中打印对应树的后序遍历序列。一定有解决办法。所有数字必须用一个空格隔开,并且行的末尾不能有多余的空格。
题意:用栈的push、pop操作给出一棵二叉树的中序遍历顺序,求这棵二叉树的后序遍历。
核心代码:
void shu(int a int b,int m,int n)
{
int r,l,i;
if(n==0)
return;
if(n==1)
{
post[m]=pre[a];
break;
}
root=pre[a];
post[m+n-1]=root;
for(i=0;i<n;i++)
if(in[b+i]==root)
break;
l=i;
r=n-l-1;
shu(a+1,b,m,l);
shu(a+l+1,b+l+1,m+l,r)
}
Complete Binary Search Tree
二进制搜索树(BST)递归地定义为具有以下属性的二进制树:
节点的左子树只包含键小于节点键的节点。
节点的右子树仅包含键大于或等于节点键的节点。
左子树和右子树也必须是二进制搜索树。
完整的二叉树(CBT)是一个完全填充的树,但底层可能例外,它是从左到右填充的。
现在给定一系列不同的非负整数键,如果要求树也必须是CBT,则可以构造唯一的BST。您应该输出这个BST的水平顺序遍历序列。
输入规格:
每个输入文件包含一个测试用例。对于每种情况,第一行包含一个正整数N(≤1000)。然后在下一行给出N个不同的非负整数键。一行中所有数字用空格隔开,且不大于2000。
输出规格:
对于每个测试用例,在一行中打印对应的完整二进制搜索树的级别顺序遍历序列。一行中的所有数字都必须用空格隔开,并且行的末尾不能有多余的空格。
思路:
根据输入的结点数,建立完全二叉树;
将节点数值放在数组中,从小到大排序;
根据根左儿子的结点数(左儿子的值都比根的值小,右儿子的值都比根的值大,所以,例如左儿子有6个结点,则根的值为数组中第7大的值),选取数组中对应的值,放入其中,然后更新左儿子数组,右儿子数组,递归将值放入其中。
核心代码:
void shu(int left int right,int root)
{
n=right-left+1;
if(n==0)
return;
l=getletflength(n);
T[root]=A[left+l];
letfroot=root*2+1;
rightroot=leftroot+1;
shu(left,left+l-1,leftroot);
shu(left+1+l,right,rightroot);
}
Huffman Codes:
Huffman Codes的特点:
1.最优编码—总长度最小
2.无歧视解码—前缀码,数据仅存于叶子节点
3.没有度为1的节点—满足1.2则必然有3
核心代码
Minheap H=Creatheap(N)//创建一个空的,容量为N的最小堆
H=ReadData(N);
HuffmanTree T=Huffman(H);
int codelen=WPL(T,0);
int WPL(HuffmanTree T,int depth)
{
if(!T->left&&!T->right)
return depth*T->weight;
else
return (WPL(RT->left,depth+1)+WPL(T->right,depth+1));
}
最短路径:
用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
关于最短路径的解法,我个人是用三个数组分别是存路长,标记,代表起点到某个点的距离,通过不断查找最短距离来最后得到结果
放例题:
大奶牛很热爱加班,他和朋友在凌晨一点吃完海底捞后又一个人回公司加班,为了多加班他希望可以找最短的距离回到公司。
深圳市里有N个(2 <= N <= 1000)个公交站,编号分别为1…N。深圳是大城市,公交车整天跑跑跑。公交站1是大奶牛的位置,公司所在的位置是N。所有公交站中共有T (1 <= T <= 2000)条双向通道。大奶牛对自己的导航能力不太自信,所以一旦开始,他总是沿着一条路线走到底。
大奶牛为了锻炼未来的ACMer,决定让你帮他计算他到公司的最短距离。可以保证存在这样的路存在。
Input
第一行:两个整数:T和N
接下来T行:每一行都用三个空格分隔的整数描述一个轨迹。前两个整数是路线经过的公交站台。第三个整数是路径的长度,范围为1到100。
Output
一个整数,表示大奶牛回到公司的最小距离。
Sample Input
5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100
Sample Output
90
#include<stdio.h>
#include<string.h>
int n,m;
int a[3000][3000],book[3000],c[3000];
int max=1000010;
int bijiao(int x,int y)
{
int i,min,k,j;
for(i=1; i<=n; i++)
c[i]=a[x][i];
c[x]=0;
book[x]=1;
for(i=1; i<=n; i++)
{
min=max;
for(j=1; j<=n; j++)
{
if(book[j]==0&&c[j]<min)
{
k=j;
min=c[j];
}
}
book[k]=1;
for(j=1; j<=n; j++)
{
if(book[j]==0&&c[j]>min+a[k][j])
{
c[j]=a[k][j]+min;
}
}
}
return c[y];
}
int main()
{
scanf("%d %d",&m,&n);
memset(book,0,sizeof(book));
int i,j,x,y,ans,sum;
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
{
a[i][j]=max;
a[j][i]=max;
}
while(m--)
{
scanf("%d %d %d",&x,&y,&ans);
if(ans<a[x][y])
{
a[x][y]=ans;
a[y][x]=ans;
}
}
sum=bijiao(1,n);
printf("%d\n",sum);
return 0;
}
代码个人认为还是非常好理解的。