习题:
1.
a.(4)(1)
b.(7)(11)(8)(4)(1)
c.(5)(12)
d.(9)(4)(1)
2.
a.(11)(3)(14)
b.(10)(12)(8)(11)(3)(4)
c.(10)(12)(7)(3)(4)
d.(12)(11)(3)(14)
e.(12)(9)(11)(3)(4)
5
#include<stdio.h>
#include<math.h>
//5
//从前向后 依次头插
void Reverse(PNode plist)
{
//assert
Node* p = plist->next;
Node* q = NULL;
plist->next = NULL;
while (p != NULL)
{
q = p->next;
p->next = plist->next;
plist->next = p;
p = q;
}
}
//这个逆置方法 偏难 用了三个指针
void Reverse2(PNode plist)
{
assert(plist != NULL && plist->next != -NULL && plist->next->next != NULL);
//if
Node* p = plist->next;
Node* q = p->next;
Node* r = NULL;
p->next = NULL;
while (q != NULL)//p和r 都不合适 不能用来做标记
{
r = q->next;
q->next = p;
p = q;
q = r;
}
plist->next = p;
}
//面试题1
//fast slow
bool IsCircle(PNode plist)
{
//assert
assert(plist != NULL && plist->next != NULL);
Node* fast = plist;
Node* slow = plist;
//进来以前 让快慢指针先走一步
slow = slow->next;
fast = fast->next->next;
while ((fast != NULL) && (fast != slow))//1.不存在环 2.存在环
{
slow = slow->next;//慢指针走一步
fast = fast->next;//快指针先走一步
if (fast != NULL)//快指针这一步没走空,则再走一步
{
fast = fast->next;
}
}
if (fast == slow)//相遇 代表有环
{
return true;
}
return false;
/*if(fast == NULL)
return false;
return true;*/
}
//面试题2
Node* Intersect(PNode plist1, PNode plist2)
{
//assert
int len1 = Get_length(plist1);
int len2 = Get_length(plist2);
Node* p = len1 >= len2 ? plist1 : plist2;
Node* q = len1 > len2 ? plist2 : plist1;
//这两行代码 保证p肯定指向的是较长的那个单链表
for (int i = 0; i < abs(len1 - len2); i++)
{
p = p->next;
}
while (p != q)
{
p = p->next;
q = q->next;
}
return p;//如果返回的是NULL 代表没有交点
//如果返回的是非NULL 代表有交点 并且还将第一个交点返回出来了
}
//面试题3
Node* Get_Circle_first(PNode plist)
{
assert(plist != NULL && plist->next != NULL);
Node* fast = plist->next->next;
Node* slow = plist->next;
while ((fast != NULL) && (fast != slow))//1.不存在环 2.存在环
{
slow = slow->next;//慢指针走一步
fast = fast->next;//快指针先走一步
if (fast != NULL)//快指针这一步没走空,则再走一步
{
fast = fast->next;
}
}
if (fast != slow)
{
return NULL;
}
//由 x = (n-1)(y+z)+z 得到 一个指针从头跑
//一个指针从快慢指针相交点开始跑 速度保持一致 当相遇的时候,则是入环点
Node* p = plist;
Node* q = fast;
while (p != q)
{
p = p->next;
q = q->next;
}
return p;
}
//面试题4
//借尸还魂 让下一个节点当作替死鬼
bool Del_No_Tail(PNode plist, PNode p)
{
assert(p->next != NULL);
p->data = p->next->data;
Node* q = p->next;
p->next = p->next->next;
free(q);
return true;
}
//面试题5
bool Insert_Prior(PNode plist, PNode p, int val)
{
assert(plist != NULL && p != NULL);
Node* pnewnode = (Node*)malloc(sizeof(Node) * 1);
assert(pnewnode != NULL);
pnewnode->data = val;
pnewnode->next = p->next;
p->next = pnewnode;
int tmp = p->data;
p->data = pnewnode->data;
pnewnode->data = tmp;
return true;
}
//面试题6
bool Del_K(PNode plist, int k)
{
//assert plist k
Node* p = plist;
Node* q = plist;
for (int i = 0; i <= k; i++)
{
q = q->next;
}
while (q != NULL)
{
p = p->next;
q = q->next;
}
q = p->next;
p->next = p->next->next;
free(q);
return true;
}