剑指Offer-26-复杂链表的复制
2015-11-21 11:27
435 查看
题目:
有一个复杂链表,其结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任一结点或者NULL。其结点的C++定义如下:
struct ComplexNode
{
int m_nValue;
ComplexNode* m_pNext;
ComplexNode* m_pSibling;
};
请完成函数ComplexNode* Clone(ComplexNode* pHead),以复制一个复杂链表。
第一种方法:
分成两步:第一步是复制原始链表上的每个链表,并用m_pNext链接起来。第二步,假设原始链表中的某节点N的m_pSibling指向结点S。由于S的位置在链表上有可能在N的前面也可能在N的后面,所以要定位N的位置我们需要从原始链表的头结点开始找。假设从原始链表的头结点开始经过s步找到结点S。那么在复制链表上结点N的m_pSibling的S’,离复制链表的头结点的距离也是s。用这种办法我们就能为复制链表上的每个结点设置m_pSibling了。
对一个含有n个结点的链表,由于定位每个结点的m_pSibling,都需要从链表头结点开始经过O(n)步才能找到,因此这种方法的总时间复杂度是O(n2)。
下一篇将使用o(n)复杂度的算法,实现该功能。
有一个复杂链表,其结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任一结点或者NULL。其结点的C++定义如下:
struct ComplexNode
{
int m_nValue;
ComplexNode* m_pNext;
ComplexNode* m_pSibling;
};
请完成函数ComplexNode* Clone(ComplexNode* pHead),以复制一个复杂链表。
第一种方法:
分成两步:第一步是复制原始链表上的每个链表,并用m_pNext链接起来。第二步,假设原始链表中的某节点N的m_pSibling指向结点S。由于S的位置在链表上有可能在N的前面也可能在N的后面,所以要定位N的位置我们需要从原始链表的头结点开始找。假设从原始链表的头结点开始经过s步找到结点S。那么在复制链表上结点N的m_pSibling的S’,离复制链表的头结点的距离也是s。用这种办法我们就能为复制链表上的每个结点设置m_pSibling了。
对一个含有n个结点的链表,由于定位每个结点的m_pSibling,都需要从链表头结点开始经过O(n)步才能找到,因此这种方法的总时间复杂度是O(n2)。
下一篇将使用o(n)复杂度的算法,实现该功能。
#include <iostream> using namespace std; struct ComplexListNode { int m_nValue; ComplexListNode* m_pNext; ComplexListNode* m_pSibling; }; /** * 使用一般方式进行复制,时间复杂度o(n*n) */ ComplexListNode* clone(ComplexListNode *pHead) { if(pHead == NULL) return NULL; ComplexListNode *pNewHead = new ComplexListNode(); pNewHead->m_nValue = pHead->m_nValue; pNewHead->m_pNext = NULL; pNewHead->m_pSibling = NULL; ComplexListNode *p = pHead->m_pNext; ComplexListNode *preNewP = pNewHead; //第一步:复制原始链表的每一个结点,按照p->m_pNext连接起来 while(p) { ComplexListNode *newP = new ComplexListNode(); newP->m_nValue = p->m_nValue; newP->m_pNext = NULL; newP->m_pSibling = NULL; preNewP->m_pNext = newP; preNewP = newP; p=p->m_pNext; } p = pHead; ComplexListNode *newp = pNewHead; //第二步:设置每个结点的m_pSibling指针 //如果原始链表的头结点开始沿着m_pNext经过s步找到结点S,那么复制链表上结点N的N'的m_pSibling(S') //离复制链表的头结点的距离也是沿着m_pNext指针s步。 while(p) { if(p->m_pSibling != NULL) { ComplexListNode *sibling = pHead; ComplexListNode *newSibling = pNewHead; while(sibling != p->m_pSibling) { sibling = sibling->m_pNext; newSibling = newSibling->m_pNext; } newp->m_pSibling = newSibling; } p = p->m_pNext; newp = newp->m_pNext; } return pNewHead; } ComplexListNode* CreateNode(int nValue) { ComplexListNode* pNode = new ComplexListNode(); pNode->m_nValue = nValue; pNode->m_pNext = NULL; pNode->m_pSibling = NULL; return pNode; } void BuildNodes(ComplexListNode* pNode, ComplexListNode* pNext, ComplexListNode* pSibling) { if(pNode != NULL) { pNode->m_pNext = pNext; pNode->m_pSibling = pSibling; } } void PrintList(ComplexListNode* pHead) { ComplexListNode* pNode = pHead; while(pNode != NULL) { cout<<"The value of this node is:"<<pNode->m_nValue<<"."; if(pNode->m_pSibling != NULL) cout<<"The value of its sibling is:"<<pNode->m_pSibling->m_nValue<<"."; else cout<<"This node does not have a sibling."; cout<<endl; pNode = pNode->m_pNext; } } // ====================测试代码==================== void Test(char* testName, ComplexListNode* pHead) { if(testName != NULL) cout<<testName; cout<<"The original list is:"<<endl; PrintList(pHead); ComplexListNode* pClonedHead = clone(pHead); cout<<"The cloned list is:"<<endl; PrintList(pClonedHead); } // ----------------- // \|/ | // 1-------2-------3-------4-------5 // | | /|\ /|\ // --------+-------- | // ------------------------- void Test1() { ComplexListNode* pNode1 = CreateNode(1); ComplexListNode* pNode2 = CreateNode(2); ComplexListNode* pNode3 = CreateNode(3); ComplexListNode* pNode4 = CreateNode(4); ComplexListNode* pNode5 = CreateNode(5); BuildNodes(pNode1, pNode2, pNode3); BuildNodes(pNode2, pNode3, pNode5); BuildNodes(pNode3, pNode4, NULL); BuildNodes(pNode4, pNode5, pNode2); Test("Test1", pNode1); } // m_pSibling指向结点自身 // ----------------- // \|/ | // 1-------2-------3-------4-------5 // | | /|\ /|\ // | | -- | // |------------------------| void Test2() { ComplexListNode* pNode1 = CreateNode(1); ComplexListNode* pNode2 = CreateNode(2); ComplexListNode* pNode3 = CreateNode(3); ComplexListNode* pNode4 = CreateNode(4); ComplexListNode* pNode5 = CreateNode(5); BuildNodes(pNode1, pNode2, NULL); BuildNodes(pNode2, pNode3, pNode5); BuildNodes(pNode3, pNode4, pNode3); BuildNodes(pNode4, pNode5, pNode2); Test("Test2", pNode1); } // m_pSibling形成环 // ----------------- // \|/ | // 1-------2-------3-------4-------5 // | /|\ // | | // |---------------| void Test3() { ComplexListNode* pNode1 = CreateNode(1); ComplexListNode* pNode2 = CreateNode(2); ComplexListNode* pNode3 = CreateNode(3); ComplexListNode* pNode4 = CreateNode(4); ComplexListNode* pNode5 = CreateNode(5); BuildNodes(pNode1, pNode2, NULL); BuildNodes(pNode2, pNode3, pNode4); BuildNodes(pNode3, pNode4, NULL); BuildNodes(pNode4, pNode5, pNode2); Test("Test3", pNode1); } // 只有一个结点 void Test4() { ComplexListNode* pNode1 = CreateNode(1); BuildNodes(pNode1, NULL, pNode1); Test("Test4", pNode1); } // 鲁棒性测试 void Test5() { Test("Test5", NULL); } int main() { Test1(); Test2(); Test3(); Test4(); Test5(); return 0; }
相关文章推荐
- 解析html 生成word文档
- 字节符输出流缓冲区 BufferedOutputStreamDemo
- 字节输入流缓冲区 BufferedInputStreamDemo
- 第6章 CXF的前端应用
- jsp 静态引入<%@ include %> 动态引入<jsp:include> 区别
- BufferedReader_WriterDemo
- JS操作JSON总结
- framebuffer下bmp格式图片
- 如何优化JavaScript的构造函数
- [HNOI2008]明明的烦恼 (Prüfer编码+质因数分解计算两个阶乘的商)
- js DOM Element属性和方法整理----转载
- 指针分析/Point-to Analysis/Reference Analysis
- 前端模板语言velocity选择
- 关于bootstrapValidator提交问题的解决
- [Leetcode]Perfect Squares(DP and Math Solution)
- HTML之基本布局设计之三栏式、两栏式设计
- JavaScript实现自动生成网页元素功能(按钮、文本等)
- javascript正则表达式:非捕获分组的一个使用例子
- 聊天室软件设计-nodejs
- js几秒以后倒计时跳转示例