数据结构算法面试题精选及整理
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;
}
}
言多有失,尽量好好体会一下这些代码。