树与二叉树
// 第六章 : 二叉树
#include<bits/stdc++.h>
using namespace std;
#define ElementType char
int MAX=100;
定义结构体
// 定义结构体
typedef struct Node{
ElementType data;
struct Node *left;
struct Node *right;
}BTNode,*BTree;
1. 先序遍历二叉树(递归)
// 1. 先序遍历二叉树(递归)
void preOrder(BTree root){
if(root!=NULL){
printf("%c\n",root->data);
preOrder(root->left);
preOrder(root->right);
}
}
2. 中序遍历二叉树(递归)
// 2. 中序遍历二叉树(递归)
void inOrder(BTree root){
if(root!=NULL){
inOrder(root->left);
printf("%c\n",root->data);
inOrder(root->right);
}
}
3. 后序遍历二叉树(递归)
// 3. 后序遍历二叉树(递归)
void postOrder(BTree root){
if(root!=NULL){
postOrder(root->left);
postOrder(root->right);
printf("%c\n",root->data);
}
}
4. 层序遍历二叉树
// 4. 层序遍历二叉树
void layerOrder(BTree root){
queue <BTNode*> Q;
Q.push(root);
while(!Q.empty()){
BTNode *p;
p=Q.front();
Q.pop();
printf("%c\n",p->data);
if(p->left!=NULL){
Q.push(p->left);
}
if(p->right!=NULL){
Q.push(p->right);
}
}
}
5.先序遍历二叉树(非递归)1
// 5.先序遍历二叉树(非递归)1
void preOrder1(BTree root){
stack <BTNode *> S;
BTNode *p;
p=root;
while(p!=NULL || !S.empty()){
while(p!=NULL){
printf("%c\n",p->data);
S.push(p);
p=p->left;
}
p=S.top();
S.pop();
p=p->right;
}
}
先序遍历二叉树(非递归)2
// 先序遍历二叉树(非递归)2
void preOrder2(BTree root){
stack <BTNode *> S;
BTNode *p;
p=root;
while(p!=NULL || !S.empty()){
if(p!=NULL){
printf("%c\n",p->data);
S.push(p);
p=p->left;
}else{
p=S.top();
S.pop();
p=p->right;
}
}
}
6.中序遍历二叉树(非递归)
// 6.中序遍历二叉树(非递归)
void inOrder1(BTree root){
stack <BTNode *> S;
BTNode *p;
p=root;
while(p!=NULL || !S.empty()){
while(p!=NULL){
S.push(p);
p=p->left;
}
p=S.top();
S.pop();
printf("%c",p->data);
p=p->right;
}
}
7. 后序遍历二叉树(非递归)1
// 7. 后序遍历二叉树(非递归)1
void postOrder1(BTree root){
stack<BTNode*> S;
BTNode *p,*pre=NULL;
p=root;
while(p!=NULL || !S.empty()){
while(p!=NULL){
S.push(p);
p=p->left;
}
p=S.top();
if(p->right==NULL || p->right==pre){
printf("%c",p->data);
S.pop();
pre=p;
p=NULL;
}else{
p=p->right;
}
}
}
后序遍历二叉树(非递归)2
// 后序遍历二叉树(非递归)2
void postOrder2(BTree root){
stack<BTNode*> S;
BTNode *p,*pre=NULL;
p=root;
while(p!=NULL || !S.empty()){
if(p!=NULL){
S.push(p);
p=p->left;
}else{
p=S.top();
if(p->right==NULL || p->right==pre){
printf("%c",p->data);
S.pop();
pre=p;
p=NULL;
}else{
p=p->right;
}
}
}
}
8. 输出二叉树中的叶子节点
// 8. 输出二叉树中的叶子节点
void leafNode(BTree root){
if(root!=NULL){
if(root->left==NULL&&root->right==NULL){
printf("%c",root->data);
}
leafNode(root->left);
leafNode(root->right);
}
}
9. 求二叉树的高度
//9. 求二叉树的高度
int depth(BTree root){
if(root==NULL){
return 0;
}
int maxDepth;
int leftDepth=depth(root->left);
int rightDepth=depth(root->right);
maxDepth=leftDepth>rightDepth?leftDepth:rightDepth;
return maxDepth+1;
}
10.树状打印二叉树
//10.树状打印二叉树
//int layer=0;// layer为节点的层数
void printTree(BTree root,int layer){
if(root!=NULL){
// 输出右子树
printTree(root->right,layer+1);
// 输出当前节点
for(int i=0;i<layer;i++){
printf("-");
}
printf("%c\n",root->data);
// 输出左子树
printTree(root->left,layer+1);
}
}
11. 先序与中序创建二叉树
// 11. 先序与中序创建二叉树
//#define MAX 100
char pre[]{'A','B','C','D','F','G','H','J'};
char in[]{'D','C','F','B','A','G','J','H'};
//int pre[MAX],in[MAX];
// pre 表示先序数组,in表示中序数组
// b1 t1:为先序的上下界;b2 t2:为中序的上下界
BTree create(int b1,int t1,int b2,int t2){
// printf("%d %d %d %d\n",b1,t1,b2,t2);
BTree root;
// 1.创建当前节点
root=(BTNode *)malloc(sizeof(BTNode));
root->data=pre[b1];
root->left=NULL;
root->right=NULL;
// 2.计算左子树的个数
int count,i=b2;
while(in[i]!=pre[b1]){
i++;
}
count=i-b2; // i这个位置为左右的分界节点=pre[b1]
if(i!=b2){// 存在左子树
root->left=create(b1+1,b1+count,b2,i-1);
}
if(i!=t2){// 存在右子树
root->right=create(b1+count+1,t1,i+1,t2);
}
return root;
}
12.有二叉树广义表创建二叉树 A(B(C,D),E(F(,G),))
// 12.有二叉树广义表创建二叉树 A(B(C,D),E(F(,G),))
BTree createByguangyi(char *str){
int k=0; // k=1:插入左子树,k=2:插入右子树
BTNode *S[MAX],*p;
int top=-1; // 二叉树节点栈的顶
for(int i=0;str[i]!='\0';i++){
if((str[i]>='A'&&str[i]<='Z')||(str[i]>='a'&&str[i]<='z')){ // 节点
p=(BTNode *)malloc(sizeof(BTNode));
p->data=str[i];
p->left=NULL;
p->right=NULL;
if(k==1){
S[top]->left=p;
}
else if(k==2){
S[top]->right=p;
}
}
else if(str[i]=='('){
top++;
S[top]=p;
k=1;
}
else if(str[i]==')'){
top--;
}
else if(str[i]==','){
k=2;
}
}
return S[0];
}
13. 输出 二叉树广义表表示形式
// 13. 输出 二叉树广义表表示形式
void printBTree_guangyi(BTree root){
if(root!=NULL){
printf("%c",root->data);
if(root->left!=NULL || root->right!=NULL){
printf("(");
printBTree_guangyi(root->left);
printf(",");
printBTree_guangyi(root->right);
printf(")");
}
}
}
14 扩展先序递归创建 二叉树
// 14 扩展先序递归创建 二叉树
BTree create_digui(){
char ch;
ch=getchar();
if(ch=='.'){
return NULL;
}
BTNode *root;
root=(BTNode *)malloc(sizeof(BTNode));
root->data=ch;
root->left=create_digui();
root->right=create_digui();
return root;
}
15 扩展层序序列创建二叉树:ABC.D.EFG.H…
// 15 扩展层序序列创建二叉树:ABC.D.EFG.H......
BTree create_ceengxu(char *str){ // 自己想的
if(str[0]=='\0'){
return NULL;
}
BTree root;
BTNode *p,*s;
queue <BTNode *> Q;
int fg=0; // 1为左 2为右
for(int i=0;str[i]!='\0';i++){
if(str[i]>='A'&&str[i]<='Z' || (str[i]>='a'&&str[i]<='z')){
s=(BTNode *)malloc(sizeof(BTNode));
s->data=str[i];
s->left=NULL;
s->right=NULL;
if(fg==1){
p=Q.front();
p->left=s;
fg=2;
}
else if(fg==2){
p=Q.front();
p->right=s;
Q.pop();
fg=1;
}
else if(fg==0){
root=s;
fg=1;
}
Q.push(s);
}
else if(str[i]=='.'){
if(fg==1){
fg=2;
}
else if(fg==2){
fg=1;
Q.pop();
}
}
}
return root;
}
扩展层序序列创建二叉树(书本)
BTree create_ceengxu_book(char *str){ //书本标准
int i=0;
if(str[i]=='.'){
return NULL;
}
queue<BTNode *>Q;
BTNode *root,*p;
root=(BTNode *)malloc(sizeof(BTNode));
root->data=str[i];
Q.push(root);
while(!Q.empty()){
p=Q.front();
Q.pop();
i++;
if(str[i]=='.'){
p->left=NULL;
}
else{
p->left=(BTNode *)malloc(sizeof(BTNode));
p->left->data=str[i];
Q.push(p->left);
}
i++;
if(str[i]=='.'){
p->right=NULL;
}
else{
p->right=(BTNode *)malloc(sizeof(BTNode));
p->right->data=str[i];
Q.push(p->right);
}
}
return root;
}
主函数
int main(){
// 1. 先序和中序创建二叉树
// BTree root=create(0,7,0,7);
// printf("depth : %d\n",depth(root));
// printTree(root,0);
// 2. 广义表创建二叉树: A(B(C,D),E(F(,G),))
// char str[100];
// gets(str);
// BTree root=createByguangyi(str);
// printBTree_guangyi(root);
// 3. 创展先序创建二叉树 : AB.DF..G..C.E.H..
// BTree root= create_digui();
// printBTree_guangyi(root);
// 4. 由扩展层序序列创建二叉树:ABC.D.EFG.H......
char str[100];
gets(str);
BTree root1 = create_ceengxu(str);
printBTree_guangyi(root1);
printf("\n");
BTree root2 = create_ceengxu_book(str);
printBTree_guangyi(root2);
return 0;
}
哈夫曼树的应用
// 哈夫曼树
#include<bits/stdc++.h>
using namespace std;
二叉树的存储结构
// 二叉树的存储结构
#define N 200
typedef struct{
int weight; // 节点的权值
int parent; // 双亲的下标
int left; // 左孩子节点序号
int right; // 有孩子节点序号
}HTNode,*HTree;
查找最小节点
void findMin(HTree ht,int n,int *s){
int max=INT_MAX;
for(int i=1;i<=n;i++){
if(ht[i].parent==0 && ht[i].weight<max){
max=ht[i].weight;
*s=i;
}
}
}
1. 创建一个哈夫曼树
// 1. 创建一个哈夫曼树
void createHuffmanTree(HTree ht,int w[],int n){ // w数组存放n个叶子节点的权值
// 给1~n个节点赋初值
for(int i=0;i<=n;i++){
ht[i]={w[i],0,0,0};
}
// 创建非叶子节点
int m=2*n-1;
int s1,s2;
for(int i=n+1;i<=m;i++){
// 在1~n-1的范围内找到parent为0,weight最小节点s1
findMin(ht,i-1,&s1);
ht[s1].parent=i;
findMin(ht,i-1,&s2);
ht[s2].parent=i;
ht[i].weight=ht[s1].weight+ht[s2].weight;
ht[i].parent=0;
ht[i].left=s1;
ht[i].right=s2;
}
}
2. 输出哈夫曼编码
// 2. 输出哈夫曼编码
void createHuffmanCode(HTree ht,int n,char *hc[]){
// for(int i=1;i<=2*n-1;i++){
// printf("%d %d %d %d\n",ht[i].weight,ht[i].parent,ht[i].left,ht[i].right);
// }
int c,p; // c,p分别表示孩子节点和双亲节点的下标
char *cd=(char *)malloc(n*sizeof(char));
cd[n-1]='\0'; // 从右往左存放编码,首先存放结束符
for(int i=1;i<=n;i++){
int start=n-1;
c=i;
p=ht[c].parent;
while(p!=0){
start--;
if(ht[p].left==c){
cd[start]='0';
}else{
cd[start]='1';
}
c=p;
p=ht[c].parent;
}
hc[i]=(char*)malloc((n-start)*sizeof(char));
strcpy(hc[i],&cd[start]);
}
free(cd);
}
主函数
int main(){
HTree ht;
int w[]={0,5,7,3,2,8},n=5;
ht=(HTree)malloc(N*sizeof(HTNode));
createHuffmanTree(ht,w,n);
for(int i=1;i<=2*n-1;i++){
printf("%d %d %d %d\n",ht[i].weight,ht[i].parent,ht[i].left,ht[i].right);
}
printf("*****************************\n");
char *hc[15];
createHuffmanCode(ht,n,hc);
for(int i=1;i<=n;i++){
printf("%s\n",hc[i]);
}
printf("******************\n");
return 0;
}