单链表的基本应用及面试题及复杂链表

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int DataType;
typedef struct Node1
{
struct Node1*next;
struct Node1*random;
DataType data;
}*PCListNode,PclistNode;
typedef struct Node
{
struct Node* next;
DataType data;
}*NODE, Node;
//创建链表
void SListInit(NODE *pHead)
{
assert(pHead);
*pHead = NULL;
}
//创建复杂链表
void SListInit1(PCListNode *pHead)
{
assert(pHead);
*pHead = NULL;
}
//申请新的节点
NODE BuySListNode(DataType data)
{
NODE PNEW = (NODE)malloc(sizeof(Node));
if (NULL == PNEW)
{
return NULL;
}
PNEW->data = data;
PNEW->next = NULL;
return PNEW;
}
// 尾插
void SListPushBack(NODE *pHead, DataType data)
{
NODE PNEW = NULL;
PNEW = BuySListNode(data);
assert(pHead);
//空
if (NULL == (*pHead))
{
*pHead = PNEW;
}//非空
else
{
NODE p = *pHead;
while (p->next)
p = p->next;
p->next = PNEW;
}
}
//复杂链表创建新节点
PCListNode BuySListNode1(DataType data)
{
PCListNode PNEW = (PCListNode)malloc(sizeof(PclistNode));
if (NULL == PNEW)
{
return NULL;
}
PNEW->data = data;
PNEW->next = NULL;
PNEW->random = NULL;
return PNEW;
}
//复杂链表尾插
void SListPushBack1(PCListNode *pHead, DataType data)
{
PCListNode PNEW = NULL;
PNEW = BuySListNode1(data);
assert(pHead);
//空
if (NULL == (*pHead))
{
*pHead = PNEW;
}//非空
else
{
PCListNode p = *pHead;
while (p->next)
p = p->next;
p->next = PNEW;
}
}
// 尾删 
void  SListPopBack(NODE *pHead)
{
assert(pHead);
NODE L = *pHead;
if (L == NULL)
{
return;
}
while (L->next->next != NULL)
{
L = L->next;
}
L->next = NULL;
free(L->next);
}
// 头插 
void SListPushFront(NODE *pHead, DataType data)
{
assert(pHead);
NODE PNEW = NULL;
PNEW = BuySListNode(data);
if (PNEW == NULL)
{
return;
}
PNEW->next = *pHead;
*pHead = PNEW;


}
//头删 
void SListPopFront(NODE *pHead)
{
NODE pDel = NULL;
assert(pHead);
//空
if (NULL == (*pHead))
return;
pDel = *pHead;
*pHead = pDel->next;
free(pDel);
}
// 查找值为data的结点,返回该结点在链表中的位置 
NODE SListFind(NODE *pHead, DataType data)
{
assert(pHead);
NODE L = *pHead;
while (L != NULL)
{
if (L->data == data)
{
return L;
}
L = L->next;
}
return NULL;
}
// 查找值为data的结点,返回该结点在复杂链表中的位置 
PCListNode SListFind1(PCListNode *pHead1, DataType data)
{
assert(pHead1);
PCListNode L = *pHead1;
while (L != NULL)
{


if (L->data == data)
{
return L;
}
L = L->next;
}
return NULL;
}
// 在链表pos位置后插入结点data 
void SListInsert(NODE *pHead, NODE pos, DataType data)
{
assert(pHead);
NODE PNEW = NULL;
PNEW = BuySListNode(data);
PNEW->next = pos->next;
pos->next = PNEW;
}
// 在复杂链表pos位置后插入结点data
void SListInsert1(PCListNode *pHead, PCListNode pos, DataType data)
{
assert(pHead);
PCListNode PNEW = NULL;
PNEW = BuySListNode1(data);
PNEW->next = pos->next;
pos->next = PNEW;
}
// 删除链表pos位置上的结点 
void SListErase(NODE *pHead, NODE pos)
{
assert(pHead);
assert(pos);
if (*pHead == NULL||NULL==pos)
return ;
if (pos == *pHead)
SListPopFront(pHead);
else
{
NODE L = *pHead;
while (L&&L->next != pos)
{
L = L->next;
}
if (L)
{
L->next = pos->next;
free(pos);
}
}
}
// 销毁单链表 
void  SListDestroy(NODE *pHead)
{
assert(pHead);
NODE pDel = NULL;
while (*pHead)
{
pDel = *pHead;
*pHead = pDel->next;
free(pDel);
}
}
// 求链表中结点的个数 
int SListSize(NODE pHead)
{
assert(pHead);
NODE L = pHead;
int count = 0;
if (pHead == NULL)
{
return 0;
}
while (L != NULL)
{
L = L->next;
count++;
}
return count;
}
// 将链表中的结点清空 
void SListClear(NODE *pHead)
{
assert(pHead);
NODE L = *pHead;
NODE tmp = NULL;
if (*pHead == NULL)
{
return;
}
while (L)
while (L->next->next != NULL)
{
L = L->next;
}
L->next = NULL;
free(L->next);
}
// 获取链表中的最后一个结点,返回该结点的地址 
NODE SListBack(NODE *pHead)
{
assert(pHead);
NODE L = *pHead;
if (*pHead = NULL)
return NULL;
while (L->next)
{
L = L->next;
}
return L;
}
// 删除链表的非尾结点,要求不能遍历链表 
//利用伪删除
void DeleteNotTailNode(NODE pos)
{
assert(pos);
NODE pCur = pos->next;
pos->data = pCur->data;
pos->next = pCur->next;
}
// 在链表pos位置前插入值为data的结点 
//利用伪替换
void InsertPosFront(NODE pos, DataType data)
{
assert(pos);
NODE PNEW = BuySListNode(data);
PNEW->next = pos->next;
pos->next = PNEW;
int tmp = pos->data;
pos->data = PNEW->data;
PNEW->data = tmp;
}
// 约瑟夫环 
void JosephCircle(NODE* pHead, const int M)
{
assert(pHead);
NODE pCur = *pHead;
NODE L = SListBack(pHead);
L->next = pCur;
while (pCur->next != pCur)
{
int count = M;
while (--count)
pCur = pCur->next;


pCur->data = pCur->next->data;
pCur->next = pCur->next->next;
*pHead = pCur;
free(pCur->next);
}
pCur->next = NULL;
*pHead = pCur;

}
// 使用冒泡方式对单链表进行排序 
void BubbleSort(NODE pHead)
{
assert(pHead);
NODE pCur = pHead;
NODE pTail = NULL;
while (pCur != pTail)
{
while (pCur->next != pTail)
{
if (pCur->data > pCur->next->data)
{
int tmp = pCur->next->data;
pCur->next->data = pCur->data;
pCur->data = tmp;
}
pCur = pCur->next;
}
pTail = pCur;
pCur = pHead;


}
}
// 单链表的逆序---三个指针 
void ReverseSList(NODE* pHead)
{
assert(*pHead);
NODE pCur = *pHead;
NODE pTail = NULL;
NODE pPre = NULL;
while (pCur)
{
pTail = pCur->next;
pCur->next = pPre;
pPre = pCur;
pCur = pTail;
}
*pHead = pPre;
}
// 单链表的逆序---使用头插法 
NODE ReverseSListOP(NODE pHead)
{
NODE pCur = pHead;
NODE pnewHead = NULL;
NODE pNext = NULL;
while (pCur)
{
pNext = pCur->next;
pCur->next = pnewHead;
pnewHead = pCur;
pCur = pNext;


}
pHead = pnewHead;
return pHead;
}
// 合并两个有序链表,合并起来依然要有序 
NODE MergeSList(NODE pHead1, NODE pHead2)
{
NODE L1 = pHead1;
NODE L2 = pHead2;
NODE pTail = NULL;
NODE  pnewHead= NULL;
NODE  end=pnewHead ;
if (L1->data < L2->data)
{
pnewHead = L1;
L1 = L1->next;
}
else
{
pnewHead = L2;
L2 = L2->next;
}
end=pnewHead ;
while (L1&&L2)
{
if (L1->data > L2->data)
{
end->next = L2;
end = L2;
L2 = L2->next;
}
else
{
end->next = L1;
end = L1;
L1 = L1->next;
}
}

if (!L1)
{
end->next = L2;
}
if (!L2)
{
end->next = L1;
}

return pnewHead;
}
// 查找链表的中间结点,要求只能遍历一次链表 
NODE FindMiddleNode(NODE pHead)
{
NODE pFast = pHead;
NODE pSlow = pHead;
while (pFast&&pFast->next)
{
pFast = pFast->next->next;
pSlow = pSlow->next;
}
return pSlow;
}
// 查找链表的倒数第K个结点 
NODE FindLastKNode(NODE pHead, int K)
{
NODE pFast = pHead;
NODE pSlow = pHead;
while (K--)
{
pFast = pFast->next;
}
while (pFast)
{
pFast = pFast->next;
pSlow = pSlow->next;
}
return pSlow;
}
// 判断两个单链表是否相交---链表不带环 
int IsCrossWithoutCircle(NODE pHead1, NODE pHead2)
{
assert(pHead1);
assert(pHead2);
NODE L1 = pHead1;
NODE L2 = pHead2;
while (L1->next)
{
L1 = L1->next;
}
while (L2->next)
{
L2 = L2->next;
}
if (L1 == L2)
{
return 1;
}
else
return 0;
}
// 如果相交 获取交点 
NODE GetCrossNode(NODE pHead1, NODE pHead2)
{
assert(pHead1);
assert(pHead2);
NODE L1 = pHead1;
NODE L2 = pHead2;
int count1 = 0;
int count2 = 0;
count1 = SListSize(pHead1);
count2 = SListSize(pHead2);
int M = count1 - count2;
while (M)
{
if (M> 0)
{
L1 = L1->next;
M--;
}
else
{
L2 = L2->next;
M++;
}
}
while (L1&&L2)
{
if (L1 == L2)
{
return L1;
}
else
{
L1 = L1->next;
L2 = L2->next;
}
}
return NULL;
}
// 判断链表是否带环 
NODE IsCircle(NODE pHead)
{
assert(pHead);
NODE pFast = pHead;
NODE pSlow = pHead;
while (pFast&&pSlow)
{
pFast = pFast->next->next;
pSlow = pSlow->next;
if (pFast == pSlow)
{
return pFast;
}
}
return NULL;
}


