Showing posts with label 链表. Show all posts
Showing posts with label 链表. Show all posts

Friday, October 2, 2015

[Leetcode] Peeking Iterator, Solution

Given an Iterator class interface with methods: next() and hasNext(), design and implement a PeekingIterator that support the peek() operation -- it essentially peek() at the element that will be returned by the next call to next().

Here is an example. Assume that the iterator is initialized to the beginning of the list: [1, 2, 3].
Call next() gets you 1, the first element in the list.
Now you call peek() and it returns 2, the next element. Calling next() after that still return 2.
You call next() the final time and it returns 3, the last element. Calling hasNext() after that should return false.

[Thoughts]
链表的一道设计题。next其实在这里就是获取头元素的值,并移动到下一个元素。peek在这里就是返回当前元素的值。

[Code]
1:  // Below is the interface for Iterator, which is already defined for you.  
2:  // **DO NOT** modify the interface for Iterator.  
3:  class Iterator {  
4:    struct Data;  
5:       Data* data;  
6:  public:  
7:       Iterator(const vector<int>& nums);  
8:       Iterator(const Iterator& iter);  
9:       virtual ~Iterator();  
10:       // Returns the next element in the iteration.  
11:       int next();  
12:       // Returns true if the iteration has more elements.  
13:       bool hasNext() const;  
14:  };  
15:  class PeekingIterator : public Iterator {  
16:  public:  
17:       PeekingIterator(const vector<int>& nums) : Iterator(nums) {  
18:         // Initialize any member here.  
19:         // **DO NOT** save a copy of nums and manipulate it directly.  
20:         // You should only use the Iterator interface methods.  
21:         this->length = nums.size();  
22:         this->nums = &nums;  
23:       }  
24:       // Returns the next element in the iteration without advancing the iterator.  
25:       int peek() {  
26:         if(currentIndex < length) {  
27:           return (*this->nums)[currentIndex];  
28:         }  
29:         return -1;  
30:       }  
31:       // hasNext() and next() should behave the same as in the Iterator interface.  
32:       // Override them if needed.  
33:       int next() {  
34:         if(currentIndex < length) {  
35:           currentIndex ++;  
36:           return (*this->nums)[currentIndex-1];  
37:         }  
38:         return -1;  
39:       }  
40:       bool hasNext() const {  
41:         return currentIndex < length;  
42:       }  
43:  private:  
44:    int currentIndex = 0;  
45:    int length = 0;  
46:    const vector<int>* nums = NULL;  
47:  };  

github:https://github.com/codingtmd/leetcode/blob/master/src/Peeking_Iterator.cpp


Wednesday, December 4, 2013

[LeetCode] Clone Graph, Solution

Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.

OJ's undirected graph serialization:

Nodes are labeled uniquely.

We use # as a separator for each node, and , as a separator for node label and each neighbor of the node.

