数据结构-线索二叉树

线索指将节点连接在一起的指针

在二叉树中,除根结点外,其余节点均有一个指针指向它,如果有n个结点,那么一共有n-1个有指向的指针。而n个结点一共有2n个指针,那么就会有n+1个空指针。利用这n+1个空指针,令它们指向遍历二叉树时的前驱和后继,就是创建一棵线索二叉树

以中序遍历为例

数据结构-线索二叉树_第1张图片

这样一棵二叉树的中序遍历顺序是DBEAFCG

如果我们把它看成一种线性结构,在这个遍历过程中,D空出来的两个指针可以指向它的前驱(NULL)和后继B,B已经指向了DE,略过看E,令E的两个空指针指向它的前驱B和后继A...以此类推,就创建了一棵线索二叉树。

结构体中增添用于记录指针指向的标记值(等于0时表示指向自己的孩子)

typedef struct Tree{
	struct Tree* leftchild;
	char data;
	struct Tree* rightchild;
	int ltag;//用于记录指向的是自己的左孩子还是前驱结点
	int rtag;//用于记录指向的是自己的右孩子还是后继结点
}BinaryTree;

首先建立一个前驱方便记录线索化过程

BinaryTreee* Pre=(BinaryTree*)malloc(sizeof(BinaryTree));
Pre=NULL;

接着将树线索化

void inThread(BinartTree *T){
	if (T){
		inThread(T->leftchild);//如果有左孩子,继续向左子树里面找空指针
		if (T->leftchild==NULL){//没有左孩子
			T->ltag=1;
			T->leftchild=Pre;//指向前驱结点
		}
		if (Pre&&Pre->rightchild==NULL){//如果前驱右指针为空
			Pre->rtag=1;
			Pre->rightchild=T;//指向T
		}
		Pre=T;//更新前驱
		inThread(T->rightchild);//再遍历右子树
	}
}

最后Pre更新为遍历的最后一个结点,右指针为空

Pre->rtag=1;
Pre->rightchild=NULL;

其余遍历顺序同理

然后记录两道搜索题

洛谷P1067

一道简单的全排列问题

数据结构-线索二叉树_第2张图片

#include 
using namespace std;
int n;//全局变量更方便访问n的值
int num[10];//收录排入的数
bool st[10];//记录数据是否已经排入
void dfs(int m) {
	if (m==n) {//一次排列完成,进行输出
		for (int i=1; i<=n; i++) {
			cout<>n;
	dfs(0);//从0开始搜素
	return 0;
}

经典的八皇后问题P1219

数据结构-线索二叉树_第3张图片

利用递归和回溯,用数组记录位置是否被占据(注意上下对角线的表示方法是行-列+边-1,下对角线表示为行+列)

#include 
using namespace std;
int a[25]= {0};//记录上对角线是否被占据
int b[25]= {0};//记录下对角线是否被占据
int p[13]= {0};//记录每行中皇后所在的列的位置
int l[13]= {0};//记录整列是否被占领
int L;
int c=0;
void print() {
	c++;//每调用一次说明解多一个
	if (c<=3) {//由于c递增在前,要想输出前三次结果需要令c<=3
		for (int i=0; i> L;
	Queen(0);
	cout<

你可能感兴趣的:(数据结构)