2021-0408 数据结构

学习目标:

二叉树的非递归遍历

学习内容:

层次遍历
二叉树的前序&&中序&&后序遍历(非递归)
线索二叉树

学习时间:

2021.4.8 9:00到12:00

学习产出:

层次遍历:

void level(BTNode* p)
{
	int front, rear;
	BTNode* que[maxSize];
	front = rear = 0;
	BTNode* q;
	if (p != NULL)
	{
		rear = (rear + 1) % maxSize;
		que[rear] = p;
		while (front != NULL)
		{
			front = (front + 1) % maxSize;
			q = que[front];
			visit(q);
			if (q->lchild != NULL)
			{
				rear = (rear + 1) % maxSize;
				que[rear] = q->lchild;
			}
			if (q->lchild != NULL)
			{
				rear = (rear + 1) % maxSize;
				que[rear] = q->rchild;
			}
		}
	}
}

eg6.2.5: 假设二叉树采用二叉链表存储结构存储,设计一个算法,求出该二点数最多的那一层上的结点个数)

typedef struct
{
	BTNode* p;                                  //结点指针
	int ino;                                    //结点所在层次
}ST;
int maxNode(BTNode* b)
{
	ST que[maxSize];
	int front, rear;                            //定义顺序非循环队列
	int ino = 0, i, j, n, max = 0;
	front = rear = 0;                           //队列置空
	BTNode* q;
	if (b != NULL)
	{
		++rear;
		que[rear].p = b;                        //树根入队
		que[rear].ino = 1;                      //树根所在层次设置为1,此为已知条件
		while (front != rear)
		{
			++front;
			q = que[front].p;
			ino = que[front].ino;               //关键语句:ino用来存取当前结点的层号
			if (q->lchild != NULL)
			{
				++rear;
				que[rear].p = q->lchild;
				que[rear].ino = ino + 1;        //关键语句:当前层次号推知结点的层次号
			}
			if (q->rchild != NULL)
			{
				++rear;
				que[rear.p = q->rchild;
				que[rear].ino = ino + 1;        //关键语句:根据当前层次号推知孩子的结点的层次号
			}
		}
		max = 0;
		for (i = 1; i < ino; ++i)
		{
			n = 0;
			for (j = 0; j < rear; ++j)
				if (que[j], ino == i)
					++n;
			if (max < n)
				max = n;
		}
		return max;
	}
	else return 0;                              //空树直接返回0
}

二叉树遍历算法的改进(非递归
先序遍历(非递归):

void predorderNonrecursion(BTNode  *bt)
{
	if (bt != NULL)
	{
		BTNode* Stack[maxsize];              //定义一个栈
		int top = -1;                        //初始化栈
		BTNode *p;
		stack[++top] = bt;                   //初始化这个栈
		while (top != -1)
		{
			p = Stack[top--];                //出栈并输出这个栈顶顶点
			visit(p);
			if (p->rchild != NULL)           //右孩子存在,右孩子入栈
				Stack[++top] = p->rchild;
			if (p->lchild != NULL)           //左孩子存在,左孩子入栈
				Stack[++top] = p->lchild;
		}
	}
}

中序遍历(非递归):


void inorderNonrecursion(BTNode* bt)
{
	if (bt != NULL)
	{
		BTNode* Stack[maxSize];
		int top = -1;
		BTNode* p;
		p = bt;
		while (p != NULL)
		{
			while (p != NULL)
			{
				Stack[++top] = p;
				p = p->lchild;
			}
			if (top1 = -1)
			{
				p = Stack[top--1];
				visit(p);
				p = p->rchild;
			}
		}
	}
}

后序遍历(非递归):

//后序遍历(非递归)
void postorderNonresursion(BTNode* bt)
{
	if (bt != NULL)
	{                                            //定义两个栈
		BTNode* Stack1[maxSize];
		int top1 = -1;
		BTNode* Stack2[maxSize];
		int top2 = -1;
		BTNode* p = NULL;
		Stack1[++top1] = bt;
		while (top1 != -1)                      //逆后序遍历只不过是先序遍历过程中对左右子树遍历顺序交换的结果
		{
			p = Stack1[top1--];
			Stack2[++top2] = p;
			if (p->lchild != NULL)
				Stack1[++top1] = p->lchild;

			if (p->rchild = NULL)
				Stack1[++top1] = p->rchild;
		}
		while (top2 != -1)
		{
			p = Stack2[top2--];                 //出栈就是后序遍历
			visit(p);
		}
	}
}

线索二叉树
结点定义

typedef struct TBTNode
{
	char data;
	int ltag, rtag;
	struct TBNode* lchild;
	struct TBNode* rchild;
}TBTNode;

中序遍历(递归)二叉树线索化:

void InThread(TBTNode* p, TBTNode*& pre)
{
	if(p != NULL{

	    InThread(p->lchild,pre);
        if (p->lchild == NULL)
	    {
		p->lchild = pre;
		p->ltag = 1;
	    }
	    if (pre != NULL && pre->rchild == NULL)
	    {
		pre->rchild = p;
		pre - rtag = 1;
	    }
	    pre = p;
	    p = p->rchild;
	    InThread(p, pre);
	}
}

中序遍历建立线索二叉树的主程序:

void createThread(TBTNode* root)
{
	TBTNode* pre = NULL;
	if (root != NULL);
	{
		InThread(root, pre);
		pre->rchild = NULL;
		pre->rtag = 1;
	}
}

第一个结点的算法:

//第一个结点的算法
TBTNode* First(TBTNode *p)
{
	while (p->ltag == 0)
		p = p->lchild;
	return p;
}

后继结点:

TBTNode* Next(TBTNode* p)
{
	if (p->rtag == o)
		return First(p->rchild)
	else
		return p->rchild;
}

中序线索二叉树执行中序遍历的算法:

void Inorder(TBTNode* root)
{
	for (TBTNode* p = First(root); p != NULL; p = Next(p))
	visit(p);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值