链表通常的实现方式是,定义结构体和指针,在结点与结点之间随心所欲插入新的结点。
而在刘汝佳的《算法竞赛入门经典》中,提出了另一种"双数组"(s数组和next数组)实现方式。代码如下。(结合输出部分代码来理解)
for (int i = 1; i <= n; i++)
char ch = s[i];
if (ch == '[')cur = 0;//将光标移动到链表首部
else if (ch == ']')cur = last;//光标移动到链表尾部
else{//在光标所在位置插入节点
next[i] = next[cur];
//如果光标后的位置已经被赋值,则这个值被“插队”了。
//将这个值赋给next[i]。因为在输出时,这里的next[i]
//将是下一个被输出的字符的位置。
//比如cur=10,i=8,则next[8]=next[10];next[10]=8;
//在输出时,光标先被导向到10,输出s[next[10]],
//接着被导向到next[10],亦即8,输出s[next[8]]
next[cur] = i;//将光标后的位置赋值为i(输出时输出s[i])
if (cur == last)last = i;//如果光标被移动到了最后,将last值更新
cur = i;
//不管此前光标在首部(cur==0)还是尾部(cur==last)还是中间,i都是光标的下一个位置。
//因为next[cur]=i。
}
}```
输出代码如下。
for (int i = next[0]; i != 0; i = next[i])
printf("%c", s[i]);
printf("\n");
PS:
我爱指针,指针使我快乐。