一、单链表反转
LinkList Reserve_L(LinkList L)
{
if(L==NULL||L->next==NULL)
return 0;
LNode *p,*r;
p=L->next;//指向第一个结点
L->next=NULL;//把头结点摘下来
while(p!=NULL)
{
r=p->next;//向后遍历
p->next=L->next;//把p指向的结点摘下来, 第一次时next=null 充当最后一个结点
L->next=p;//头插法,把第一个结点插在表头之后
p=r;
}
}
上面这一种是 不算表头的 表头里没有数据
下面这一种是表头带数据,表头也要丢到最后
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;
}
二、判断单链表是否有环
bool isLoop(Node *head)
{
Node *fast,*slow;
slow=fast=head;
while(slow!=NULL&&fast->next!=NULL)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
return true;
}
return false;
}
三、判断链表中的环的入口
ListNode* EnterofLoop(ListNode* pHead)
{
if(pHead==NULL||pHead->next==NULL||pHead->next->next==NULL)//结点不足三个构不成环
{
return NULL;
}
ListNode *pFast=pHead->next->next;
LiseNode *pSlow=pHead->next;
while(pFast!=pSlow)
{
if(pFast->next!=NULL&&pFast->next->next!=NULL)
{
pFast=pFast->next->next;
pSlow=pSlow->next;
}
else return NULL;
}
pFast=pHead;
while(pFast!=pSlow)
{
pFast=pFast->next;
pSlow=pSlow->next;
}
return pFast;
}
四、合并2个有序链表
递归操作:
Node mergeList(Node List1,Node List2)
{
if(List1==NULL)
return List2;
if(List2==NULL)
return List1l;
Node *resultNode;
if(list1->val<list2->val)
{
resultNode=list1;
list1=list1->next;
}
else
{
resultNode=list2;
list2=list2->next;
}
resultNode->next=mergeList(List1,List2);
return resultNode;
}
非递归写法
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
ListNode *p1,*p2,*pre1,*p3;
pre1 = p1 = pHead1; p2 = pHead2;
while(p1 && p2)
{
if(p1->val > p2->val)
{
pre1->next = p2;
p3 = p2->next;
p2->next = p1;
p2 = p3;
}
pre1 = p1;
p1 = p1->next;
}
if(p2)
pre1->next = p2;
return pHead1;
}
五、删除链表中重复出现的结点
(1)重复的全部删除
pre指针指向一定不重复的结点,last是工作指针用于遍历。
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead == NULL || pHead->next == NULL)
return pHead;
ListNode *Head = new ListNode(0);
Head->next = pHead;//在链表前新建一个结点,防止第一个和第二个就相同
ListNode *pre = Head;
ListNode *last = Head->next;
while(last != NULL)
{
if(last->next != NULL && last->val == last->next->val)
{
while(last->next != NULL && last->val == last->next->val)
{
last = last->next;
}
pre->next = last->next;//标志处
last = last->next;
}
else
{
pre = pre->next;
last = last->next;
}
}
return Head->next;
}
(2)重复的结点保留一次
public static Node deleteDup3(Node x) {
Node tmp = x;
while(tmp != null) {
if (tmp.next == null) {
break;
}
if (tmp->val == tmp->next->val) {
tmp->next = tmp->next->next;
} else {
tmp = tmp->next;
}
}
return x;
}
递归解法
public static Node deleteDup4(Node head) {
if (head == null || head.next == null)
return head;
head.next = deleteDup4(head.next);
return head.val == head.next.val ? head.next : head;
}
六、找出两个链表的第一个公共结点
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
map<ListNode*, int> m;
ListNode *p = pHead1;
while(p != NULL) {
m[p] = 1;
p = p->next;
}
p = pHead2;
while(p != NULL) {
if(m[p]) {
return p;
}
p = p->next;
}
return NULL;
}
最后一提,一个综合的算法题目
一个链表假设第一个节点定位下标1,第二个为2,下标为奇数的结点是升序排序,偶数的结点是降序排序,如何让整个链表有序?
第一步 拆分成2个链表保存
第二步 其中一个链表进行反转
第三步 合并2个有序链表。
这里不细说了 上面都有提到过,读者们自行编码调试吧!