数据结构算法面试题精选及整理
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; } }