下面是后面链表相关题目中需要用到的链表结点的定义和相关操作函数,参见下面的list.h文件:
注意链表结点的定义采用cpp的定义方式,它会被cpp的文件调用。比如后面删除链表重复结点的文件del_repeated_list.cpp中的编译方式:
g++ -g del_repeated_list.cpp -o del_repeated_list
#include
#include struct ListNode{int value;ListNode* next;
};ListNode* CreateListNode(int value){ListNode* pNode = new ListNode();pNode->value = value;pNode->next = NULL;return pNode;
}void ConnectListNode(ListNode* pCurrent, ListNode* pNext){if(pCurrent == NULL){printf("Error to connect two nodes.
");exit(1);}pCurrent->next = pNext;
}void PrintListNode(ListNode* pNode){if(pNode == NULL)printf("The node is null.
");elseprintf("The key in node is %d.
", pNode->value);
}void PrintList(ListNode* pHead){ListNode* pNode = pHead;while(pNode){printf("%d ", pNode->value);pNode = pNode->next;}printf("
");
}void DestroyList(ListNode* pHead){ListNode* pNode = pHead;while(pNode){ListNode* pNext = pNode->next;delete pNode;pNode = pNext;}
}void AddToTail(ListNode** pHead, int value){ListNode* pNode = new ListNode();pNode->value = value;pNode->next = NULL;if(*pHead == NULL)*pHead = pNode;else{ListNode* pCurrent = *pHead;while(pCurrent->next)pCurrent = pCurrent->next;pCurrent->next = pNode;}
}void RemoveHead(ListNode** pHead, int value){if(pHead == NULL || *pHead == NULL)return;ListNode* pToBeDeleted = NULL;if((*pHead)->value == value){pToBeDeleted = *pHead;*pHead = (*pHead)->next;}else{ListNode* pNode = *pHead;while(pNode->next != NULL && pNode->next->value != value)pNode = pNode->next;if(pNode->next != NULL && pNode->next->value == value){pToBeDeleted = pNode->next;pNode->next = pNode->next->next;}}if(pToBeDeleted != NULL){delete pToBeDeleted;pToBeDeleted = NULL;}
}
题目:链表中倒数第k个节点 输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。 示例: 给定一个链表: 1->2->3->4->5, 和 k =...
题目:从尾到头打印链表 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 限制: 0 <= 链表长度 <= 10000 题目: /*** Definition for singly-linked list.* struct Lis...
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例:输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 解法一:双指针法 时间复杂度:O(a+b) 循环比较两个子问题的次数为 a+b a,b为两个子问题的长度空间复杂度:O(1) 双指针,常数级别复杂度...
这是一道经典的面试题,下面是我的研究和举一反三,特整理如下: 分为三种情形: (1)删除有序链表的重复节点,重复节点一个都不留 (2)删除有序链表的重复节点,重复节点只留一个 (3)删除无序链表的重复节点,重复节点只留一个 下面是相关节点的定义: typedef struct ListNode {int val;struc...
题目:合并两个排序的链表 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。 示例1: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 限制: 0 <= 链表长度 <= 1000 解题: /*** Definition for singly-linked li...
题目:反转链表 定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 限制: 0 <= 节点个数 <= 5000 解题: 方法一:双指针 我们可以申请两个指针,第一个指针叫 new_next,最...
LRU算法(Least Recently Used) 算是我们经常遇到的一种淘汰算法,其中内存管理模块进行内存页回收时有用到,针对不经常使用的内存页,LRU淘汰策略能够将该内存页回收给操作系统。 属于 我们操作系统设计中的 时间局部性原理,最长时间未被访问的数据优先淘汰,当内存中已存在的数据再次被访问时,则进行热度的提升。 本文为...
题目描述 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 示例: 给定 1->2->3->4, 你应该返回 2->1->4->3. 方法一(递归): 将配对交换过程拆解为多个以两个元素为一对的子问题 …n(k-1) -> n(k)->n(k+1)...
已知两个已排序链表头节点指针headA与headB,将这两个链表合并,合并后仍为 有序的,返回合并后的头节点。 主要步骤如下: 创建一个临时的头节点,头节点每次指向headA 或者 headB较小的节点当headA->data 比headB->data小的时候,headA的当前节点加入临时头节点,同时headA指针向后移动;否则h...