王道复试C语言 第六章树形数据结构(中:二叉树)——代码笔记分享

文章目录

  • 二叉树
    • 链式存储:存储节点
    • 结构体:描述节点
    • 10.1先序建树
    • 先序遍历
      • 递归实现
      • 栈实现
    • 中序遍历
      • 递归实现
      • 栈实现
    • 后序遍历
      • 递归实现
      • 栈实现
    • 层次遍历:队列实现
    • 10.2重建二叉树:输入先序和中序,输出后序

树章节的内容是根据我自己之前的代码编写的,与王道课程有出入,仅作参考。

二叉树

链式存储:存储节点

root变量:存储根节点的地址
每个节点:数据域+指针域(左孩子和右孩子)
王道复试C语言 第六章树形数据结构(中:二叉树)——代码笔记分享_第1张图片

结构体:描述节点

struct biTree {
	char data;
	biTree* lchild;
	biTree* rchild;
};

10.1先序建树

牛客网OJ

#define _CRT_SECURE_NO_WARNINGS
#include 

struct biTree {
	char data;
	biTree* lchild;
	biTree* rchild;
};

biTree* create(biTree* T) {
	char data;
	scanf("%c", &data);
	if (data != '#') {//#在输入时作为空结点标识
		T = new biTree;//创建空结点
		T->data = data;//数据域赋为输入值
		T->lchild = NULL;//指针域设为空
		T->rchild = NULL;
		T->lchild = create(T->lchild);//先序递归创建
		T->rchild = create(T->rchild);
	}
	return T;
}

void inOrder(biTree* T) {
	if (!T) {
		return;
	}
	inOrder(T->lchild);//左
	printf("%c ", T->data);//中
	inOrder(T->rchild);//右
}

int main() {
	biTree* T = new biTree;//申请一个根节点空间
	T = create(T);//输入先序序列创建一颗二叉树,空结点以#代替 
    inOrder(T);
	return 0;
}

先序遍历

递归实现

#define _CRT_SECURE_NO_WARNINGS
#include 

struct biTree {
	char data;
	biTree* lchild;
	biTree* rchild;
};

void preOrder(biTree* T) {
	if (!T) {
		return;
	}
	printf("%c ", T->data);//根
	preOrder(T->lchild);//左
	preOrder(T->rchild);//右
}

int main() {
	biTree* T = new biTree;
	biTree* create(biTree*);//创建函数放在资源文件里
	T = create(T);//输入先序序列创建一颗二叉树,空结点以#代替 
	printf("二叉树的先序序列为:");
	preOrder(T);
	return 0;
}

栈实现

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;

struct biTree {
	char data;
	biTree* lchild;
	biTree* rchild;
};

void preOrderStack(biTree* T) {
	biTree* p = T;//复制一颗树,以防原数据丢失
	stack<biTree*> s;
	while (p || !s.empty()) {
		if (p) {
			printf("%c ", p->data);//根
			s.push(p);
			p = p->lchild;//左
		}
		else {
			p = s.top();
			s.pop();
			p = p->rchild;//右
		}
	}
}

int main() {
	biTree* T = new biTree;
	biTree* create(biTree*);//创建函数放在资源文件里
	T = create(T);//输入先序序列创建一颗二叉树,空结点以#代替 
	printf("二叉树的先序序列为:");
	preOrderStack(T);
	return 0;
}

中序遍历

递归实现

#define _CRT_SECURE_NO_WARNINGS
#include 

struct biTree {
	char data;
	biTree* lchild;
	biTree* rchild;
};

void inOrder(biTree* T) {
	if (!T) {
		return;
	}
	inOrder(T->lchild);//左
	printf("%c ", T->data);//根
	inOrder(T->rchild);//右
}

int main() {
	biTree* T = new biTree;
	biTree* create(biTree*);
	T = create(T);
	printf("二叉树的中序序列为:");
	inOrder(T);
}

栈实现

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;

struct biTree {
	char data;
	biTree* lchild;
	biTree* rchild;
};

