今天终于看到了面试必考之:
栈与队列
由于栈的操作只能在栈顶进行,所以栈的操作的时间复杂度为常数。
函数的递归调用也是通过栈实现的。
将十进制正整数 n 转化为 m 进制数,1 < m <= 16
递归:
void ConvertFun(Stack<char> s, int n, int m)
{
char[] digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
if(n > 0)
{
ConvertFun(s, n/m, m);
s.Push(digit[n%m]);
}
if(s.Count > 0)
{
print(s.Pop());
}
}
非递归:
void ConvertFunc(int n, int m)
{
char[] digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
Stack<char> s = new Stack<char>();
while(n > 0)
{
s.Push(digit[n%m]);
n = n / m;
}
while(s.Count > 0)
{
print(s.Pop());
}
}
判断字符串内括号是否匹配
bool paren(string s)
{
char[] c = s.ToCharArray();
Stack<char> stk = new Stack<char>();
for(int i = 0; i < c.Length; i++)
{
switch(c[i])
case '(': case '[': case '{': stk.Push(c[i]); break;
case ')': if((!stk.Any())||(stk.Pop() != '(')) return false; break;
case ']': if((!stk.Any())||(stk.Pop() != '[')) return false; break;
case '}': if((!stk.Any())||(stk.Pop() != '{')) return false; break;
default:break;
}
return !stk.Any();
}
逆波兰表达式RPN:操作符紧邻于对应的(最后一个)操作数之后
例: 1 2 + 3 4 ^ * = (1+2)*3^4
二叉树
树属于半线性结构。任何有根有序的多叉树都可以等价转化为二叉树。
从图论的角度看,树等价于连通无环图。
一般多叉树转化为二叉树按照“长子+兄弟”的规律转化:长子为左结点,兄弟为右结点。
前缀无歧义编码,PFC编码:各编码串互不为前缀。
PFC编码对应于二叉树即为所有字符都必须是叶节点(字符为父节点会满足其为其子的前缀)。
遍历二叉树
先序遍历 递归
void PreOrder(TreeNode root)
{
if(root == null)
{
return;
}
print(root.value);
PreOrder(root.left);
PreOrder(root.right);
}
先序遍历 非递归:
void PreOrder(TreeNode root)
{
if(root == null)
{
return;
}
Stack<TreeNode> s = new Stack<TreeNode>();
TreeNode nt = new TreeNode(root.value);
while((nt != null) || s.Any())
{
if(nt != null)
{
print(nt.value);
s.Push(nt);
nt = nt.left;
}
else
{
TreeNode tmp = (TreeNode)s.Pop();
nt = tmp.right;
}
}
}
中序遍历 递归
void InOrder(TreeNode root)
{
if(root == null)
{
return;
}
InOrder(root.left);
print(root.value);
InOrder(root.right);
}
中序遍历 非递归
void InOrder(TreeNode root)
{
if(root == null)
{
return;
}
Stack<TreeNode> s = new Stack<TreeNode>();
TreeNode nt = new TreeNode(root.value);
while((nt != null) || s.Any())
{
if(nt != null)
{
s.Push(nt);
nt = nt.left;
}
else
{
print(nt.value);
TreeNode tmp = (TreeNode)s.Pop();
nt = tmp.right;
}
}
}
后序遍历 递归
void PostOrder(TreeNode root)
{
if(root == null)
{
return;
}
PostOrder(root.left);
PostOrder(root.right);
print(root.value);
}
后序遍历 非递归
void PostOrder(TreeNode root)
{
if(root == null)
{
return;
}
Hash<TreeNode> visited = new Hash<TreeNode>() //用于确认是否访问过右结点
Stack<TreeNode> s = new Stack<TreeNode>();
TreeNode nt = new TreeNode(root.value);
while((nt != null) || s.Any())
{
if(nt != null)
{
s.Push(nt);
nt = nt.left;
}
else
{
TreeNode tmp = s.Top();
if(tmp.right != null) && !visited.Contain(tmp.right))
{
nt = tmp.right;
}
else
{
print(tmp.value);
visited.Add(tmp);
s.Pop();
}
}
}
}
层次遍历
void LevelOrder(TreeNode root)
{
if(root == null)
{
return;
}
print(root.value);
Queue q = new Queue();
q.Enqueue(root);
while(q.Any())
{
TreeNode nt = (TreeNode)q.Dequeue();
if(nt.left != null)
{
print(nt.left.value);
q.Enqueue(nt.left);
}
if(nt.right != null)
{
print(nt.right.value);
q.Enqueue(nt.right);
}
}
}