#include <iostream>
#include <assert.h>
#include <malloc.h>
#include <stack>
using namespace std;
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node* next;
}Node,*pNode,*pList;
void Init(pList* head)
{
*head = NULL;
}
void PushBack(pList* head,DataType x)//尾插
{
Node* cur = *head;
Node* p = (Node*)malloc(sizeof(Node));
p->data = x;
p->next = NULL;
if (cur == NULL)//空链表
{
*head = p;
}
else
{
while (cur->next)//非空链表
{
cur = cur->next;
}
cur->next = p;
}
}
//逆序打印链表
void PrintfromTail1(pNode head)
{
//1.数组
//2.逆序---->正向打印---->逆序
//3.递归
if (head)
{
PrintfromTail1(head->next);
cout << head->data<<"--->";
}
}
//递归转循环
void PrintfromTail2(pNode head)
{
if (head == NULL)
return;
stack<Node*> s;
Node* cur = head;
while (cur)
{
s.push(cur);
cur = cur->next;
}
while (!s.empty())
{
cur = s.top();
cout << cur->data << " ";
s.pop();
}
cout << endl;
}
void Print(pNode head)//正序打印
{
pNode cur = head;
for (; cur!=NULL; cur = cur->next)
{
cout << cur->data << " ";
}
cout << endl;
}
size_t size(pNode head)
{
pNode cur = head;
size_t count = 0;
while (cur)
{
cur = cur->next;
count++;
}
return count;
}
pNode Find(pNode head,size_t pos)
{
assert(pos >= 0 && pos <= size(head));
pNode cur = head;
if (head == NULL)
return NULL;
else
{
for (size_t i = 0; i < pos; i++)
{
cur = cur->next;
}
}
return cur;
}
//删除无头单链表的非尾结点
void DelteNoTail(pNode head, int pos)
{
pNode p=Find(head, pos);
pNode Del = p->next;
swap(p->data, Del->data);
p->next = Del->next;
delete Del;
}
//在无头单链表的一个非头结点前插入一个结点
void InsertNoHead(pNode head, int pos,DataType data)
{
pNode p = Find(head, pos);
pNode pnext = p->next;
pNode NewNode = new Node;
NewNode->data = data;
p->next = NewNode;
NewNode->next = pnext;
swap(p->data, NewNode->data);
}
pNode Back(pNode head)//找到最后一个元素
{
if (head == NULL)
return NULL;
pNode cur = head;
while (cur->next)
{
cur = cur->next;
}
return cur;
}
//单链表实现约瑟夫环
pNode JosephCircle(pNode head, int M)
{
//构环
pNode Tail = Back(head);
pNode cur = head;
Tail->next = head;
while (cur->next!=cur)
{
int N = M;//重要
while (--N)//报数
{
cur = cur->next;
}
cout << cur->data<<" ";
//替换删除
pNode Del = cur->next;
cur->data = Del->data;
cur->next = Del->next;
delete Del;
}
cout << endl;
cur->next = NULL;
head = cur;
return cur;
}
//逆置/反转单链表
//1.三个指针
pNode Reverse(pNode& head)
{
//空链表,只有一个结点的链表
if (head==NULL || head->next==NULL)
return head;
pNode pPre = NULL;
pNode pCur = head;
pNode pNext = head->next;
while (pNext)
{
pCur->next = pPre;
pPre = pCur;
pCur = pNext;
pNext = pCur->next;
}
pCur->next = pPre;
head = pCur;
}
//头插逆置
pNode ReverList(pNode& head)
{
pNode pCur = head;
pNode pCurNext = NULL;
pNode Newhead = NULL;
while (pCur)
{
pCurNext = pCur->next;
pCur->next = Newhead;
Newhead = pCur;
pCur = pCurNext;
}
return Newhead;
}
//单链表排序
void BubbleSort(pNode head)
{
if (head == NULL || head->next == NULL)
return;
pNode pCur = head;
pNode pNext = pCur->next;
pNode pTail = NULL;
bool ischange = false;
while (pTail != head)
{
pCur = head;
pNext = pNext->next;
ischange = false;//标志,检查是否发生交换
while (pNext)
{
if (pCur->data > pNext->data)
{
swap(pCur->data, pNext->data);
ischange = true;
}
pCur = pNext;
pNext = pNext->next;
}
pTail = pCur;
if (!ischange)//没有交换
return;
}
}
//合并两个有序链表,合并后仍有序
pNode Merge2List(pNode phead1, pNode phead2)
{
pNode L1 = phead1;
pNode L2 = phead2;
pNode pNewNode = NULL;
pNode pTail = NULL;
//有一个为空
if (L1 == NULL)
return L2;
if (L2 == NULL)
return L1;
//设置第一个头指针的位置在head1还是head2的位置
if (L1->data <= L2->data)
{
pNewNode = L1;
pTail = pNewNode;
L1 = L1->next;
}
else
{
pNewNode = L2;
pTail = pNewNode;
L2 = L2->next;
}
//比较,每次比较小的尾插在新链表中
while (L1&&L2)
{
if (L1->data <= L2->data)
{
pTail->next = L1;
L1 = L1->next;
}
else
{
pTail->next = L2;
L2 = L2->next;
}
pTail = pTail->next;
}
//一个链表走到尾,另一个链表直接连接在新链表的尾部
if (L1)
pTail->next = L1;
if (L2)
pTail->next = L2;
return pNewNode;
}
//查找中间结点
pNode MidNode(pNode head)
{
pNode fast = head;
pNode slow = head;
pNode cur = head;
if (head == NULL||head->next==NULL)
return head;
//while (fast)
//{
// fast = fast->next->next;
// slow = slow->next;
//}
//return slow;//偶数返回中间的后一个
while (fast->next&&fast->next->next)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
//删除倒数第k个结点
void DelRekNode(pNode head, size_t k)
{
pNode fast = head;
pNode slow = head;
pNode cur = NULL;
pNode Del = NULL;
if (NULL == head || k == 0)//链表为空或k为0
return;
while (k--)//快指针先走k步
{
fast = fast->next;
}
while (fast->next)
{
fast = fast->next;
slow = slow->next;
}
cur = slow;//cur指向要删除结点的前一个结点
Del = cur->next;
cur->next = Del->next;
delete Del;
}
/*
//判断链表是否带环
bool IsCricle(pNode head)
{
pNode fast = head;
pNode slow = head;
while (fast&&slow)
{
if (fast == slow)
return true;
else
return false;
fast = fast->next->next;
slow = slow->next;
}
}
*/
//判断是否带环,返回两个指针相遇位置
pNode IsCricle(pNode head)
{
pNode fast = head;
pNode slow = head;
while (fast && slow&&fast->next)
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
return fast;
}
return NULL;
}
//求环的长度
size_t LenofCricleList(pNode head)
{
pNode meet = IsCricle(head);
assert(meet);
int count = 1;
pNode cur =meet;
while (cur->next!=meet)
{
cur = cur->next;
count++;
}
return count;
}
//求环入口地址
pNode ExtofCircle(pNode head)
{
pNode meet = IsCricle(head);
assert(meet);
pNode cur = head;
while (cur!=meet)
{
meet = meet->next;
cur = cur->next;
}
return cur;
}
size_t LenNoCircle(pNode head)
{
size_t len = 0;
while (head)
{
head = head->next;
len++;
}
return len;
}
//判断两链表是否相交,若相交,求交点
pNode CheckCross(pNode head1, pNode head2)
{
pNode cur1 = head1;
pNode cur2 = head2;
//两个链表均不带环
if ((!IsCricle(head1)) && (!IsCricle(head2)))
{
size_t len1 = LenNoCircle(head1);
size_t len2 = LenNoCircle(head2);
if (len1 > len2)
{
//头指针为head1的链表先走len2-len1步
for (int i = 0; i < len2 - len1; i++)
{
cur1 = cur1->next;
}
}
if (len1>len2)
{
for (size_t i = 0; i <= len1 - len2; i++)
{
cur2 = cur2->next;
}
}
//两个指针一起走
while ((NULL != cur1) && (NULL != cur2))
{
cur1 = cur1->next;
cur2 = cur2->next;
if (cur1 == cur2)
return cur1;
}
}
//两个链表均带环
else if (IsCricle(head1) && IsCricle(head2))
{
//交点在环外
pNode ex1 = ExtofCircle(head1);
pNode ex2 = ExtofCircle(head2);
if (ex1 == ex2)
{
//两个链表环外的部分的长度
ex1->next = NULL;
ex2->next = NULL;
size_t len1 = LenNoCircle(head1);
size_t len2 = LenNoCircle(head2);
while (len1 < len2)
{
for (size_t i = 0; i < len1 - len2; i++)
{
cur2 = cur2->next;
}
}
while (len1>len2)
{
for (size_t i = 0; i < len2 - len1; i++)
{
cur1 = cur1->next;
}
}
while (NULL != cur1&&NULL != cur2)
{
cur1 = cur1->next;
cur2 = cur2->next;
if (cur1 == cur2)
return cur1;
}
}
else
{
return ex1;
}
}
//其他情况
return NULL;
}
int main()
{
Node* head0 = NULL;//不带环
Init(&head0);
PushBack(&head0, 1);
PushBack(&head0, 4);
PushBack(&head0, 6);
PushBack(&head0, 8);
pNode tail = Back(head0);
Node* head1 = NULL;//不带环
Init(&head1);
PushBack(&head1, 1);
PushBack(&head1, 3);
pNode mid = Back(head1);
PushBack(&head1, 5);
PushBack(&head1, 7);
tail->next = mid;
pNode p=CheckCross(head0, head1);
cout << p << endl;
Node* head2 = NULL;//带环
Init(&head2);
PushBack(&head2, 2);
PushBack(&head2, 3);
PushBack(&head2, 7);
PushBack(&head2, 9);
pNode pTail = Back(head2);
pTail->next = head2;
//Print(head);
//DelteNTail(head, 1);
//Print(head);
//InsertNoHead(head, 2,10);
//Print(head);
//JosephCircle(head, 2);
//Reverse(head);
//Print(head);
//pNode p =ReverList(head);
//Print(p);
//BubbleSort(head);
//Print(head);
//pNode p=Merge2List(head, head1);
//Print(p);
//pNode mid = MidNode(head);
//cout << mid->data << endl;
//DelRekNode(head, 3);
//Print(head);
//if (IsCricle(head1))
//cout << "1" << endl;
//else
//cout << "-1" << endl;
//int len = LenofCricleList(head1);
//cout << len << endl;
//ExtofCircle(head1);
system("pause:");
return 0;
}
用C++语言实现链表面试题
最新推荐文章于 2024-04-25 19:34:16 发布