======================================================
二叉链表.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
//1
typedef struct BiTNode
{
int data;
struct BiTNode *lchild, *rchild;
}BiTNode;
typedef struct BiTNode * BiTree;
//2
//第二种表示方法 三叉链表
//三叉链表
typedef struct TriTNode
{
int data;
//左右孩子指针
struct TriTNode *lchild, *rchild;
struct TriTNode *parent;
}TriTNode, *TriTree;
//双亲链表
#define MAX_TREE_SIZE 100
typedef struct BPTNode
{
int data;
int parentPosition; //指向双亲的指针 //数组下标
char LRTag; //左右孩子标志域
}BPTNode;
typedef struct BPTree
{
BPTNode nodes[100]; //因为节点之间是分散的,需要把节点存储到数组中
int num_node; //节点数目
int root; //根结点的位置 //注意此域存储的是父亲节点在数组的下标
}BPTree;
//用这个数据结构能表达出一颗树。。。能,怎么表达?不能why
void main()
{
BPTree myTree; //
myTree.root = 0; //数组的0号位置 是根结点
myTree.nodes[0].data = 'A';
//B
myTree.nodes[1].data = 'B';
myTree.nodes[1].parentPosition = 0;
myTree.nodes[1].LRTag = 1;
//C
myTree.nodes[2].data = 'C';
myTree.nodes[2].parentPosition = 0;
myTree.nodes[2].LRTag = 2;
system("pause");
}
void main11()
{
BiTNode nodeA, nodeB, nodeC, nodeD, nodeE;
nodeA.lchild = NULL;
nodeA.rchild = NULL;
nodeA.data = 0;
memset(&nodeA, 0, sizeof(BiTNode));
memset(&nodeB, 0, sizeof(BiTNode));
memset(&nodeC, 0, sizeof(BiTNode));
memset(&nodeD, 0, sizeof(BiTNode));
memset(&nodeE, 0, sizeof(BiTNode));
nodeA.data = 1;
nodeA.lchild = &nodeB;
nodeA.rchild = &nodeC;
nodeB.lchild = &nodeD;
nodeC.lchild = &nodeE;
printf("hello...\n");
system("pause");
return ;
}
============================================================
树的操作.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
//1
typedef struct BiTNode
{
int data;
struct BiTNode *lchild, *rchild;
}BiTNode;
typedef struct BiTNode * BiTree;
//先序遍历
void preOrder(BiTNode *T)
{
if (T == NULL)
{
return ;
}
printf("%d ", T->data); //
if (T->lchild != NULL)
{
preOrder(T->lchild);
}
if (T->rchild != NULL)
{
preOrder(T->rchild);
}
}
void InOrder(BiTNode *T)
{
if (T == NULL)
{
return ;
}
if (T->lchild != NULL)
{
InOrder(T->lchild);
}
printf("%d ", T->data); //
if (T->rchild != NULL)
{
InOrder(T->rchild);
}
}
void PostOrder(BiTNode *T)
{
if (T == NULL)
{
return ;
}
if (T->lchild != NULL)
{
PostOrder(T->lchild);
}
if (T->rchild != NULL)
{
PostOrder(T->rchild);
}
printf("%d ", T->data); //
}
/*
1
2 3
4 5
*/
//求树的叶子结点的个数
int sum = 0;
void coutLeafNum(BiTNode *T)
{
if (T == NULL)
{
return ;
}
if (T->lchild == NULL && T->rchild ==NULL)
{
sum ++;
}
coutLeafNum(T->lchild); //求左子树的叶子结点个数
coutLeafNum(T->rchild); //求右子树 叶子结点个数
}
//1 递归函数遇上全局变量 ===>函数参数
//2 //遍历的本质 强化
//访问树的路径是相同的,是不过是计算叶子结点的时机不同....
void coutLeafNum2(BiTNode *T, int *sum)
{
if (T == NULL)
{
return ;
}
if (T->lchild == NULL && T->rchild ==NULL)
{
//*sum++;
//*sum = *sum +1;
(*sum )++ ; //++后置 ++ 先*p 然后sum++
//1 p++
//1 是让实参++ 而不是让地址++
}
coutLeafNum2(T->lchild, sum); //求左子树的叶子结点个数
coutLeafNum2(T->rchild, sum); //求右子树 叶子结点个数
}
void coutLeafNum3(BiTNode *T, int *sum)
{
if (T == NULL)
{
return ;
}
coutLeafNum3(T->lchild, sum); //求左子树的叶子结点个数
coutLeafNum3(T->rchild, sum); //求右子树 叶子结点个数
if (T->lchild == NULL && T->rchild ==NULL)
{
(*sum )++ ; //计算叶子结点
}
}
//求树的高度
int Depth(BiTNode *T)
{
int depthval = 0;
int depthLeft = 0, depthRight = 0;
if (T == NULL)
{
return 0;
}
depthLeft = Depth(T->lchild); //求左子树的高度
depthRight = Depth(T->rchild); //求右子树的高度
//1 + 谁大要谁
depthval = 1 + ( (depthLeft>depthRight) ? depthLeft :depthRight );
return depthval;
}
//copy二叉树
BiTNode* CopyTree(BiTNode *T)
{
BiTNode *newlptr = NULL;
BiTNode *newRptr = NULL;
BiTNode *newNode = NULL;
if (T == NULL)
{
return NULL;
}
newlptr = CopyTree(T->lchild);
newRptr = CopyTree(T->rchild);
//new结点
newNode = (BiTNode *)malloc(sizeof(BiTNode)) ; //
if (newNode == NULL)
{
return NULL;
}
newNode->data = T->data; //从旧树中copy数据
newNode->lchild = newlptr; //新的左子树
newNode->rchild = newRptr; //新的右子树
return newNode;
}
void main()
{
BiTNode nodeA, nodeB, nodeC, nodeD, nodeE;
nodeA.lchild = NULL;
nodeA.rchild = NULL;
nodeA.data = 0;
memset(&nodeA, 0, sizeof(BiTNode));
memset(&nodeB, 0, sizeof(BiTNode));
memset(&nodeC, 0, sizeof(BiTNode));
memset(&nodeD, 0, sizeof(BiTNode));
memset(&nodeE, 0, sizeof(BiTNode));
nodeA.data = 1;
nodeB.data = 2;
nodeC.data = 3;
nodeD.data = 4;
nodeE.data = 5;
nodeA.lchild = &nodeB;
nodeA.rchild = &nodeC;
nodeB.lchild = &nodeD;
nodeC.lchild = &nodeE;
//拷贝二叉树
{
BiTNode *newTree = NULL;
newTree = CopyTree(&nodeA);
printf("\n中序遍历新树:");
InOrder(newTree);
}
{
//求树的高度
int depth = Depth(&nodeA);
printf("depth:%d \n", depth);
}
//计算树的叶子结点
{
int mysum = 0;
coutLeafNum(&nodeA);
printf("sum:%d \n", sum);
coutLeafNum2(&nodeA, &mysum);
printf("mysum:%d \n", mysum);
mysum = 0;
coutLeafNum3(&nodeA, &mysum);
printf("mysum:%d \n", mysum);
}
//printf("\n先序遍历树: ");
//preOrder(&nodeA);
printf("\n中序遍历树: ");
InOrder(&nodeA);
//printf("\n后序遍历树: ");
//PostOrder(&nodeA);
system("pause");
}
=========================================================
中序递归.c
#include <iostream>
using namespace std;
#include "stack"
//1
typedef struct BiTNode
{
int data;
struct BiTNode *lchild, *rchild;
}BiTNode;
typedef struct BiTNode * BiTree;
//递归 中序遍历
void InOrder(BiTNode *T)
{
if (T == NULL)
{
return ;
}
if (T->lchild != NULL)
{
InOrder(T->lchild);
}
printf("%d ", T->data); //
if (T->rchild != NULL)
{
InOrder(T->rchild);
}
}
BiTNode * GoFarLeft(BiTNode *T, stack<BiTNode *> &s)
{
if (T ==NULL)
{
return NULL;
}
while (T->lchild != NULL) //一直往左走 ,找到中序遍历的起点
{
s.push(T);
T = T->lchild; //让指针下移
}
return T; //
}
void MyInOrder(BiTNode *T)
{
stack<BiTNode *> s; //
BiTNode *t = GoFarLeft(T, s); //一直往左走 找到中序遍历的起点
while (t != NULL)
{
printf("%d ", t->data);
//若结点 有右子树,重复步骤1
if (t->rchild != NULL)
{
t = GoFarLeft(t->rchild, s);
}
//若结点 没有右子树 看栈是否为空
else if ( !s.empty() )
{
t = s.top(); //把栈顶弹出
s.pop();
}
else
{
t = NULL;
}
}
}
void main()
{
BiTNode nodeA, nodeB, nodeC, nodeD, nodeE;
nodeA.lchild = NULL;
nodeA.rchild = NULL;
nodeA.data = 0;
memset(&nodeA, 0, sizeof(BiTNode));
memset(&nodeB, 0, sizeof(BiTNode));
memset(&nodeC, 0, sizeof(BiTNode));
memset(&nodeD, 0, sizeof(BiTNode));
memset(&nodeE, 0, sizeof(BiTNode));
nodeA.data = 1;
nodeB.data = 2;
nodeC.data = 3;
nodeD.data = 4;
nodeE.data = 5;
nodeA.lchild = &nodeB;
nodeA.rchild = &nodeC;
nodeB.lchild = &nodeD;
nodeC.lchild = &nodeE;
printf("\n中序遍历递归算法");
InOrder(&nodeA);
printf("\n中序遍历非递归算法");
MyInOrder(&nodeA);
cout<<"hello..."<<endl;
system("pause");
return ;
}
====================================================
树的线索化.c
#define _CRT_SECURE_NO_WARNINGS
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
/* Link==0表示指向左右孩子指针, */
/* Thread==1表示指向前驱或后继的线索 */
#define Thread 1
#define Link 0
typedef struct BiThrNode /* 二叉线索存储结点结构 */
{
char data; /* 结点数据 */
struct BiThrNode *lchild, *rchild; /* 左右孩子指针 */
int LTag;
int RTag; /* 左右标志 */
} BiThrNode, *BiThrTree;
char Nil='#'; /* 字符型以空格符为空 */
/* 按前序输入二叉线索树中结点的值,构造二叉线索树T */
BiThrNode* CreateBiThrTree()
{
BiThrNode *tmp = NULL;
char ch;
scanf("%c",&ch);
if (ch == '#')
{
return NULL;
}
else
{
tmp = (BiThrNode *)malloc(sizeof(BiThrNode));
if (tmp == NULL)
{
return NULL;
}
memset(tmp, 0, sizeof(BiThrNode));
tmp->data = ch;
tmp->lchild = CreateBiThrTree(); /* 递归构造左子树 */
tmp->rchild = CreateBiThrTree();
}
return tmp;
}
BiThrNode *pre; /* 全局变量,始终指向刚刚访问过的结点 */
/* 中序遍历进行中序线索化 */
void InThreading(BiThrNode *p)
{
if(p)
{
InThreading(p->lchild); // 递归左子树线索化
if(p->lchild == NULL) // 没有左孩子
{
p->LTag = Thread; p->lchild = pre; //前驱线索 左孩子指针指向前驱
}
if(pre->rchild == NULL) // 前驱没有右孩子
{
pre->RTag = Thread; pre->rchild = p; // 后继线索 前驱右孩子指针指向后继(当前结点p)
}
pre = p; // 保持pre指向p的前驱
InThreading(p->rchild); // 递归右子树线索化
}
}
/* 中序遍历二叉树T,并将其中序线索化,Thrt指向头结点 */
BiThrNode* InOrderThreading(BiThrTree T)
{
BiThrNode *Thrt = NULL;
Thrt = (BiThrNode *)malloc(sizeof(BiThrNode)); //建头结点
if (Thrt == NULL)
{
return NULL;
}
memset(Thrt, 0, sizeof(BiThrNode));
Thrt->LTag = Link; //左孩子为孩子指针
Thrt->RTag = Thread; //右孩子为线索化的指针
Thrt->rchild = Thrt; // 右指针回指 */ //步骤2和4
if(T == NULL) // 若二叉树空,则左指针回指
{
Thrt->lchild = Thrt; //步骤1和3
}
else
{
Thrt->lchild = T; //步骤1
pre = Thrt ;
InThreading(T); // 中序遍历进行中序线索化
pre->rchild = Thrt; //步骤4
pre->RTag = Thread; // 最后一个结点线索化
Thrt->rchild = pre; //步骤2
}
return Thrt;
}
/* 中序遍历二叉线索树T(头结点)的非递归算法 */
int InOrderTraverse_Thr(BiThrNode* T)
{
BiThrNode* p;
p = T->lchild; /* p指向根结点 */
while (p != T)
{
/* 空树或遍历结束时,p==T */
while (p->LTag == Link)
p = p->lchild;
printf("%c ", p->data);
//如果中序遍历的最后一个结点的 右孩子 == T 说明到最后一个结点 ,遍历结束..
while (p->RTag==Thread && p->rchild!=T)
{
p = p->rchild;
printf("%c ", p->data);
}
p = p->rchild;
}
return 0;
}
/* 中序遍历二叉线索树T(头结点)的非递归算法 */
int InOrderTraverse_Thr2(BiThrNode* T)
{
BiThrNode* p;
p = T->rchild; /* p指向根结点 */
while (p != T)
{
/* 空树或遍历结束时,p==T */
while (p->RTag == Link)
p = p->rchild;
printf("%c ", p->data);
//如果中序遍历的最后一个结点的 右孩子 == T 说明到最后一个结点 ,遍历结束..
while (p->LTag==Thread && p->lchild!=T)
{
p = p->lchild;
printf("%c ", p->data);
}
p = p->lchild;
}
return 0;
}
int main()
{
BiThrTree T, H;
printf("请按前序输入二叉树(如:'ABDH##I##EJ###CF##G##')\n");
T = CreateBiThrTree(); // 按前序产生二叉树
H = InOrderThreading(T); // 中序遍历,并中序线索化二叉树
printf("中序遍历(输出)二叉线索树:\n");
InOrderTraverse_Thr(H); // 中序遍历(输出)二叉线索树
printf("\n逆序访问:");
InOrderTraverse_Thr2(H);
printf("\n");
system("pause");
return 0;
}