20/1/20树的遍历、进制转换

20/1/20树的遍历、进制转换

树的遍历

树的遍历方式有三种,分别是前序、中序以及后序遍历。前、中、后说明的是根节点出现的位置,即前序遍历指先根,再左子树最后右子树。
要想利用程序实现树的遍历,首先应选取恰当的数据结构,树形结构多数构造结构体,利用指针存储。如下:

数据结构选择

struct Node{ 
	int data; 
	Node* lchild; 
	Node* rchild;
};

树的创建

这里以二叉搜索树的创建为例。
二叉搜索树:任一结点的左子树仅包含严格小于该结点的键值,而其右子树包含大于或等于该结点的键值。

Node* butree(Node* Btree,int x){//树的生成 
	if(!Btree){//树为空 
		Btree=(Node*)malloc(sizeof(struct Node));//不可省略 
		Btree->data=x; 
		Btree->lchild=NULL; 
		Btree->rchild=NULL;
	if(x<Btree->data){ 
		Btree->lchild=butree(Btree->lchild,x); 
	}else if(x>=Btree->data){ 
		Btree->rchild=butree(Btree->rchild,x); 
		} 
	} 
return Btree;
}

创建好合适的树形结构之后,也就有了遍历的基础。
遍历的方式有递归和迭代两种方式,递归方式代码简洁,逻辑结构也相当清晰,但内存消耗较大。相比之下,迭代的实现方式更注重过程的思想,利用栈来实现三种遍历。

递归实现树的遍历

void po(Node* root){//先序遍历 
 if(root){ 
 	a1[num1++]=root->data; 
 	po(root->lchild); 
 	po(root->rchild); 
 	} 
 } 

中序以及后序遍历与前序遍历的思想相同,只需修改获取结点值的语句的位置即可。(上文第三行代码)

迭代实现树的遍历

明日补充

进制转换

十六进制转八进制

十六进制的每一位数字对应四位二进制数字;八进制的每一位数字对应三位二进制数字,高位不足补零。
故:十六进制转八进制数,可依照如下思路完成

  1. 将十六进制数字按位转化为4位二进制数,存入数组/字符串~~(字符串较为好用一些,因为字符串的合并通过+便可实现)~~
  2. 统计形成的二进制数的位数是否是3的整数倍,若不是则在左侧添0
  3. 从左到右依次扫描二进制数组( 字符串),每三位计算一次结果并输出。
    实现全代码如下:
#include<bits/stdc++.h>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<string.h>
#define ll long long
#define INF 10000
#include<map>
#include<stack>
#include<queue>
#include<stdio.h>
#include<string.h>
using namespace std;
int A[4000005];
int ans[2000005];
int main(){
 int N;
 scanf("%d",&N);
 int num=0;
 while(N--){
  char s[100005];
  string s1="";
  cin>>s;
  int len=strlen(s);
  //cout<<len<<" "<<4*len<<endl;
  for(int i=0;i<len;i++){
   //cout<<s[i]<<" ";
   switch(s[i]){
	    case '0':
	     s1+="0000";break;
	    case '1':
	     s1+="0001";break;
	    case '2':
	     s1+="0010";break;
	    case '3':
	     s1+="0011";break;
	    case'4':
	     s1+="0100";break;
	    case '5':
	     s1+="0101";break;
	    case '6':
	     s1+="0110";break;
	    case'7':
	     s1+="0111";break;
	    case '8':
	     s1+="1000";break;
	    case '9':
	     s1+="1001";break;
	    case'A':
	     s1+="1010";break;
	    case 'B':
	     s1+="1011";break;
	    case 'C':
	     s1+="1100";break;
	    case'D':
	     s1+="1101";break;
	    case 'E':
	     s1+="1110";break;
	    case 'F':
	     s1+="1111";break;
	   }
	  }
	  int le=s1.length();
  if(le%3==1){//位数不足,则补0
	   s1="00"+s1;
	   le+=2;
  }else if(le%3==2){
	   s1="0"+s1;
	   le+=1;
  }
 // cout<<s1<<" "<<le<<endl;
  for(int i=0;i<le;){
   int t=0;
   for(int j=0;j<3;j++){
   	t+=(s1[i+j]-'0')*pow(2,2-j);
   }
   	ans[num++]=t;
   	i+=3;
  }
  int flag=1;
  for(int i=0;i<num;i++){
	 if(flag&&ans[i]!=0){
		flag=0;
	   }
		if(flag) continue;
	   	cout<<ans[i];
	}
	  cout<<endl;
	  num=0;
	 }
return 0;
}

十进制转其他进制

无需借助额外的进制,循环除再倒着输出就可以了,代码如下:

void zhuan(int n){//十进制转八进制
	int num=0;
	while(n){
		A[num++]=n%8;
		n/=8;
	}
}

输出时逆序输出就可以了。如果是字符串来保存数组,可以利用reverse(A,A+num)来逆转字符数组。
转为十六进制时由于会出现二位数,可选择利用字符串来保存结果。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值