链表的各种基本操作_链表经常进行的运算操作有创建链表、求链表的长度、在链表中查找某个数据元素、在

	tmp->m_pNext = L;
	L = tmp;
	return;
}

if ( pos >= ListLen(L) || pos < 0)
{
	cout << "Error input pos."<< endl;
	return;
}

ListNode *pInsert = L;
while (pos--)
{
	pInsert = pInsert->m_pNext;
}
tmp->m_pNext = pInsert->m_pNext;
pInsert->m_pNext = tmp;

return;

}


5. 删除。



void DeleteListNode(ListNode *&L, int value)
{
if (L == nullptr)
{
cout << “Error input L.”;
return;
}

ListNode *pDelete = L;
if (L->m_value == value)
{
	L = L->m_pNext;
	delete pDelete;
	return;
}

ListNode *pFront = nullptr;
while (pDelete != nullptr && pDelete->m_value != value)
{
	pFront = pDelete;
	pDelete  = pDelete->m_pNext;
}

if (pDelete == nullptr)
{
	cout << "Not found value in L.";
	return;
}
if (pDelete->m_value == value)
{
	pFront->m_pNext = pDelete->m_pNext;
	delete pDelete;
}

return;

}


6. 翻转。



ListNode * ReverseList(ListNode *L)
{
if(L == nullptr || L->m_pNext == nullptr)
return nullptr;

ListNode * pCurrent = nullptr;

while (L != nullptr)
{
	ListNode * tmp = L->m_pNext;
	L->m_pNext = pCurrent;
	pCurrent = L;
	L = tmp;
}

/*DisplayList(L);
DisplayList(pCurrent);*/
return pCurrent;

}


7. 打印。



void DisplayList(ListNode * L)
{
ListNode * list = L;

while (list != nullptr)
{
	cout << list->m_value << " -> ";
	list = list->m_pNext;
}
cout << "null" << endl;

}


8. 链表长度。



int ListLen(ListNode *L)
{
int len = 0;

while (L != nullptr)
{
	L = L->m_pNext;
	++len;
}

return len;

}


9. 找到链表倒数第k个节点。



ListNode *FindKthNode(ListNode *L, int k)
{
if (ListLen(L) < k)
return nullptr;

ListNode *pFront = nullptr, *pBack = nullptr;

pFront = pBack = L;

int ii = 0;
while (ii++ < k-1)
{
	pFront = pFront->m_pNext;
}

while (pFront->m_pNext != nullptr)
{
	pFront = pFront->m_pNext;
	pBack = pBack->m_pNext;
}

return pBack;

}


10. 合并两排序的链表。



ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
if (pHead1 == nullptr)
return pHead2;
if (pHead2 == nullptr)
return pHead1;

  ListNode *pNewHead = nullptr, *pNewTail = nullptr;
  ListNode *pNode1 = pHead1, *pNode2 = pHead2;

  while (pNode1 != nullptr && pNode2 != nullptr)
  {
	ListNode *pTmp = nullptr;

	if (pNode1->val < pNode2->val)
	{
		pTmp = pNode1;
		pNode1 = pNode1->next;
	}
	else
	{
		pTmp = pNode2;
		pNode2 = pNode2->next;
	}

	if (pNewHead == nullptr)
	{
		pNewHead = pNewTail = pTmp;
	}
	else
	{
		pNewTail->next = pTmp;
		pNewTail = pNewTail->next;
	}
  }

  if ( pNode1 == nullptr )  //和归并排序时的判断条件不一样。
  {
	pNewTail->next = pNode2;
  }
  if ( pNode2 == nullptr )
  {
	pNewTail->next  = pNode1;
  }

  return pNewHead;

}


11. 删除链表中重复的节点. 180420



ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead == nullptr)
return nullptr;
if (pHead->next == nullptr)
return pHead;
if (pHead->val == pHead->next->val && pHead->next->next == nullptr)
return nullptr;

ListNode *pNewNode = new ListNode(-1);
pNewNode->next = pHead;

ListNode *pLastNode = pNewNode;
ListNode *pCurNode = pHead;
ListNode *pNextNode = pHead->next;
int flag = 0;

while (pNextNode != nullptr)
{
	while (pNextNode && pCurNode->val == pNextNode->val)
	{
		pNextNode = pNextNode->next;
		pCurNode->next = pNextNode;
		flag = 1;
	}
	
	if ( flag )
	{
		pCurNode = pNextNode;
		pLastNode->next = pCurNode;
		flag = 0;

		if (pNextNode)
			pNextNode = pNextNode->next;
	}

	if (pNextNode && pCurNode->val != pNextNode->val)
	{
		pLastNode = pLastNode->next;
		pCurNode = pCurNode->next;
		pNextNode = pNextNode->next;
	}

}

