数据结构算法面试题精选及整理-二叉树

                                                              数据结构算法面试题精选及整理

                                                                                                            by: Ju136

可能很多从也学习过算法与数据结构,这里主要讨论一些比较经典的代码与算法。并给出思路与代码。主要收集与整理了网络上、或者面试过程中经常问到的问题。能力有限,欢迎指正。

Note

在本文中,虽然代码风格可能与《高质量C/C++编程》中所提到代码风格不一样,但是我可以说一下我的原则,

一句话一种情况的处理。尽量把代码的量缩小,意思更集中。比如:

node<T> *t = new node<T>(); t->data = value; t->left = t->right = NULL;

这里很明显看得出来是申请一个变量并进行初始化操作。如果是写成如下形式

node<T> *t = new node<T>(); 
t->data = value; 
t->left =NULL;
t->right = NULL;

感觉代码量上去了,意思不集中。

一句话,本文的代码目的是集中表述意思减少代码量

树可能是最经常被问到的一个问题,这里先把最基本的一些知识进行被充与复习。

在建立你的程序之前,请包含以下头文件。建议使用G++进行C++的学习。当然VS也可以好好帮我们进行debug.

#include<iostream>
#include<stack>
#include<queue>
#include<stdlib.h>
#include<string>
#include<string.h>
#include<stdio.h>
using namespace std;

二叉树结点

这里我们采用最简单的 struct,对于只是讨论数据结构来说,struct足够了,当然也可以写成class的形式,不过要添加很多代码。结构处理考虑得更多,这里也不再多说了。

template<typename T>
struct node
{
	T data;
	node *left;
	node *right;
};

建立二叉树

首先一般自己在写代码的时候,需要建立一个树来进行测试,一般会手动地去添加一个树。下面提供一种自动生成二叉树的方式。当然,主要还是基于随机生成的方法。来减少手动生成树的麻烦。

在下面的代码中level表示建立的树的层数。

代码的大意比较容易理解:根据生成的随机数来决定哪个子树接着生成树。这个代码可以保证生成的树是具有level层的。

template<typename T>
node<T> *create(int level)
{
	if (!level) return NULL;

	node<T> *t = new node<T>();
	t->data = rand() % 10;   //这里为了简单起见,使用了rand函数,实际上也可以根据具体的情况来进行处理。
        t->left = t->right = NULL;
	if (1 == level) return t;

	int v = rand() % 3;
	switch(v)
	{
		case 0:
			t->left = create<T>(level - 1);
			t->right = create<T>(level - 1);
			break;
		case 1:
			t->left = create<T>(level - 1);
			break;
		case 2:
			t->right = create<T>(level - 1);
			break;
		default: break;
	}
	return t;
}

这里也给出树的销毁。

template<typename T>
void free_tree(node<T> *t)
{
	if (!t) return;
	free_tree(t->left);
	free_tree(t->right);
	delete t;
}

实际上就是按照后序在进行销毁。

在讨论如何使用前序与中序生成二叉树之前,我们先把一些基本的遍历回顾一下。

递归遍历

相信递归的遍历是比较简单的,这里写出三种遍历的递归方式:

template<typename T>
void front_order(const node<T> *t)
{
	if (!t) return;
	cout << t->data;
	front_order(t->left);
	front_order(t->right);
}

template<typename T>
void mid_order(node<T> *t)
{
	if (!t) return;
	mid_order(t->left);
	cout << t->data;
	mid_order(t->right);
}

template<typename T>
void back_order(node<T> *t)
{
	if (!t) return;
	back_order(t->left);
	back_order(t->right);
	cout << t->data;
}

非递归实现

那么如何用非递归来进行实现?

这里也给出代码如下:

template<typename T>
void front(node<T> *t)
{
	if (!t) return;
	stack<node<T> *> s;
	while (t || !s.empty())
	{
		while (t) { cout << t->data; s.push(t); t = t->left;}
		t = s.top(); s.pop(); t = t->right;
	}
}

template<typename T>
void mid(node<T> *t)
{
	if (!t) return;
	stack<node<T> *> s;
	while (t || !s.empty())
	{
		while (t) { s.push(t); t = t->left;}
		t = s.top(); s.pop(); 
		cout << t->data;
		t = t->right;
	}
}

template<typename T>
void back(node<T> *t)
{
	if (!t) return;
	stack<node<T> *> s;
	node<T> *pre = NULL;
	while (t || !s.empty())
	{
		while (t) { s.push(t); t = t->left;}
		t = s.top();
		if (t->right == NULL || pre == t->right)
		{
			cout << t->data;
			s.pop(); pre = t; t = NULL;
		}
		else t = t->right;
	}
}

言多有失,尽量好好体会一下这些代码。

    原文作者:ju136
    原文地址: https://blog.csdn.net/ju136/article/details/6852215
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