// 求环的长度 
int GetCircleLen(NODE pHead)
{
assert(pHead);
NODE pMeetNode = IsCircle(pHead);
NODE pCur = pMeetNode;
int count = 1;
while (pCur->next != pMeetNode)
{
pCur = pCur->next;
count++;
}
return count;
}




// 求环的入口点--注意推断过程 
NODE GetEnterNode(NODE pHead, NODE pMeetNode)
{
assert(pHead);
assert(pMeetNode);
NODE pCur = pHead;
while (pMeetNode != pCur)
{
pMeetNode = pMeetNode->next;
pCur = pCur->next;
}
return pCur;
}




// 判断链表是否相交,(链表可能带环)
void IsListCrossWithCircle(NODE pHead1, NODE pHead2)
{
assert(pHead1);
assert(pHead2);
NODE L1 = pHead1;
NODE L2 = pHead2;
NODE pMeetNode1 = IsCircle(pHead1);
NODE pMeetNode2 = IsCircle(pHead2);
if (pMeetNode1 == NULL&&pMeetNode2 == NULL)
{
if (IsCrossWithoutCircle(pHead1, pHead2) == 1)
{
printf("链表相交!!!");
}
else
{
printf("链表不相交!!!");
}
}
else if ((pMeetNode1 == NULL&&pMeetNode2 != NULL) || (pMeetNode2 == NULL&&pMeetNode1 != NULL))
{
printf("链表不相交!!!");
}
else if (pMeetNode1&&pMeetNode2)
{
printf("链表相交!!!");
}
}


