数据结构总结【树与二叉树】

//  第六章 : 二叉树
#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;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

战胜.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值