数据结构与算法--二叉树(二)

======================================================

二叉链表.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;
}

















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值