- 线性表
(1)线性表: 线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。
线性表的逻辑结构简单,便于实现和操作。
(2)基本特征:
1.集合中必存在唯一的一个“第一元素”;
2.集合中必存在唯一的一个 “最后元素” ;
3.除最后一个元素之外,均有 唯一的后继(后件);
4.除第一个元素之外,均有 唯一的前驱(前件)
- 线性表分类
(1)数组: 存储空间连续
(2)单向链表
(3)双向链表
(4)环形链表
- 存储结构
链表处理核心:
(1) 链表的节点遍历方式
struct ListNode{
int val;
ListNode* next;
};
: 一般在题目中的链表一般以指针的形式给出,所以我们访问的方式是以 ->
链表节点的
(2)链表指针翻转的方法
- 删除链表中的某个节点
void deleteNode(ListNode* node)
{
node->val=node->next->val;
node->next=node->next->next;
}
// 删除某个节点的方法,其实就是修改其中的指针即可
- 链表反转
注意程序的鲁棒性,链表断开等情况
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL) return NULL;//注意程序鲁棒性
ListNode* pNode=pHead;//当前指针
ListNode* pReverseHead=NULL;//新链表的头指针
ListNode* pPrev=NULL;//当前指针的前一个结点
while(pNode!=NULL){//当前结点不为空时才执行
ListNode* pNext=pNode->next;//链断开之前一定要保存断开位置后边的结点
if(pNext==NULL)//当pNext为空时,说明当前结点为尾节点
pReverseHead=pNode;
pNode->next=pPrev;//指针反转
pPrev=pNode;
pNode=pNext;
}
return pReverseHead;
}
};
- 链表的第一个公共结点
输入两个链表,找出它们的第一个公共结点。
class Solution {
public:
ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2)
{
ListNode* p1 = pHead1;
ListNode* p2 = pHead2;
while (p1 != p2)
{
p1 = (p1 == NULL) ? pHead2 : p1->next;
p2 = (p2 == NULL) ? pHead1 : p2->next;
}
return p1;
}
};
- 从尾到到头打印链表
(取自剑指offer题)
思路:利用栈的FILO的特性,实现从尾到到头打印链表
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
class Solution {
public:
void printListFromTailToHead(ListNode* head) {
stack<ListNode*> sta;
ListNode* pNode=head;
while(pNode!=NULL)
{
sta.push(pNode);
pNode=pNode->next;
}
while(!sta.empty())
{
ListNode* ls=sta.top();
cout<<ls->val<<endl;
sta.pop();
}
}
};
- 查找链表倒数第k个节点
时间复杂度O(n)
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if (pListHead == NULL || k == 0) return NULL;
ListNode* pList_ahead = pListHead;
ListNode* pList_behind = pListHead;
for (int i = 1; i < k ; ++i)
{
if (pList_ahead->next != NULL)
pList_ahead = pList_ahead->next;
else
return NULL;
}
while (pList_ahead->next != NULL)
{
pList_behind = pList_behind->next;
pList_ahead = pList_ahead->next;
}
return pList_behind;
}
};
- 合并有序链表
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
ListNode* result = NULL;
ListNode* current = NULL;
if(pHead1 == NULL)
return pHead2;
if(pHead2 == NULL)
return pHead1;
while(pHead1 != NULL && pHead2 != NULL){
if(pHead1->val <= pHead2->val){
if(result == NULL){
current = result = pHead1;
} else {
current->next = pHead1;
current = current->next;
}
pHead1 = pHead1->next;
} else {
if(result == NULL){
current = result = pHead2;
} else {
current->next = pHead2;
current = current->next;
}
pHead2 = pHead2->next;
}
}
if(pHead1 == NULL){
current->next = pHead2;
}
if(pHead2 == NULL){
current->next = pHead1;
}
return result;
}
};
- 删除链表中重复的节点
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if (pHead == NULL) return NULL;
if (pHead != NULL && pHead->next == NULL) return pHead;
ListNode* cur;
if (pHead->next->val == pHead->val)
{
cur = pHead->next->next;
while (cur != NULL && cur->val == pHead->val)
cur = cur->next;
return deleteDuplication(cur);
}
else
{
cur = pHead->next;
pHead->next = deleteDuplication(cur);
return pHead;
}
}
};