As an example, consider the serialized graph {0,1,2#1,2#2,2}.

The graph has a total of three nodes, and therefore contains three parts as separated by #.

  1. First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
  2. Second node is labeled as 1. Connect node 1 to node 2.
  3. Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.

Visually, the graph looks like the following:

       1
/ \
/ \
0 --- 2
/ \
\_/

 


[Thoughts]


这题和链表拷贝类似:http://fisherlei.blogspot.com/2013/11/leetcode-copy-list-with-random-pointer.html


所不同的是,在链表拷贝中,没有借助额外空间,通过多次链表遍历来拷贝、链接及拆分。


而这里图的拷贝,也可以通过多次遍历来插入拷贝节点,链接拷贝节点以及将拷贝节点拆分出来。但是同样的问题是,需要对图进行多次遍历。如果想在一次遍历中,完成拷贝的话,那就需要使用额外的内存来使用map存储源节点和拷贝节点之间的对应关系。有了这个关系之后,在遍历图的过程中,就可以同时处理访问节点及访问节点的拷贝节点,一次完成。详细看下面代码。


 


[Code]


1 /**
2 * Definition for undirected graph.
3 * struct UndirectedGraphNode {
4 * int label;
5 * vector<UndirectedGraphNode *> neighbors;
6 * UndirectedGraphNode(int x) : label(x) {};
7 * };
8 */
9 class Solution {
10 public:
11 UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) {
12 if(node == NULL) return NULL;
13 unordered_map<UndirectedGraphNode *, UndirectedGraphNode *> nodeMap;
14 queue<UndirectedGraphNode *> visit;
15 visit.push(node);
16 UndirectedGraphNode * nodeCopy = new UndirectedGraphNode(node->label);
17 nodeMap[node] = nodeCopy;
18 while (visit.size()>0)
19 {
20 UndirectedGraphNode * cur = visit.front();
21 visit.pop();
22 for (int i = 0; i< cur->neighbors.size(); ++i)
23 {
24 UndirectedGraphNode * neighb = cur->neighbors[i];
25 if (nodeMap.find(neighb) == nodeMap.end())
26 {
27 // no copy of neighbor node yet. create one and associate with the copy of cur
28 UndirectedGraphNode* neighbCopy = new UndirectedGraphNode(neighb->label);
29 nodeMap[cur]->neighbors.push_back(neighbCopy);
30 nodeMap[neighb] = neighbCopy;
31 visit.push(neighb);
32 }
33 else
34 {
35 // already a copy there. Associate it with the copy of cur
36 nodeMap[cur]->neighbors.push_back(nodeMap[neighb]);
37 }
38 }
39 }
40
41 return nodeCopy;
42 }
43 };

Tuesday, December 3, 2013

[LeetCode] Sort List, Solution

Sort a linked list in O(n log n) time using constant space complexity.

[Thoughts]
O(nlgn)的排序算法没几个,无非就是quick sort, heap sort和merge sort. 对于链表排序来说,难点之一就是如何O(1)定位节点。如果是数组,那么可以通过下标直接找到节点,但是对于链表,很明显没有下标这个东西可以用,如果需要定位到第k个元素,只能从节点头部顺序的访问K次,但是,如果排序中每一个定位操作都要这样做的话,就太慢了。
所以,问题其实就是,如何能够节省链表节点的定位时间。如果采用merge sort的话,就可以通过递归的特性来避免这个时间损耗。具体看代码

[Code]
关键的部分已用红字标明。通过递归调用的顺序来保证节点的访问顺序。
1:    ListNode *sortList(ListNode *head) {  
2:      if(head == NULL) return NULL;  
3:      int len = 0;  
4:      ListNode* it = head;  
5:      while(it!= NULL)  
6:      {  
7:        len++;  
8:        it = it->next;  
9:      }  
10:      ListNode* newHead = Sort(&head, len);  
11:      return newHead;  
12:    }  
13:    ListNode* Sort(ListNode** head, int length)  
14:    {  
15:         if (length == 1)  
16:         {  
17:              ListNode* temp = *head;            
18:              *head = (*head)->next;  // 确保head每被访问一次,则向后移动一次
19:              temp->next = NULL; // 尾节点需要为NULL,否则Merge函数没法使用 
20:              return temp;  
21:         }  
22:         ListNode* leftHead = Sort(head, length / 2); 
23:         ListNode* rightHead = Sort(head, length - length / 2);  
24:         ListNode* newHead = Merge(leftHead, rightHead);  
25:         return newHead;  
26:    }  
27:    ListNode* Merge(ListNode* first, ListNode* second) // 普通的链表merge函数
28:    {  
29:      ListNode* head = new ListNode(-1);  
30:      ListNode* cur = head;  
31:      while(first!=NULL || second!=NULL)  
32:      {  
33:        int fv = first == NULL? INT_MAX:first->val;  
34:        int sv = second == NULL? INT_MAX:second->val;  
35:        if(fv<=sv)  
36:        {  
37:          cur->next = first;  
38:          first = first->next;  
39:        }  
40:        else  
41:        {  
42:          cur->next = second;  
43:          second = second->next;  
44:        }  
45:        cur = cur->next;  
46:      }  
47:      cur = head->next;  
48:      delete head;  
49:      return cur;  
50:    }  


Update 08/23/2014
True. Recursion is not constant space. I didn't read the problem description carefully. Here, add an implementation via iteration.