void inOrderStack(biTree* T) {
	biTree* p = T;
	stack<biTree*> s;
	while (p || !s.empty()) {
		if (p) {
			s.push(p);
			p = p->lchild;//左
		}
		else {
			p = s.top();
			printf("%c ", p->data);//根
			s.pop();
			p = p->rchild;//右
		}
	}
}

int main() {
	biTree* T = new biTree;
	biTree* create(biTree*);
	T = create(T);
	printf("二叉树的中序序列为:");
	inOrderStack(T);
}

后序遍历

递归实现

#define _CRT_SECURE_NO_WARNINGS
#include 

struct biTree {
	char data;
	biTree* lchild;
	biTree* rchild;
};

void postOrder(biTree* T) {
	if (!T) {
		return;
	}
	postOrder(T->lchild);//左
	postOrder(T->rchild);//右
	printf("%c ", T->data);//根
}

int main() {
	biTree* T = new biTree;
	biTree* create(biTree*);
	T = create(T);
	printf("二叉树的后序序列为:");
	postOrder(T);
}

栈实现

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;

struct biTree {
	char data;
	biTree* lchild;
	biTree* rchild;
};

void postOrderStack(biTree* T) {
	biTree* p = T;
	biTree* r = NULL;//暂存上一个输出的节点
	stack<biTree*> s;
	while (p || !s.empty()) {
		if (p) {
			s.push(p);
			p = p->lchild;//左
		}
		else {
			p = s.top();
			if (p->rchild && p->rchild != r) {
				p = p->rchild;//右
			}
			else {
				printf("%c ", p->data);//根
				s.pop();
				r = p;
				p = NULL;
			}
		}
	}
}

int main() {
	biTree* T = new biTree;
	biTree* create(biTree*);
	T = create(T);
	printf("二叉树的后序序列为:");
	postOrderStack(T);
}

层次遍历:队列实现

#define _CRT_SECURE_NO_WARNINGS
#include 
#include
using namespace std;

struct biTree {
	char data;
	biTree* lchild;
	biTree* rchild;
};

void levelOrder(biTree* T) {
	biTree* p = T;
	queue<biTree*> q;
	q.push(p);

	while (!q.empty()) {
		p = q.front();
		q.pop();
		printf("%c ", p->data);
		if (p->lchild)
			q.push(p->lchild);
		if (p->rchild)
			q.push(p->rchild);
	}
}

int main() {
	biTree* T = new biTree;
	biTree* create(biTree*);
	T = create(T);
	printf("二叉树的层次序列为:");
	levelOrder(T);
}

10.2重建二叉树:输入先序和中序,输出后序

牛客网OJ

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
using namespace std;

struct biTree {
	char data;
	biTree* lchild;
	biTree* rchild;
};

biTree* rebuild(string preOrder, string inOrder) {
	//返回树的根节点的地址
	if (preOrder.size() == 0) {//递归的最小问题
		return NULL;
	}
	else {
		//从先序确定根
		char rootdata = preOrder[0];
		biTree* newNode = new biTree;
		newNode->data = rootdata;
		//拿根去切割中序
		int pos = inOrder.find(rootdata);//pos是根在中序序列中的下标
		//preOrder.substr(1, pos);左子树:从preOrder中切割出从下标1开始,长度为pos的子串
		//preOrder.substr(pos + 1); 右子树:从preOrder中切割出从下标pos+1开始,到结束位置的子串
		//inOrder.substr(0, pos);左子树
		//inOrder.substr(pos + 1);右子树
		newNode->lchild = rebuild(preOrder.substr(1, pos), inOrder.substr(0, pos));
		newNode->rchild = rebuild(preOrder.substr(pos + 1), inOrder.substr(pos + 1));
		return newNode;
	}
}

void postOrder(biTree* T) {
	if (!T) {
		return;
	}
	postOrder(T->lchild);//左
	postOrder(T->rchild);//右
	printf("%c", T->data);//根
}

int main() {
	char preOrder[30];
	char inOrder[30];
	while (scanf("%s%s", preOrder, inOrder) != EOF) {
		biTree* T = rebuild(preOrder, inOrder);
		postOrder(T);
		printf("\n");
	}
}

你可能感兴趣的:(C++,数据结构,c语言,c++)