// 复杂链表的复制 
PCListNode CopyComplexList(PCListNode pHead1)
{
if (pHead1 == NULL)
{
return NULL;
}


PCListNode pOldNode = NULL;
PCListNode pNewNode = NULL;
PCListNode pHead2 = NULL;
PCListNode Pcur = SListFind1(&pHead1, 1);
SListInsert1(&pHead1,Pcur , 1);
    Pcur = SListFind1(&pHead1, 2);
SListInsert1(&pHead1, Pcur, 2);
Pcur = SListFind1(&pHead1, 3);
SListInsert1(&pHead1, Pcur, 3);
Pcur = SListFind1(&pHead1, 4);
SListInsert1(&pHead1, Pcur, 4);
//复制复杂链表接链
pOldNode = pHead1;
while (pOldNode)
{
pNewNode = pOldNode->next;
if (NULL == pOldNode->random)
{
pNewNode->random = NULL;
}
else
pNewNode->random = pOldNode->random->next;


pOldNode = pNewNode->next;
}
//拆
pOldNode = pHead1;
pNewNode = pOldNode->next;
pHead2 = pNewNode;
while (pNewNode->next != NULL)
{
pOldNode->next = pNewNode->next;
pOldNode = pNewNode->next;
pNewNode->next = pOldNode->next;

pNewNode = pOldNode->next;
}
pOldNode->next = NULL;




return pHead2;
}