Same idea as merge sort.  One example as below:

For each round, the iteration is O(n). And for merge sort, we totally need run the iteration for lg(n) round(the height of recursion tree). So, the total time complexity is  O(nlgn). Maybe someone can share a brief implementation. My current code is a bit fat.

1:  ListNode *sortList(ListNode *head) {  
2:       // Get length first  
3:       ListNode* p = head;  
4:       int len = 0;  
5:       while (p != NULL)  
6:       {  
7:            p = p->next;  
8:            len++;  
9:       }  
10:       ListNode* fakehead = new ListNode(-1);  
11:       fakehead->next = head;       
12:       for (int interval = 1; interval <= len; interval = interval * 2)  
13:       {  
14:            ListNode* pre = fakehead;  
15:            ListNode* slow = fakehead->next, *fast = fakehead->next;  
16:            while (fast != NULL || slow != NULL)  
17:            {  
18:                 int i = 0;  
19:                 while (i< interval && fast != NULL)  
20:                 {  
21:                      fast = fast->next; //move fast pointer ahead 'interval' steps  
22:                      i++;  
23:                 }  
24:                 //merge two lists, each has 'interval' length  
25:                 int fvisit = 0, svisit = 0;  
26:                 while (fvisit < interval && svisit<interval && fast != NULL && slow != NULL)  
27:                 {  
28:                      if (fast->val < slow->val)  
29:                      {  
30:                           pre->next = fast;  
31:                           pre = fast;  
32:                           fast = fast->next;  
33:                           fvisit++;  
34:                      }  
35:                      else  
36:                      {  
37:                           pre->next = slow;  
38:                           pre = slow;  
39:                           slow = slow->next;  
40:                           svisit++;  
41:                      }  
42:                 }  
43:                 while (fvisit < interval && fast != NULL)  
44:                 {  
45:                      pre->next = fast;  
46:                      pre = fast;  
47:                      fast = fast->next;  
48:                      fvisit++;  
49:                 }  
50:                 while (svisit < interval && slow != NULL)  
51:                 {  
52:                      pre->next = slow;  
53:                      pre = slow;  
54:                      slow = slow->next;  
55:                      svisit++;  
56:                 }  
57:                 pre->next = fast;  
58:                 slow = fast;  
59:            }  
60:       }  
61:       ListNode* newhead = fakehead->next;  
62:       delete fakehead;  
63:       return newhead;  
64:  }  

























Monday, March 18, 2013

[LeetCode] Remove Duplicates from Sorted List II, Solution


Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
For example,
Given 1->2->3->3->4->4->5, return 1->2->5.
Given 1->1->1->2->3, return 2->3.
» Solve this problem

[Thoughts]
实现题。前面加一个Safeguard,这样可以避免处理头结点的复杂。

[Code]
1:       ListNode *deleteDuplicates(ListNode *head) {  
2:            if(head == NULL) return head;  
3:            ListNode *G = new ListNode(INT_MIN);  
4:            G->next = head;  
5:            ListNode *cur = G, *pre = head;  
6:            while(pre!=NULL)  
7:            {  
8:                 bool isDup = false;  
9:                 while(pre->next!=NULL && pre->val == pre->next->val)  
10:                 {  
11:                      isDup = true;  
12:                      ListNode *temp = pre;  
13:                      pre = pre->next;  
14:                      delete temp;  
15:                 }  
16:                 if(isDup)  
17:                 {  
18:                      ListNode *temp = pre;  
19:                      pre = pre->next;  
20:                      delete temp;  
21:                      continue;  
22:                 }  
23:                 cur->next = pre;  
24:                 cur = cur->next;  
25:                 pre= pre->next;  
26:            }  
27:            cur->next = pre;  
28:            ListNode *temp = G->next;  
29:            delete G;  
30:            return temp;      
31:       }  


Saturday, March 16, 2013

[LeetCode] Merge Two Sorted Lists, Solution

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
» Solve this problem

[Thoughts]
简单的实现,也没什么可说的。

