今天終於看到了面試必考之:
棧與隊列
由於棧的操作只能在棧頂進行,所以棧的操作的時間複雜度爲常數。
函數的遞歸調用也是通過棧實現的。
將十進制正整數 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);
}
}
}