Linux与数据结构 2019-3-17上午

1.二叉树

1.1 不用递归实现中序遍历

  • 1.保存,向左走,弹出,打印,向右走
void UnRecInorderTraversal
{
	if(p_tree == NULL)return;

	Stack* p_stack = NULL;
	s_Init(p_stack);

	while(1)
	{
		while(p_tree)
		{
			// 保存
			s_Push(p_stack, p_tree);

			// 向左走
			p_tree = p_tree->p_left;
		}

		// 弹出
		p_tree = s_Pop(p_stack);

		if(p_tree == NULL)return;

		// 打印
		printf("%d ", p_tree->n_value);

		// 向右走
		p_tree = p_tree->p_right;
	}
}

1.2 不使用递归进行后序遍历

  • 1.大致的思路就是:保存、向左走、判断栈顶是否为空、判断栈顶元素是否有右、有右的话是否被打印过、没被打印则返回保存从头开始;
void UnRecLastorderTraversal(BinaryTree* p_tree)
{
	// 定义一个标记来记录上一个被打印过的节点
	BinaryTree* p_flag = NULL;

	// 申请辅助栈
	Stack* p_stack = NULL;
	s_Init(&p_stack);

	// 遍历树
	while(1)
	{
		while(p_tree)
		{
			// 保存
			s_Push(p_stack, p_tree);
			
			// 向左走
			p_tree = p_tree->p_left;
		}

		// 判断栈顶元素是否为空(为空的话不能进行左右节点的判断)
		if(p_stack->p_top->n_value == NULL)break;

		// 判断栈顶元素是否有右节点,有右节点的话是否被打印过
		if(p_stack->p_top->n_value->p_right == NULL || p_stack->p_top->n_value->p_right == p_flag)
		{
			p_flag = s_Pop(p_stack);
			printf("%d ", p_flag->n_value);
		}
		// 栈顶元素的右不为空并且没有被打印过就将其压入栈中
		else
		{
			p_tree = p_stack->p_top->n_value->p_right;
		}
	}
}

1.3 层序遍历(需要用到队列和循环)

  • 1.将队列的代码复制过来;
// ==========================队列==========================
typedef struct node
{
	int n_value;
	struct node* p_next;
}Node;

typedef struct queue
{
	int n_count;
	Node* p_tail;
	Node* p_head;
}Queue;

void q_Init(Queue** pp_queue)
{
	*pp_queue = (Queue*)malloc(sizeof(Queue));
	(*pp_queue)->n_count = 0;
	(*pp_queue)->p_head = NULL;
	(*pp_queue)->p_tail = NULL;
}

void q_Push(Queue* p_queue, BinaryTree* num)
{
	Node* p_temp = NULL;
	if(p_queue == NULL)return;

	p_temp = (Node*)malloc(sizeof(Node));
	p_temp->n_value = num;
	p_temp->p_next = NULL;

	if(p_queue->p_head != NULL)
		p_queue->p_tail->p_next = p_temp;
	else
		p_queue->p_head = p_temp;
	p_queue->p_tail = p_temp;
	p_queue->n_count++;
}

BinaryTree* q_Pop(Queue* p_queue)
{
	BinaryTree* re_num;
	Node* p_del = NULL;
	if(p_queue == NULL)return NULL;

	p_del = p_queue->p_head;
	re_num = p_del->n_value;

	p_queue->p_head = p_queue->p_head->p_next;
	free(p_del);
	p_del = NULL;
	p_queue->n_count--;
	if(p_queue->n_count == 0)p_queue->p_tail = NULL;

	return re_num;
}
// ==========================队列==========================

void SequenceTraversal(BinaryTree* p_tree)
{
	if(p_tree == NULL)return;

	// 申请辅助队列
	Queue* p_queue = NULL;
	q_Init(&p_queue);

	// 根入队
	q_Push(p_queue, p_tree);

	// 将树的节点装入树中
	while(p_queue->n_count)
	{
		p_tree = q_Pop(p_queue);
		printf("%d ", p_tree->n_value);

		if(p_tree->p_left != NULL)
			q_Push(p_queue, p_tree->p_left);
		if(p_tree->p_right != NULL)
			q_Push(p_queue, p_tree->p_right);
	}
}

1.4 如何把一颗二叉树按层打印(我想打印第几层就打印第几层)

  • 1.可以使用两个队列来存储;
  • 2.也可以用两个变量来记录;
  • 3.还可以使用一个特殊标识符来记录;

猜你喜欢

转载自blog.csdn.net/weixin_42896619/article/details/88703859