[Code]
1:    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {  
2:      if(l1 == NULL) return l2;  
3:      if(l2 == NULL) return l1;  
4:      ListNode *head = new ListNode(-1);  
5:      ListNode *p = head;  
6:      while(l1 != NULL && l2!=NULL)  
7:      {  
8:          if(l1->val < l2->val)  
9:          {  
10:             p->next = l1;  
11:             l1= l1->next;  
12:          }  
13:          else  
14:          {  
15:             p->next = l2;  
16:             l2 = l2->next;  
17:          }  
18:          p = p->next;  
19:      }  
20:      if(l1 != NULL)  
21:          p->next = l1;  
22:      if(l2 != NULL)  
23:          p->next = l2;  
24:      p = head->next;  
25:      delete head;  
26:      return p;      
27:    }  


Update 04/13/13 refactor code for succinct
1:       ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {  
2:            ListNode* head = new ListNode(-1);  
3:            ListNode* p = head;  
4:            while(l1!=NULL || l2!= NULL)  
5:            {  
6:                 int val1 = l1==NULL?INT_MAX:l1->val;  
7:                 int val2 = l2==NULL? INT_MAX:l2->val;  
8:                 if(val1<=val2)  
9:                 {  
10:                      p->next = l1;          
11:                      l1=l1->next;  
12:                 }  
13:                 else  
14:                 {  
15:                      p->next = l2;  
16:                      l2 = l2->next;  
17:                 }  
18:                 p= p->next;  
19:            }  
20:            p = head->next;  
21:            delete head;  
22:            return p;  
23:       }  

Monday, January 7, 2013

[LeetCode] Swap Nodes in Pairs 解题报告


Given a linked list, swap every two adjacent nodes and return its head.
For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.
Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.
» Solve this problem

[解题思路]
双指针互换,要考虑一些边界条件,比如链表为空,链表长度为1,链表长度为2.
加一个safeGuard可以避开链表长度为2的检测。

[Code]
1:  ListNode *swapPairs(ListNode *head) {   
2:       if(head == NULL) return NULL;   
3:       if(head->next == NULL) return head;   
4:       ListNode* safeG = new ListNode(-1);   
5:       safeG->next= head; // head will be changed in next switch  
6:       ListNode *pre = head->next;   
7:       ListNode *cur = head;   
8:       ListNode *post = safeG;   
9:       while(pre!=NULL)   
10:       {   
11:            ListNode* temp = pre->next;   
12:            pre->next = cur;   
13:            cur->next = temp;   
14:            post->next = pre;   
15:            post= cur;   
16:            if(post->next == NULL) break;   
17:            cur = post->next;   
18:            pre = cur->next;           
19:       }   
20:       head = safeG->next;   
21:       delete safeG;   
22:       return head;   
23:  }   

Haoran给了一个递归解法,更简洁
1:    ListNode *swapPairs(ListNode *head) {  
2:      if (head == NULL || head->next == NULL) {  
3:        return head;  
4:      }  
5:      ListNode* nextPair = head->next->next;  
6:      ListNode* newHead = head->next;  
7:      head->next->next = head;  
8:      head->next = swapPairs(nextPair);  
9:      return newHead;  
10:    }  


Tuesday, January 1, 2013

[LeetCode] Rotate List 解题报告


Given a list, rotate the list to the right by k places, where k is non-negative.
For example:
Given 1->2->3->4->5->NULL and k = 2,
return 4->5->1->2->3->NULL.
» Solve this problem

[解题思路]
首先从head开始跑,直到最后一个节点,这时可以得出链表长度len。然后将尾指针指向头指针,将整个圈连起来,接着往前跑len – k%len,从这里断开,就是要求的结果了。

[Code]
1:    ListNode *rotateRight(ListNode *head, int k) {  
2:      // Start typing your C/C++ solution below  
3:      // DO NOT write int main() function  
4:      if(head == NULL || k ==0) return head;  
5:      int len =1;  
6:      ListNode* p = head,*pre;  
7:      while(p->next!=NULL)  
8:      {  
9:        p = p->next;  
10:        len++;      
11:      }  
12:      k = len-k%len;  
13:      p->next = head;  
14:      int step =0;  
15:      while(step< k)  
16:      {  
17:        p = p->next;  
18:        step++;  
19:      }  
20:      head = p->next;  
21:      p->next = NULL;  
22:      return head;  
23:    }  


