单向链表
[cpp]
view plain
copy
- struct ListNode {// 单向链表
- int val;
- struct ListNode *next;
- ListNode(int x) : val(x), next(NULL) {}
- };
从尾到头打印链表
[cpp]
view plain
copy
- vector<int> TravelListFromTailToHead(struct ListNode* head) {// 【从尾到头打印链表】
- vector<int> result;
- if(NULL == head)
- return result;
- ListNode *p = head;
- stack<ListNode*> nodeStack;
- while(p != NULL) {
- nodeStack.push(p);
- p = p->next;
- }
- while(!nodeStack.empty()) {
- p = nodeStack.top();
- result.push_back(p->val);
- nodeStack.pop();
- }
- return result;
- }
链表中倒数第 k 个结点
[cpp]
view plain
copy
- ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {// 【链表中倒数第 k 个结点】
- if(NULL == pListHead || 0 == k) return NULL;
- ListNode *p1 = pListHead, *p2 = pListHead;// 使用快慢指针
- while(p2->next && k– > 1) {// k– > 1 一定要放在后面
- p2 = p2->next;
- }
- if(k > 1) return NULL;// 说明 k 值比节点数还大
- while(p2->next) {
- p2 = p2->next;
- p1 = p1->next;
- }
- return p1;
- }
反转链表
[cpp]
view plain
copy
- ListNode* ReverseList(ListNode* pHead) {// 【反转链表】
- if(NULL == pHead) return NULL;
- ListNode *p = pHead, *pNext = pHead->next, *pPre = NULL;// 需要定义三个指针
- while(pNext) {
- p->next = pPre;
- pPre = p;
- p = pNext;
- pNext = pNext->next;
- }
- p->next = pPre;
- return p;
- }
合并两个排序的链表
[cpp]
view plain
copy
- ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {// 【合并两个排序的链表】
- if(NULL == pHead1) return pHead2;
- if(NULL == pHead2) return pHead1;
- ListNode *pHead = NULL, *p;// pHead:保存新链表表头;p:用于新链表遍历生成
- if(pHead1->val <= pHead2->val) {
- pHead = pHead1;
- pHead1 = pHead1->next;
- } else {
- pHead = pHead2;
- pHead2 = pHead2->next;
- }
- p = pHead;
- while(pHead1 && pHead2) {
- if(pHead1->val <= pHead2->val) {
- p->next = pHead1;
- pHead1 = pHead1->next;
- } else {
- p->next = pHead2;
- pHead2 = pHead2->next;
- }
- p = p->next;
- }
- while(pHead1) {
- p->next = pHead1;
- p = p->next;
- pHead1 = pHead1->next;
- }
- while(pHead2) {
- p->next = pHead2;
- p = p->next;
- pHead2 = pHead2->next;
- }
- return pHead;
- }
两个链表的第一个公共结点
[cpp]
view plain
copy
- ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {// 【两个链表的第一个公共结点】
- ListNode *p = pHead1, *q = pHead2;
- // 先计算两个链表的长度
- unsigned int nLength1 = 0, nLength2 = 0;
- while(p != NULL && q != NULL) {
- nLength1++;
- nLength2++;
- p = p->next;
- q = q->next;
- }
- while(p != NULL) {
- nLength1++;
- p = p->next;
- }
- while(q != NULL) {
- nLength2++;
- q = q->next;
- }
- // 根据两链表的长度差,长的链表先走这个差值的步数
- int n = abs(nLength1 – nLength2);
- p = pHead1;
- q = pHead2;
- if(nLength1 < nLength2) {
- p = pHead2;
- q = pHead1;
- }
- while(n–)
- p = p->next;
- // 对齐后,一起走,直到遇到第一个公共节点
- while(p != NULL && q != NULL && p != q) {
- p = p->next;
- q = q->next;
- }
- return p;
- }
链表中环的入口结点
[cpp]
view plain
copy
- ListNode* getMeetNode(ListNode* pHead) {// 用快慢指针,必然相会于环内某个节点,返回这个节点,否则返回 NULL
- if(NULL == pHead) return NULL;
- ListNode* pSlow = pHead->next;
- if(NULL == pSlow) return NULL;
- ListNode* pFast = pSlow->next;
- while(pSlow != NULL && pFast != NULL) {
- if(pFast == pSlow)
- return pFast;
- pFast = pFast->next;
- pSlow = pSlow->next;
- if(pFast != pSlow)
- pFast = pFast->next;
- }
- return NULL;
- }
- ListNode* EntryNodeOfLoop(ListNode* pHead) {// 【链表中环的入口结点】
- ListNode* meetNode = getMeetNode(pHead);// 用快慢指针得到环内某个节点
- if(NULL == meetNode)
- return NULL;
- int n = 1;
- // 用这个环内节点计算得到环内节点数
- ListNode* p = meetNode->next;
- while(p != meetNode) {
- p = p->next;
- ++n;
- }
- // 用两个指针,一个指针先走环内节点个数的步数,另一个节点在链表头
- // 当两个节点相遇时,此时的节点即是环的入口节点
- p = pHead;
- while(n–)
- p = p->next;
- ListNode* p1 = pHead;
- while(p1 != p) {
- p = p->next;
- p1 = p1->next;
- }
- return p;
- }
判断链表是否是回文结构
[cpp]
view plain
copy
- bool IsPalindrome(ListNode* pHead) {// 【判断链表是否是回文结构】
- // 使用快慢指针,找到链表的中间
- ListNode* pFast = pHead;
- ListNode* pSlow = pHead;
- while(pFast != NULL && pSlow != NULL) {
- pFast = pFast->next;
- pSlow = pSlow->next;
- if(pFast != NULL)
- pFast = pFast->next;
- }
- pSlow = ReverseList(pSlow);// 从中间节点开始将链表反转(链表被改变,即现场改变)
- // 从两头开始往中间遍历,判断是否是回文结构
- bool flag = true;
- ListNode *p1 = pHead, *p2 = pSlow;
- while(p2 != NULL) {
- if(p1->val != p2->val) {
- flag = false;
- }
- p1 = p1->next;
- p2 = p2->next;
- }
- ReverseList(pSlow);// 将链表恢复(恢复现场)
- return flag;
- }
删除链表中的重复结点
删除链表中相邻的重复结点(保留一个)
[cpp]
view plain
copy
- void DeleteDuplication(ListNode* &pHead) {// 【删除链表中相邻的重复结点(保留一个)】
- if(NULL == pHead) return;
- ListNode *p1 = pHead, *p2 = p1->next;
- while(p2 != NULL) {
- if(p2->val == p1->val) {
- while(p2 != NULL && p2->val == p1->val) {
- ListNode* p = p2;
- p2 = p2->next;
- delete p;
- p = NULL;
- }
- p1->next = p2;
- }
- if(NULL != p2)
- p2 = p2->next;
- p1 = p1->next;
- }
- }
删除链表中重复结点(保留一个)
[cpp]
view plain
copy
- void DeleteDuplication2(ListNode* &pHead) {// 【删除链表中重复结点(保留一个)】
- if(NULL == pHead) return;
- set<int> s;
- s.insert(pHead->val);
- ListNode* p = pHead, *pNode = pHead->next;
- while(pNode != NULL) {
- if(s.find(pNode->val) == s.end()) {
- s.insert(pNode->val);
- p->next = pNode;
- p = p->next;
- pNode = pNode->next;
- } else {
- ListNode* q = pNode;
- pNode = q->next;
- delete q;
- q = NULL;
- p->next = NULL;
- }
- }
- }
删除链表中相邻重复结点
[cpp]
view plain
copy
- void DeleteDuplication3(ListNode* &pHead) {// 【删除链表中相邻重复结点】
- if(NULL == pHead) return;
- ListNode *pPre = NULL, *pNode = pHead;
- while(pNode != NULL) {
- ListNode* pNext = pNode->next;
- if(pNext != NULL && pNext->val == pNode->val) {
- const int val = pNode->val;
- ListNode* p = pNode;
- while(p != NULL && val == p->val) {
- pNext = p->next;
- delete p;
- p = pNext;
- }
- if(NULL == pPre)
- pHead = pNext;
- else
- pPre->next = pNext;
- pNode = pNext;
- } else {
- pPre = pNode;
- pNode = pNode->next;
- }
- }
- }
复杂链表
[cpp]
view plain
copy
- struct RandomListNode {// 复杂链表
- int val;
- struct RandomListNode *next, *random;
- RandomListNode(int x) : val(x), next(NULL), random(NULL) {}
- };
复杂链表的复制
[cpp]
view plain
copy
- RandomListNode* Clone(RandomListNode* pHead) {// 【复杂链表的复制】
- if(NULL == pHead) return NULL;
- RandomListNode *p = pHead;
- while(p != NULL) {
- RandomListNode *pNode = new RandomListNode(p->val);
- pNode->next = p->next;
- p->next = pNode;
- p = pNode->next;
- }
- p = pHead;
- RandomListNode *pClone;
- while(p != NULL) {
- pClone = p->next;
- if(p->random != NULL)
- pClone->random = p->random->next;
- p = pClone->next;
- }
- p = pHead;
- RandomListNode *pCloneHead = pHead->next;
- // pClone = pHead->next;
- // p = pClone->next;
- // while(p != NULL) {
- // pClone->next = p->next;
- // pClone = pClone->next;
- // p->next = pClone->next;
- // p = p->next;
- // }
- RandomListNode *tmp;
- while(p->next) {
- tmp = p->next;
- p->next = tmp->next;
- p = tmp;
- }
- return pCloneHead;
- }