//总结链表和顺序表的优缺点
///打印链表
void PrintSList(NODE pHead)
{
NODE L = pHead;
while (L != NULL)
{
printf("%d--->", L->data);
L = L->next;
}
printf("NULL");
printf("\n");
}
///打印复杂链表
void PrintSList1(PCListNode pHead1)
{
PCListNode L = pHead1;
while (L != NULL)
{
printf("%d--->", L->data);
L = L->next;
}
printf("NULL");
printf("\n");
}


//void test2()
//{
// NODE pHead1;
// NODE pHead2;
// SListInit(&pHead1);
// SListInit(&pHead2);
// SListPushBack(&pHead1, 1);
// SListPushBack(&pHead1, 3);
// SListPushBack(&pHead1, 5);
//
// SListPushBack(&pHead2, 2);
// SListPushBack(&pHead2, 4);
// SListPushBack(&pHead2, 5);
// PrintSList(pHead1);
// PrintSList(pHead2);
//
// SListFind(&pHead1, 5)->next = SListFind(&pHead2, 5);
// if (IsCrossWithoutCircle(pHead1, pHead2))
// {
// printf("相交!!!!");
// }
// else {
// printf("不相交!!!!");
// }
// printf("%d", GetCrossNode(pHead1, pHead2)->data);
//}
void test5()
{
PCListNode pHead1;
SListInit1(&pHead1);
SListPushBack1(&pHead1, 1);
SListPushBack1(&pHead1, 2);
SListPushBack1(&pHead1, 3);
SListPushBack1(&pHead1, 4);
PrintSList1(pHead1);
SListFind1(&pHead1, 1)->random = SListFind1(&pHead1, 3);
SListFind1(&pHead1, 2)->random = SListFind1(&pHead1, 1);
SListFind1(&pHead1, 3)->random = SListFind1(&pHead1, 3);
SListFind1(&pHead1, 4)->random = NULL;
PCListNode pHead2=CopyComplexList(pHead1);
PrintSList1(pHead1);
}
int main()
{
test5();
system("pause");
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值