[Note]
注意K大于len的可能。

Monday, December 31, 2012

[LeetCode] Reverse Nodes in k-Group 解题报告


Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
You may not alter the values in the nodes, only nodes itself may be changed.
Only constant memory is allowed.
For example,
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
» Solve this problem

[解题思路]
同上一题,每K个元素,翻转一次。最后一次如果不到K,再翻转回来即可。代码中链表翻转的code可以拆分成单独函数,这里懒得再refactor了。

[Code]
1:      ListNode *reverseKGroup(ListNode *head, int k) {  
2:      // Start typing your C/C++ solution below  
3:      // DO NOT write int main() function  
4:      ListNode* safeG = new ListNode(-1);  
5:         safeG->next = head;            
6:            if(head == NULL || k==1) return head;  
7:            ListNode* pre = safeG, *cur = head, *post = head->next;  
8:            while(cur!=NULL)  
9:            {  
10:                 post = cur->next;  
11:                 int i =0;  
12:                 while(i<k-1 && post!=NULL)  
13:                 {  
14:                      ListNode *temp = post->next;  
15:                      post->next = cur;  
16:                      cur = post;  
17:                      post = temp;  
18:                      i++;  
19:                 }  
20:                 if(i!=k-1)                 
21:                 {  
22:                      int k =0;  
23:                      ListNode * temp = post;  
24:                      post = cur;  
25:                      cur = temp;  
26:                      while(k<i)  
27:                      {  
28:                           temp = post->next;  
29:                           post->next = cur;  
30:                           cur = post;  
31:                           post = temp;  
32:                           k++;  
33:                      }  
34:                      break;  
35:                 }  
36:                 ListNode* temp = pre->next;  
37:                 pre->next = cur;  
38:                 temp->next = post;  
39:                 pre = temp;  
40:                 cur = pre->next;  
41:            }  
42:            head = safeG->next;  
43:            delete safeG;  
44:            return head;  
45:    }  

[LeetCode] Reverse Linked List II 解题报告

Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given 1->2->3->4->5->NULL, m = 2 and n = 4,
return 1->4->3->2->5->NULL.
Note:
Given m, n satisfy the following condition:
1 ≤ m  n ≤ length of list.
» Solve this problem

[解题思路]
分三步走
1. 找到m节点的前一个指针pre(加个safe guard可避免头指针的问题)
2. 从m节点开始往后reverse N个节点(双指针,cur,post)
3. 合并pre链表,cur链表及post链表。

这题难就难在繁琐上,要考虑各种边界条件,比如
{1,2,3}, 3,3
{1,2,3}, 1,1
{1,2,3}, 1,3
所以,code中需要添加一些边界检查条件。这题15分钟以内bug free我是做不到。

1:       ListNode *reverseBetween(ListNode *head, int m, int n) {   
2:            // Start typing your C/C++ solution below   
3:            // DO NOT write int main() function   
4:            int step = n-m;   
5:            ListNode* safeG = new ListNode(-1); //intro a safe guard to avoid handle head case  
6:            safeG->next = head;   
7:            head = safeG;   
8:            ListNode* pre = head;   
9:            while(m>1)   
10:            {   
11:                 pre=pre->next;   
12:                 m--;   
13:            }   
14:            ListNode* cur = pre->next, *post = cur->next;   
15:            if(step>=1)   
16:            {   
17:                 while(step>0 && post!=NULL)   
18:                 {   
19:                      ListNode* temp = post->next;   
20:                      post->next = cur;   
21:                      cur = post;   
22:                      post = temp;   
23:                      step--;   
24:                 }   
25:                 ListNode* temp = pre->next;   
26:                 pre->next = cur;   
27:                 temp->next = post;   
28:            }   
29:            safeG = head;   
30:            head = head->next;   
31:            delete safeG;   
32:            return head;     
33:       }   

Update: 3/19/2013. SafeG在这里没有意义。

