两个链表的第一个公共结点
摘要:题目:输入两个链表,找出它们的第一个公共结点。链表结点定义如下:struct ListNode{ int m_nKey; ListNode *m_pNext;};解决办法:首先遍历两个链表得到它们的长度,就能知道哪个链表比较长,以及长的链表比短的链表多几个结点。在第二次遍历的时候,在较长的链表上先走若干步,接着再同时在两个链表上遍历,找到的第一个相同的结点就是它们的第一个公共结点。ListNode *FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2){ //得到两个链表的长度 unsigned int nLength1 =...
阅读全文
posted @
2014-03-10 16:59
猿人谷
阅读(526)
推荐(0) 编辑
合并两个排序的链表
摘要:题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如下图中的链表1和链表2,则合并之后的升序链表如链表3所示。链表结点定义如下:struct ListNode{ int m_nValue; ListNode *m_pNext;}; 注:链表1和链表2是两个递增排序的链表,合并这两个链表得到升序链表为链表3.首先分析合并两个链表的过程。我们的分析从合并两个链表的头结点开始。链表1的头结点的值小于链表2的头结点的值,因此链表1的头结点将是合并后链表的头结点。如下图所示。链表1的头结点的值小于链表2的头结点的值,因此链表1的头结点是合并后链表的头结点。在剩余的结点
阅读全文
posted @
2013-11-03 18:31
猿人谷
阅读(14091)
推荐(1) 编辑
从尾到头打印链表
摘要:题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。链表结点定义如下:struct ListNode{ int m_nKey; ListNode *m_pNext;};解决这个问题肯定要遍历链表。遍历的顺序是从头到尾的顺序,可输出的顺序却是从尾到头。也就是说第一个遍历到的结点最后一个输出,而最后一个遍历到得结点第一个输出。这就是典型的“后进先出”,可以用栈实现这种顺序。每经过一个结点的时候,把该结点放到一个栈中。当遍历完整个链表后,再从栈顶开始逐个输出结点的值,此时输出的结点的顺序已经反转过来了。实现代码如下:void PrintListReverse(ListNode...
阅读全文
posted @
2013-11-02 21:28
猿人谷
阅读(3226)
推荐(0) 编辑
查找链表中倒数第k个结点
摘要:题目:输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。链表结点定义如下:struct ListNode{ int m_nKey; ListNode* m_pNext;};分析:为了得到倒数第k个结点,很自然的想法是先走到链表的尾端,再从尾端回溯k步。可是输入的是单向链表,只有从前往后的指针而没有从后往前的指针。因此我们需要打开我们的思路。既然不能从尾结点开始遍历这个链表,我们还是把思路回到头结点上来。假设整个链表有n个结点,那么倒数第k个结点是从头结点开始的第n-k-1个结点(从0开始计数)。如果我们能够得到链表中结点的个数n,...
阅读全文
posted @
2013-11-01 22:07
猿人谷
阅读(789)
推荐(0) 编辑
判断单链表是否存在环
摘要:周末参加完美世界校园招聘中就有一道判断单链表是否有环的编程题。写一个C/C++函数,来判断一个单链表是否具有环,如果存在环,则给出环的入口点。有一个单链表,其中可能有一个环,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一环。现在需要解决的问题有以下两个:如何判断一个链表是不是这类链表?如果链表为存在环,如果找到环的入口点?判断链表是否存在环,办法为:设置两个指针(fast, slow),初始值都指向头,slow每次前进一步,fast每次前进二步,如果链表存在环,则fast必定先进入环,而slow后进入环,两个指针必定相遇。(当然,fast先行头到尾部为NULL,则
阅读全文
posted @
2013-10-21 14:11
猿人谷
阅读(691)
推荐(0) 编辑
删除链表中的重复元素
摘要:昨晚在参加兰亭集势的笔试时,看到了这样一个题目。大致意思就是给出一个单链表,链表中有重复的元素,需要删除重复的元素。如:1→2→3→5→4→3→7,删除重复元素后变成1→2→3→5→4→7。思路其实还蛮简单:建立三个工作指针p,q,r,然后p遍历全表。p每到一个结点,q就从这个结点往后遍历,并与p的数值比较,相同的话就free掉那个结点。LinkList RemoveDupNode(LinkList L) //删除重复结点的算法{ LinkList p , q , r; p = L -> next; while(p) //p用于遍历链表 { q = p; while(q->next
阅读全文
posted @
2013-10-18 09:28
猿人谷
阅读(1378)
推荐(0) 编辑
双向链表
摘要:双向链表 在线性链式存储结构的结点中只有一个指示直接后继的指针域,由此,从某个结点出发只能顺指针往后寻查其他结点。若要寻查结点的直接前趋,则需从表头指针出 发。换句话说,在单链表中,NextElem的执行时间是o(1),而PriorElem的执行时间为O(n)。为克服单链表这种单向性的缺点,可利用双 向链表。 双向链表是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。所以在双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前驱。//线性表的双向链表存储结构typedef struct DulNode{ ElemType data; struct DulNod...
阅读全文
posted @
2013-10-14 09:48
猿人谷
阅读(575)
推荐(0) 编辑
在O(1)时间删除链表结点
摘要:题目:给定链表的头指针和一个结点指针,在O(1)时间删除该结点。函数的声明如下:void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted);分析:这是一道广为流传的Google面试题,能有效考察我们的编程基本功,还能考察我们的反应速度,更重要的是,还能考察我们对时间复杂度的理解。注意函数的第一个参数pListHead是一个指向指针的指针。例如,当我们往一个空链表中插入一个结点时,新插入的结点就是链表的头指针。由于此时会改动头指针,因此必须把pHead参数设为指向指针的指针,否则出了这个函数pHead仍然是一个空指针。在链表中删除一
阅读全文
posted @
2013-09-09 11:48
猿人谷
阅读(785)
推荐(0) 编辑
单链表反转的分析及实现
摘要:我先画一个单链表,这个单链表有4个元素。我的思路就是,每次把第二个元素提到最前面来。比如下面是第一次交换,我们先让头结点的next域指向结点a2,再让结点a1的next域指向结点a3,最后将结点a2的next域指向结点a1,就完成了第一次交换。第一次交换然后进行相同的交换将结点a3移动到结点a2的前面,然后再将结点a4移动到结点a3的前面就完成了反转。第二次交换第三次交换思路有了,那就可以写代码了。这里我们需要额外的两个工作指针来辅助交换。这个下面的步骤慢慢理解下,结合图片。注意结点之间的关系要先断再连。步骤:定义当前结点 current,初始值为首元结点,current = L->ne
阅读全文
posted @
2013-09-06 09:47
猿人谷
阅读(1578)
推荐(0) 编辑