链表:
单链表,实现代码 http://blog.csdn.net/qiming_zhang/article/details/6948173
1、一个单链表,经一次查询,我想得到倒数第K个元素,如何得到?
答:(1)设置一个队列,长度为K,遍历链表入队,满了就队首的出去。最后队首就是了。
(2)两个指向头结点的指针,一个先向后移动k位,然后两个同时向后面移动直到一个节点到达链尾,前面一个指针的位置就是了。
2、是否有环?
答:设置两个指针(fast,slow),初始值都指向头,slow每次前进一步,fast每次前进二步,如果链表存在环,则fast必定先进入环,而slow后进入环,两个指针必定相遇。fast先行头到尾部为NULL,则为无环链表。
3、环入口?
答:当fast按照每次2步,slow每次一步的方式走,发现fast和slow重合,确定了单向链表有环路了接下来,让fast回到链表的头部,重新走,每次步长不是走2了,而是走1,那么当slow和fast再次相遇的时候,就是环路的入口了。
这点可以证明的:
在fast和slow第一次相遇的时候,假定slow走了n步骤,环路的入口是在p步的时候经过的,那么有:
slow走的路径: p+c = n; c为slow和fast相交点距离环路入口的距离
fast走的路径: p+c+k*L = 2*n; L为环路的周长,k是整数。
显然,如果从p+c点开始,slow再走n步骤的话,还可以回到p+c这个点同时fast从头开始走的话,经过n步,也会达到p+c这点显然在这个步骤当中slow和fast只有前p步骤走的路径不同,所以当slow和fast再次重合的时候,必然是在链表的环路入口点上。
slist * FindLoopPort(slist * head) { slist * slow = head, * fast = head; while ( fast && fast -> next ) { slow = slow -> next; fast = fast -> next -> next; if ( slow == fast ) break ; } if (fast == NULL || fast -> next == NULL) return NULL; slow = head; while (slow != fast) { slow = slow -> next; fast = fast -> next; } return slow; }
栈:
顺序栈:实现代码 http://blog.csdn.net/qiming_zhang/article/details/6948161