Update 3/6/2014. 又看了一遍,SafeG还是有必要的,避免对于head的处理。

Friday, December 28, 2012

[LeetCode] Partition List 解题报告


Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
For example,
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.
» Solve this problem

[解题思路]
从左往右扫描,找到第一个大于X的指针,然后再该指针左边,不断插入小于X的元素。这里为了避免处理head是否为空的检测,在头指针位置先插入一个干扰元素,以保证head永不为空,然后在最后返回的时候删除掉。


[Code]
1:    ListNode *partition(ListNode *head, int x) {  
2:      // Start typing your C/C++ solution below  
3:      // DO NOT write int main() function      
4:      ListNode* p = new ListNode(x-1);  
5:      p->next = head;  
6:      head = p;  
7:      ListNode* pre;  
8:      while(p!=NULL && p->val < x)  
9:      {  
10:        pre = p;  
11:        p = p->next;  
12:      }  
13:      if(p!=NULL)  
14:      {      
15:        ListNode* cur = pre;  
16:        while(p!=NULL)      
17:        {  
18:          if(p->val <x)  
19:          {  
20:            ListNode* temp = cur->next;  
21:            pre->next = p->next;  
22:            cur->next = p;  
23:            cur = p;  
24:            p->next = temp;  
25:            p = pre;  
26:          }  
27:          pre=p;  
28:          p= p->next;        
29:        }  
30:      }  
31:      ListNode* temp = head;  
32:      head = head->next;  
33:      delete temp;  
34:      return head;      
35:    }  


[Note]
1. Line 15
cur为插入位置的指针,在双指针遍历过程中是不变的。


Wednesday, December 26, 2012

[LeetCode] Merge k Sorted Lists 解题报告


Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
» Solve this problem

[解题思路]
merge sort。外面套一层循环即可。注意指针操作即可。


[Code]
1:    ListNode *mergeKLists(vector<ListNode *> &lists) {  
2:      // Start typing your C/C++ solution below  
3:      // DO NOT write int main() function  
4:      ListNode * head = new ListNode(INT_MIN);  
5:      for(int i = 0; i < lists.size(); i++)  
6:      {  
7:        ListNode* p1 = head->next;  
8:        ListNode * p2 = lists[i];  
9:        ListNode* pre = head;  
10:        while(p1!= NULL && p2!= NULL)  
11:        {  
12:          if(p1->val >= p2->val)  
13:          {  
14:            pre->next = p2;   
15:            p2 = p2->next; pre = pre->next;  
16:            pre->next = p1;  
17:            continue;  
18:          }  
19:          pre = p1;  
20:          p1 = p1->next;;  
21:        }  
22:        if(p2 != NULL)  
23:        {  
24:          pre->next = p2;  
25:        }  
26:      }  
27:      ListNode* del = head;  
28:      head = head->next;  
29:      delete del;  
30:      return head;      
31:    }  

Update, 3/9/2013
Refactor the code
1:    ListNode *mergeKLists(vector<ListNode *> &lists) {  
2:      if(lists.size() == 0) return NULL;  
3:      ListNode *p = lists[0];  
4:      for(int i =1; i< lists.size(); i++)  
5:      {  
6:        p = merge2Lists(p, lists[i]);  
7:      }  
8:      return p;  
9:    }  
10:    ListNode * merge2Lists(ListNode *head1, ListNode *head2)  
11:    {  
12:      ListNode *head = new ListNode(INT_MIN);  
13:      ListNode *p = head;  
14:      while(head1!=NULL && head2!=NULL)  
15:      {  
16:        if(head1->val < head2->val)  
17:        {  
18:          p->next = head1;  
19:          head1 = head1->next;  
20:        }  
21:        else  
22:        {  
23:          p->next = head2;  
24:          head2 = head2->next;  
25:        }  
26:        p = p->next;  
27:      }  
28:      if(head1 !=NULL)  
29:      {  
30:        p->next = head1;  
31:      }  
32:      if(head2 != NULL)  
33:      {  
34:        p->next = head2;  
35:      }  
36:      p = head;  
37:      head = head->next;  
38:      delete p;  
39:      return head;  
40:    }