链表专题[三种逆置方式和微软笔试题]

来源:互联网 发布:网络系统集成设计方案 编辑:程序博客网 时间:2024/06/11 13:34

说起链表,是大家最熟悉的数据结构了,也是大学上课时比较先讲到的。那么是否真正掌握了呢。

单链表逆置是最常考的题目,但完全写正确好像三种方式也没那么容易吧。

第一种:非递归,思路就是从头结点开始,记录头结点的下一个结点,同时将头结点的指针指向之前的结点(设为NULL),然后将头结点的值赋给之前的结点,然后继续下一个结点的逆置,直到为空。

第二种:  递归方式。思路就是一直递归,直到最后一个结点的之前一个结点结束,这时然后最后一个结点的指针指向之前一个结点,同时将之前一个结点的指针置为空(这样顺便修改了原来链表头结点的指针为空)。难点在于怎么返回逆置之后的头结点。

第三种: 栈。既然可以递归了那么考虑用栈来解决。

好了,貌似单链表比较复杂的操作我们掌握了。问题解决了,那么是否能灵活运用呢?看下面一道题目(微软2014年校招编程题)

Given a singly linked list L: (L0 , L1 , L2...Ln-1 , Ln). Write a program to reorder it so that it becomes(L0 , Ln , L1 , Ln-1 , L2 , Ln-2...).
struct Node  
{  
    int val_;  
    Node* next;  
};  
Notes:
1)Space Complexity should be O(1) 
2)Only the ".next" field of a node is modifiable.

注意:空间复杂度为O(1)意味着不能有大于O(1)的辅助空间。

注意是从尾倒着插,可能会用到逆置,那解题思路是神马呢?

根据长度将链表分为两半,对后面的链表进行逆置,然后将两个链表合并(擦,神一样的思路啊,这就是链表逆置和合并的灵活应用了,当做为笔试题是否能想到呢。。。),好了,废话不多说了,代码在下面,看注释吧。

#include<iostream>#include<string>#include<stack>using namespace std;struct ListNode{int value;ListNode* next;};//增加元素void AddToList(ListNode** pHead,int value){ListNode* pTemp = *pHead; pTemp = (ListNode *)malloc(sizeof(ListNode));pTemp->value = value;pTemp->next = NULL;if(*pHead == NULL)*pHead = pTemp;else{ListNode* pNTemp = *pHead;while(pNTemp->next != NULL)pNTemp = pNTemp->next;pNTemp->next = pTemp;}}//求长度int ListLen(ListNode* pHead){int n =0;while(pHead != NULL){pHead = pHead->next;n++;}return n;}//非递归逆置ListNode* Reverse(ListNode* pHead){ListNode* pTemp = pHead;ListNode *pre,*plast = NULL;while(pTemp!= NULL){pre = pTemp->next;    pTemp->next = plast;plast = pTemp;pTemp = pre;}return plast;}//递归逆置,关键是如何在递归中找到起点(原来的最后一点)ListNode* Reverse_recurve(ListNode* pHead){if(pHead == NULL || pHead->next == NULL )return pHead;ListNode *pHead1 = Reverse_recurve(pHead->next);pHead->next->next = pHead;pHead->next = NULL;return pHead1;}//用栈逆置ListNode* Reverse_stack(ListNode* pHead){stack<ListNode*> lstack;while(pHead != NULL){lstack.push(pHead);pHead = pHead->next;}pHead = lstack.top();ListNode* plast = pHead;ListNode* pre;lstack.pop();while(!lstack.empty()){pre = lstack.top();lstack.pop();plast->next = pre;plast = pre;}plast->next = NULL;return pHead;}//合并链表void merge(ListNode* pHead,int n){ListNode* pTemp1 = pHead,*pTemp2,*pTemp;if(n%2 == 0)n = n/2;elsen = n/2+1;while(n-1){pTemp1 = pTemp1->next;n--;}pTemp = pTemp1->next;pTemp1->next = NULL;//逆置pTemp = Reverse(pTemp);//合并while(pTemp != NULL){pTemp1 = pHead->next;pTemp2 = pTemp->next;pTemp->next = pHead->next;pHead->next = pTemp;pHead  = pTemp1;pTemp  = pTemp2;}return;}int main(){ListNode* pHead = NULL;AddToList(&pHead,1);AddToList(&pHead,2);AddToList(&pHead,3);AddToList(&pHead,4);AddToList(&pHead,5);//AddToList(&pHead,6);ListNode* pHead1 = pHead;pHead1 = Reverse(pHead1);pHead = pHead1;while(pHead1->next != NULL){printf("%d->",pHead1->value);pHead1 = pHead1->next;}printf("%d\n",pHead1->value);//递归pHead1 = pHead;pHead1 = Reverse_recurve(pHead1);pHead = pHead1;while(pHead1->next != NULL){printf("%d->",pHead1->value);pHead1 = pHead1->next;}printf("%d\n",pHead1->value);//栈pHead1 = pHead;pHead1 = Reverse_stack(pHead1);pHead = pHead1;while(pHead1->next != NULL){printf("%d->",pHead1->value);pHead1 = pHead1->next;}printf("%d\n",pHead1->value);//微软题目pHead1 = pHead;int len = ListLen(pHead);merge(pHead,len);while(pHead->next != NULL){printf("%d->",pHead->value);pHead = pHead->next;}printf("%d\n",pHead->value);system("PAUSE");return 0;}
输出结果如下:




0 0
原创粉丝点击