在 LaTeX 中绘制激活堆栈

在 LaTeX 中绘制激活堆栈

我正在尝试绘制一个激活堆栈。我非常擅长 TikZ,所以我希望你能帮助我。

激活堆栈图

如您所见,有四个框一个叠在另一个上面。每个框都有一个名称,放在右侧,由上部和下部组成,上部显示变量和数字,下部分为两半。左半部分必须包含指向其下方框之一的箭头,右半部分仅包含几个字符。底部的框没有尖尖的箭头,因为它不必引用任何东西。

我真的希望你能帮助我,我非常感激。

答案1

你可以从以下方式开始:

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{positioning, arrows.meta}
\usepackage{cancel}

\tikzset{box/.style={draw, minimum width=3cm, minimum height=2cm, outer sep=0pt, font=\ttfamily, align=left},
    minibox/.style={box, minimum width=1.5cm, minimum height=5mm, anchor=north west},
    pointer/.style={fill, circle, minimum size=2mm, inner sep=0pt},
    }

\begin{document}
\begin{tikzpicture}[>=Latex]

\node[box, label=right:$P_2$] (P2) {};
\node[minibox] at (P2.south west) (P2-1) {};
\node[minibox] at (P2.south) (P2-2) {};

\node[box, label=right:$P_4$, below=1cm of P2] (P4) {};
\node[minibox] at (P4.south west) (P4-1) {};
\node[minibox] at (P4.south) (P4-2) {};

\node[box, label=right:$P_3$, below=1cm of P4] (P3) {a/d(p1)=0\\b=\cancel{3} 2};
\node[minibox] at (P3.south west) (P3-1) {};
\node[minibox] at (P3.south) (P3-2) {};

