如图1所示,要删除带头结点的非空单循环链表中的第一个元素,就要先用临时指针q指向待删结点,q=h->next;然后将q从链表中断开,h->next=q->next(这一步也可写成h->next=h->next->next);此时要考虑一种特殊情况,若待删结点是链表的尾结点,即循环单链表中只有一个元素(p和q指向同一个结点),如图2所示,则在删除后要将尾指针指向头结点,即if(p==q)p=h;最后释放q结点即可。
栈和队列的逻辑结构都是相同的,都属于线性结构,只是它们对数据的运算不同。
对于双向循环链表,不管是表头指针还是表尾指针,都可以很方便地找到表头结点,方便在表头做插入或删除操作。而单循环链表通过尾指针可以很方便地找到头结点,但通过头指针找尾结点则需要遍历一次链表。对于C,插入和删除结点后,找尾结点需要花费O(n)的时间。
链表采用不带头结点的单链表表示时,进栈操作在首部插入一个结点x(即x->next=top),插入完后需将top指向该插入的结点x。
当第i个元素第一个出栈时,则i之前的元素可以依次排在i之后出栈,但剩余的元素可以在此时进栈并且也会排在i之前的元素出栈,所以第j个出栈的元素是不确定的。
逐个判断每个选项可能的入栈出栈顺序。
3之后的4,5…,n都是 P 3 P_3 P3可取的数(持续进栈直到该数入栈后立即出栈)。接下来分析1和2: P 1 P_1 P1可以是3之前入栈的数(可能是1或2),也可以是4,当 P 1 P_1 P1=1时, P 3 P_3 P3可取2;当 P 1 P_1 P1=2时, P 3 P_3 P3可取1;当 P 1 P_1 P1=4时, P 3 P_3 P3可取除1,3,4之外的所有数;故 P 3 P_3 P3可能取值的个数为n-1。
Ⅰ. 采用非递归方式重写递归程序时必须使用栈
Ⅱ. 函数调用时,系统要用栈保存必要的信息
Ⅲ. 只要确定了入栈次序,即可确定出栈次序
Ⅳ. 栈是一种受限的线性表,允许在其两端进行操作
Ⅰ的反例:计算斐波拉契数列迭代实现只需要一个循环即可实现。
Ⅲ的反例:入栈序列为1,2,进行Push,Push,Pop,Pop操作,出栈次序为2,1;进行Push,Pop,Push,Pop操作,出栈次序为1,2.
Ⅳ的反例:栈是一种受限的线性表,只允许在一端进行操作。
Ⅰ. 最后插入队列中的元素总是最后被删除
Ⅱ. 当同时进行插入、删除操作时,总是插入操作优先
Ⅲ. 每当有删除操作时,总要先做一次插入操作
Ⅳ. 每次从队列中删除的总是最早插入的元素
队列“先进先出”的特性表现在:先进队列的元素先出队列,后进队列的元素后出队列,进队列对应的是插入操作,出队列对应的是删除操作。Ⅰ和Ⅳ均正确。