return pNewNode->next;

}


12. 找两个链表第一个公共节点。 180424



struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};



ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2)
{
if (pHead1 == nullptr || pHead2 == nullptr)
return nullptr;

  ListNode *pNode1 = pHead1, *pNode2 = pHead2;
int cnt1 = 0, cnt2 = 0;
while (pNode1)
{
	cnt1++;
	pNode1 = pNode1->next;
}
while (pNode2)
{
	cnt2++;
	pNode2 = pNode2->next;
}

pNode1 = (cnt1>cnt2) ? pHead1 : pHead2;
pNode2 = (cnt1>cnt2) ? pHead2 : pHead1;

for (int ii=0; ii!=abs(cnt1-cnt2); ++ii)
	pNode1 = pNode1->next;

ListNode * pRet = nullptr;
while (pNode1 && pNode2)
{
	if (pNode1 == pNode2)
	{
		pRet = pNode1;
		break;
	}
	else
	{
		pNode1 = pNode1->next;
		pNode2 = pNode2->next;
	}
}

return pRet;

}


13. 复杂链表的复制。180424



struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};



// ---------------牛客网大神通过的版本---------------
RandomListNode* Clone(RandomListNode* pHead )
{
if(!pHead)
return NULL;
RandomListNode *currNode = pHead;

while(currNode)
{
	RandomListNode *node = new RandomListNode(currNode->label);
	node->next = currNode->next;
	currNode->next = node;
	currNode = node->next;
}
currNode = pHead;
while(currNode)
{
	RandomListNode *node = currNode->next;
	if (currNode->random)
		node->random = currNode->random->next;

	currNode = node->next;
}
//拆分
RandomListNode *pCloneHead = pHead->next;
RandomListNode *tmp;
currNode = pHead;

while(currNode->next)
{
	tmp = currNode->next;
	currNode->next =tmp->next;
	currNode = tmp;
}

return pCloneHead;

}



// ------------ 自己的版本,未通过,错误尚未找出-------------
RandomListNode* Clone(RandomListNode* pHead)
{
if (pHead == nullptr)
return nullptr;

  // ------------ 拷贝----------------
  RandomListNode *pNode = pHead;
  while (pNode)
  {
	RandomListNode *pTmp = new RandomListNode(*pNode);
	pTmp->next = pNode->next;
	pNode->next = pTmp;

	if (pNode->random)
		pTmp->random = pNode->random->next;

	pNode = pTmp->next;
	pTmp = nullptr;
  }

  // ------------- 拆分-----------------
  pNode = pHead;
  RandomListNode *pNewHead = pHead->next;
  RandomListNode *pProcNode = pNewHead;

  if (pNode)   // 要让pNode走在pProcNode的前面。
  {
	pNode->next = pProcNode->next;
	pNode = pNode->next;
  }

  while (pProcNode && pNode)
  {
	pProcNode->next = pNode->next;  // pNode后面不会是空,所以这样赋值可以确保pProcNode后面不会是空
	pProcNode = pProcNode->next;
	pNode->next = pProcNode->next;
	pNode = pNode->next;
  }

  return pNewHead;

}


14. 寻找链表中环的入口节点。180425



ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if(pHead == nullptr || pHead->next == nullptr)
return nullptr;

ListNode *pFast = pHead, *pLow = pHead;

// ----------- 获取环的大小------------
int cnt = 0;
pFast = pFast->next;
pFast = (pFast==nullptr) ? pFast : pFast->next;
pLow = pLow->next;
++cnt;

while (pFast != pLow && pFast)
{
	pFast = pFast->next;
	pFast = (pFast==nullptr) ? pFast : pFast->next;
	pLow = pLow->next;
	++cnt;
}

if (pFast == nullptr)
	return nullptr;

// --------获取环的入口-----------
pFast = pLow = pHead;
ListNode *pRet = nullptr;
for (int ii=0; ii != cnt; ++ii)
	pFast = pFast->next;

while (pFast != pLow)
{
	pFast = pFast->next;
	pLow = pLow->next;
}
pRet = pFast;

return pRet;

}


15. 主函数测试。



int main(int argc, char **argv)
{
ListNode * L = new ListNode;
InitList(L);

cout << "请输入链表节点,以-1结束:" << endl;
L = CreateListFromTail();
DisplayList(L);

int pos = 1, value = 10;
cout << "在指定位置 " << pos << " 前方插入节点:" << value << endl;
InsertListNodeFromFront(L, pos, value);
DisplayList(L);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值