\node[box, label=right:$P_4$, below=1cm of P3] (P1) {a=3\\b=2\\c=1\\d=0};
\node[minibox] at (P1.south west) (P1-1) {};
\node[minibox] at (P1.south) (P1-2) {\# 6};

\draw[->] (P2-1.center) coordinate[pointer]  -- ([xshift=-10mm]P2-1.west) |- ([yshift=-8mm]P3.north west);
\draw[->] (P4-1.center) coordinate[pointer]  -- ([xshift=-5mm]P4-1.west) |- ([yshift=-4mm]P3.north west);
\draw[->] (P3-1.center) coordinate[pointer]  -- ([xshift=-5mm]P3-1.west) |- ([yshift=-4mm]P1.north west);
\draw[-|] (P1-1.center) coordinate[pointer]  -- ([xshift=-5mm]P1-1.west);
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

您可能会发现我写的一本书中的这段摘录很有用。请不要直接使用。

\documentclass{独立}
\usepackage[dvipsnames]{xcolor}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{链}
\usetikzlibrary{计算}
\usetikzlibrary{形状}
\usetikzlibrary{shapes.multipart}

\newcommand\kk[1]{\textcolor{RoyalBlue}{\text{\textup{\textbf{\texttt{#1}}}}}
\newcommand\cc[1]{\textcolor{Sepia}{\text{\textup{\textbf{\texttt{#1}}}}}

\开始{文档}

\开始{tikzpicture}
\begin{范围}[起始链=向左,节点距离=0pt]
\def\width{9ex}

\tikzstyle{框架}=[
    字体=\scriptsize,
    %文本宽度=7ex,
    画,
    在链上,
    矩形分割,
    矩形分割部分=20,
    矩形分割部分对齐={center, left},
    矩形分割空部分高度=0ex,
    矩形分割空部分深度=0ex,
    矩形分割空部分宽度=0ex,
]

\node(主)[框架,
    矩形分割部分=5,
    矩形分割部分填充={紫红色!30,棕色!30,棕色!30,黄色!40}
] {%
\nodepart{一}
  \begin{迷你页面}{\宽度}
    \centering 保存的 O/S 状态
  \end{迷你页面}
\nodepart{two} \kk{int} \cc{argc}
\nodepart{three} \kk{char} \cc{**argv}
\nodepart{四}
  \开始{minipage}{14ex} \居中
   \kk{int} \cc{a[500]}\medskip\\
    \tikz{\node(a)[
    画,
    字体=\tiny,
    文本宽度=12ex,
    矩形分割部分,
    矩形分割部分填充={黄色},
    矩形分割部分对齐={左,左,左,左}
  ][%]
    \nodepart{一} \cc{a[499]}
    \nodepart{two} \cc{a[498]}
    \nodepart{three} {\begin{minipage}{6ex}\quad\\\mbox{\quad}\large\qquad$\vdots$\quad\\\scriptsize\end{minipage}}
    \nodepart{四}\cc{a[1]}
    \nodepart{五}\cc{a[0]}
  };}
  \end{迷你页面}
\nodepart{五}
  \开始{minipage}{14ex} \居中
   \kk{int} \cc{b[200]}\\
    \tikz{\node[
    画,
    文本宽度=12ex,
    字体=\tiny,
    矩形分割部分=3,
    矩形分割部分填充={黄色},
    矩形分割部分对齐={左,左,左,左}
  ][%]
    \nodepart{一} \cc{b[199]}
    \nodepart{two} {\large $\vdots$}
    \nodepart{three}\cc{b[0]}
  };}
  \end{迷你页面}
};

\node(排序)[框架,
    矩形分割部分=3,
    文本宽度=10ex,
    矩形分割部分填充={Fuchsia!30,brown!30,brown!30}
] {%
\nodepart{一}
  \begin{迷你页面}{\宽度}
    \centering 保存了 \cc{main} 的状态
  \end{迷你页面}
\nodepart{two} \kk{int} \cc{*a}
\nodepart{three} \kk{int} \cc{n}
};

\node(qsort1)[框架,
    矩形分割部分=5,
    矩形分割部分填充={Fuchsia!30,teal!30,brown!30,brown!30,yellow!40}
] {%
\nodepart{一}
  \begin{迷你页面}{\宽度}
    \centering 保存了 \cc{sort} 的状态
  \end{迷你页面}
\nodepart{two} \kk{void} \cc{*bp} \quad
\nodepart{three} \kk{int} \cc{来自}
\nodepart{四} \kk{int} \cc{至}
\nodepart{五} \kk{int} \cc{p}
};

\node (qsort2) [框架,  
    矩形分割部分=5,
    矩形分割部分填充={Fuchsia!30,teal!30,brown!30,brown!30,yellow!40}
] {%
\nodepart{一}
  \begin{迷你页面}{\宽度}
    \centering 保存 \cc{qsort}$_1$ 的状态
  \end{迷你页面}
\nodepart{two} \kk{void} \cc{*bp}
\nodepart{three} \kk{int} \cc{来自}
\nodepart{四} \kk{int} \cc{至}
\nodepart{五} \kk{int} \cc{p}
};

\node (qsort3) [框架,
  文本宽度=9ex,
    矩形分割部分=5,
    矩形分割部分填充={Fuchsia!30,teal!30,brown!30,brown!30,yellow!40}
] {%
\nodepart{一}
  \begin{迷你页面}{\宽度}
    \centering 保存 \cc{qsort}$_2$ 的状态
  \end{迷你页面}
\nodepart{two} \kk{void} \cc{*bp}
\nodepart{three} \kk{int} \cc{来自}
\nodepart{四} \kk{int} \cc{至}
\nodepart{五} \kk{int} \cc{p}
};

\节点(枢轴)[框架,
    矩形分割部分=6,
    矩形分割部分填充={Fuchsia!30,teal!30,yellow!40}
] {%
\nodepart{一}
  \begin{迷你页面}{\宽度}
    \centering 保存 \cc{qsort}$_3$ 的状态
  \end{迷你页面}
\nodepart{two}\kk{void} \cc{*bp}
\nodepart{三}\kk{int} \cc{最后}
\nodepart{四}\kk{int} \cc{枢轴}
\nodepart{五}\kk{int} \cc{拆分}
\nodepart{六}\kk{int} \cc{i}
};

\node(交换)[框架,
    矩形分割部分=5,
    矩形分割部分填充={Fuchsia!30,teal!30,brown!30,brown!30,yellow!40}
] {%
\nodepart{一}
  \begin{迷你页面}{\宽度}
    \centering 保存了 \cc{pivot} 的状态
  \end{迷你页面}
\nodepart{two} \kk{void} \cc{*bp}
\nodepart{three} \kk{int} \cc{i}
\nodepart{四} \kk{int} \cc{j}
\nodepart{五} \kk{int} \cc{t}
};

\node(arrow)[链上]{\Huge$\Leftarrow$};

\node[above=0 pt of main.north,anchor=south,font=\itshape] {main};
\node[above=0 pt of sort.north,anchor=south,font=\itshape] {sort};
\node[qsort1.north 的 above=0 pt,anchor=south,font=\itshape] {qsort$_1$};
\node[qsort2.north 的 above=0 pt,anchor=south,font=\itshape] {qsort$_2$};
\node[qsort3.north 的 above=0 pt,anchor=south,font=\itshape] {qsort$_3$};
\node[above=0 pt of pivot.north,anchor=south,font=\itshape] {pivot};
\node[above=0 pt of swap.north,anchor=south,font=\itshape] {swap};

\tikzstyle{bp}=[draw=black,thin,->,opacity=0.5,>=latex,->]
\draw[bp] 让
            \p1 = ($(qsort1.two 东)!0.1!(qsort1.two) $),
         \p2 = ($(main.text)+(0,0) $),
           \p3 = ($(sort.text split)!0.75!(sort.text split 东) +(1ex,0)$)
                (\x1,\y1)->(\x1,\y2)--(\x3,\y2)--(\x3,\y3);
\draw[bp] 让
            \p1 = ($(qsort2.two 东)!0.1!(qsort2.two) $),
         \p2 = ($(main.text)+(0,1ex) $),
           \p3 = ($(sort.text split)!0.75!(sort.text split 东) +(0ex,0)$)
                (\x1,\y1)--(\x1,\y2)--(\x3,\y2)--(\x3,\y3);

\draw[bp] 让
            \p1 = ($(qsort3.two 东)!0.1!(qsort3.two) $),
         \p2 = ($(main.text)+(0,2ex) $),
           \p3 = ($(sort.text split)!0.75!(sort.text split 东) +(-1ex,0)$)
                (\x1,\y1)--(\x1,\y2)--(\x3,\y2)--(\x3,\y3);

\draw[bp] 让
            \p1 = ($(swap.two 东)!0.1!(swap.two) $),
            \p2 = ($(main.text)+(0,3ex) $),
           \p3 = ($(sort.text split)!0.75!(sort.text split 东) +(-2ex,0)$)
                (\x1,\y1)->(\x1,\y2)->(\x3,\y2)->(\x3,\y3);



\draw[bp] 让
            \p1 = ($(pivot.two 东)!0.1!(pivot.two) $),
         \p2 = ($(main.text)+(0,-2.5ex) $),
           \p3 = ($(qsort3.text 拆分)!0.75!(qsort3.text 拆分东) +(-1ex,0)$)
                (\x1,\y1)--(\x1,\y2)--(\x3,\y2)--(\x3,\y3);

\绘制[bp]
                ($(sort.two 东)!0.5!(sort.two) $) |- (a.西南);
\结束{范围}

\node[fill=gray!10,label=above left:{\scriptsize Legend},font=\scriptsize] 位于 ($(swap)+(0,-20ex)$) {%
  \开始{迷你页面}{37ex}
    \开始{tikzpicture}
        \matrix[行间隔=1mm, 列间隔=2mm,第 1 列/.style={anchor=base west},第 2 列/.style={anchor=base west},font=\scriptsize]{%
          \node[fill=Fuchsia!30,draw] {调用者的保存状态}; & \node[draw,,fill=teal!30] {后退指针};\\
          \node[draw,fill=brown!30] {参数}; & \node[draw,fill=yellow!40] {局部变量};\\
        };
    \结束{tikzpicture}
\end{迷你页面}
};

\开始{范围}[
每个节点/.style={ellipse,draw,font=\scriptsize\ttfamily,inner sep=1pt,fill=blue!20}
]
\节点(根)
在 ($(arrow)+(-24ex,10ex)$)
{$\top$}
[]
子节点 {主节点}}
子节点 {节点 {排序}
    子节点 {节点 {交换}}
    子节点 {节点 {qsort}
        子节点 {pivot}}
    }
};
\结束{范围}
\node[above=2pt of root,font=\small\bfseries]{嵌套结构};
\node[above=22pt of main,font=\small,xshift=-30ex]{\textbf{硬件栈上的框架}};
\node[above=10pt of main,font=\footnotesize,xshift=-30ex]{\textit{(从高内存向低内存增长,从右到左描绘)}};
\结束{tikzpicture}
\结束{文档}

在此处输入图片描述

相关内容