在这里简单实现了单链表的基本操作,重点实现单链表的各种面试题。
代码如下:
头文件LinkList.h:
#ifndef __LinkList_H__
#define __LinkList_H__
#include
#include
#include
#include
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node *next;
}Node,*pNode;
void InitList(pNode *pHead); //初始化链表
void PushBack(pNode *pHead,DataType data); //尾插
void PopBack(pNode *pHead); //尾删
void PushFront(pNode *pHead,DataType data); //头插
void PopFront(pNode *pHead); //头删
pNode Find(pNode pHead,DataType data); //查找结点位置
void Insert(pNode pos,DataType data); //在指定位置插入结点
pNode BuyNode(DataType data); //创建新结点
void DestroyList(pNode *pHead); //销毁链表
pNode Back(pNode pHead); //返回最后一个结点地址
void PrintList(pNode pHead); //打印链表
int Size(pNode pHead); //求链表中结点个数
////////////链表面试题/////////////
void PrintFromT2H(pNode pHead); //逆序打印链表
void DeleteNotTail(pNode pos); //删除无头结点非尾结点的指定位置结点
void InsertNotHead(pNode pHead,pNode pos,DataType data);//无头指针在当前结点前插入一个结点
void JosphCircle(pNode *pHead,int M); //约瑟夫环问题
pNode FindMidNode(pNode pHead); //查找中间结点返回其地址
pNode FindLastKNode(pNode pHead,int k); //查找倒数第k个结点
void ReverseList(pNode *pHead); //反转链表
void BubbleSort(pNode pHead); //冒泡排序
pNode MergeList(pNode pList1,pNode pList2); //合并两有序链表后依有序
int IsCross(pNode pHead1,pNode pHead2); //判断两链表是否相交
pNode GetCrossNode(pNode pHead1,pNode pHead2);//若两链表相交,求交点
pNode HasCircle(pNode pHead); //判断链表是否带环
int GetCircleLen(pNode pMeetNode); //求环的长度
pNode GetEnterNode(pNode pHead,pNode pMeetNode); //获取环的入口点
int IsCrossWithCircle(pNode pHead1,pNode pHead2);//判断带环链表是否相交
pNode UnionSet(pNode pHead1,pNode pHead2); //求两个已排序单链表中相同的数据打印出来
#endif __LinkList_H__
#include "LinkList.h"
void InitList(pNode *pHead) //初始化链表
{
assert(pHead);
*pHead=NULL;
}
void PushBack(pNode *pHead,DataType data) //尾插
{
assert(pHead);
if(*pHead==NULL)
{
*pHead=BuyNode(data);
}
else
{
pNode cur=*pHead;
while(cur->next!=NULL)
{
cur=cur->next;
}
cur->next=BuyNode(data);
}
}
void PopBack(pNode *pHead) //尾删
{
assert(pHead);
if(*pHead==NULL)
{
return;
}
else if((*pHead)->next==NULL)
{
free(*pHead);
*pHead=NULL;
}
else
{
pNode cur=*pHead;
pNode prev=cur;
while(cur->next)
{
prev=cur;
cur=cur->next;
}
free(cur);
cur=NULL;
prev->next=NULL;
}
}
void PushFront(pNode *pHead,DataType data) //头插
{
pNode cur=NULL;
assert(pHead);
if(*pHead==NULL)
{
*pHead=BuyNode(data);
}
else
{
cur=BuyNode(data);
cur->next=*pHead;
*pHead=cur;
}
}
void PopFront(pNode *pHead) //头删
{
assert(pHead);
if(*pHead==NULL)
{
return;
}
else if((*pHead)->next==NULL)
{
free(*pHead);
*pHead=NULL;
}
else
{
pNode cur=*pHead;
*pHead=cur->next;
free(cur);
cur=NULL;
}
}
pNode Find(pNode pHead,DataType data) //查找结点位置
{
pNode pos=NULL;
assert(pHead);
pos=pHead;
while(pos)
{
if((pos->data)==data)
{
return pos;
}
pos=pos->next;
}
return NULL;
}
void Insert(pNode pos,DataType data) //在指定位置插入结点
{
pNode cur=NULL;
if(pos==NULL)
{
return;
}
cur=BuyNode(data);
cur->next=pos->next;
pos->next=cur;
}
pNode BuyNode(DataType data) //创建新结点
{
pNode newNode=(pNode)malloc(sizeof(Node));
if(NULL==newNode)
{
printf("out of memory\n");
exit(EXIT_FAILURE);
}
newNode->data=data;
newNode->next=NULL;
return newNode;
}
void PrintList(pNode pHead) //打印链表
{
pNode cur=NULL;
assert(pHead);
cur=pHead;
while(cur)
{
printf("%d-->",cur->data);
cur=cur->next;
}
printf("\n");
}
void DestroyList(pNode *pHead) //销毁链表
{
pNode cur=*pHead;
assert(pHead);
while(cur)
{
pNode del=cur;
cur=cur->next;
free(del);
del=NULL;
}
*pHead=NULL;
}
pNode Back(pNode pHead) //返回最后一个结点地址
{
pNode cur=pHead;
pNode tail=NULL;
while(cur)
{
tail=cur;
cur=cur->next;
}
return tail;
}
void PrintFromT2H(pNode pHead) //逆序打印链表
{
pNode cur=pHead;
if(pHead!=NULL)
{
PrintFromT2H(cur->next);
printf("<--%d",cur->data);
}
}
void DeleteNotTail(pNode pos) //删除无头结点非尾结点的指定位置结点
{
pNode del=NULL;
if(pos==NULL||pos->next==NULL)
{
return;
}
del=pos->next;
pos->data=del->data;
pos->next=del->next;
free(del);
del=NULL;
}
void InsertNotHead(pNode pHead,pNode pos,DataType data) //在当前结点前插入一个结点
{
assert(pHead);
if(pos!=NULL&&pos!=pHead)
{
pNode newNode=BuyNode(data);
newNode->next=pos->next;
pos->next=newNode;
newNode->data=pos->data;
pos->data=data;
}
}
void JosphCircle(pNode *pHead,int M) //约瑟夫环问题
{
pNode curpos=*pHead;
pNode del=NULL;
while(curpos!=curpos->next)
{
int count=M;
while(--count)
{
curpos=curpos->next;
}
del=curpos->next;
curpos->next=del->next;
curpos->data=del->data;
free(del);
del=NULL;
}
*pHead=curpos;
}
pNode FindMidNode(pNode pHead) //查找中间结点返回其地址
{
pNode slow=pHead;
pNode fast=pHead;
if(pHead==NULL)
{
return;
}
while(fast!=NULL&&fast->next!=NULL)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
pNode FindLastKNode(pNode pHead,int k) //查找倒数第k个结点
{
pNode back=pHead;
pNode front=pHead;
if(pHead==NULL||k<1)
{
return;
}
while(--k)
{
front=front->next;
}
while(front->next!=NULL)
{
front=front->next;
back=back->next;
}
return back;
}
void ReverseList(pNode *pHead) //反转链表
{
pNode cur=*pHead;
pNode tmp=NULL;
pNode newHead=NULL;
if(NULL==*pHead||NULL==(*pHead)->next)
{
return;
}
while(cur)
{
tmp=cur;
cur=cur->next;
tmp->next=newHead;
newHead=tmp;
}
*pHead=newHead;
}
void BubbleSort(pNode pHead) //冒泡排序
{
pNode cur=pHead;
pNode tail=NULL;
int flag=1;
if(NULL==pHead||NULL==pHead->next)
{
return;
}
while(cur!=tail)
{
flag=1;
while(cur->next!=tail)
{
if(cur->data>cur->next->data)
{
DataType tmp=cur->data;
cur->data=cur->next->data;
cur->next->data=tmp;
flag=0;
}
cur=cur->next;
}
tail=cur;
cur=pHead;
if(flag)
{
break;
}
}
}
pNode MergeList(pNode pList1,pNode pList2) //合并两有序链表后依有序
{
pNode pNode1=pList1;
pNode pNode2=pList2;
pNode pNewNode=NULL;
pNode pTailNode=NULL;
if(pList1==NULL)
{
return pList2;
}
if(pList2==NULL)
{
return pList1;
}
if(pNode1->data < pNode2->data)
{
pNewNode=pNode1;
pNode1=pNode1->next;
}
else
{
pNewNode=pNode2;
pNode2=pNode2->next;
}
pTailNode=pNewNode;
while(pNode1!=NULL&&pNode2!=NULL)
{
if(pNode1->data < pNode2->data)
{
pTailNode->next=pNode1;
pNode1=pNode1->next;
}
else
{
pTailNode->next=pNode2;
pNode2=pNode2->next;
}
pTailNode=pTailNode->next;
}
if(pNode1==NULL)
{
pTailNode->next=pNode2;
}
if(pNode2==NULL)
{
pTailNode->next=pNode1;
}
return pNewNode;
}
int IsCross(pNode pHead1,pNode pHead2) //判断两链表是否相交
{
pNode pNode1=pHead1;
pNode pNode2=pHead2;
if(pHead1==NULL||pHead2==NULL)
{
return -1;
}
while(pNode1->next)
{
pNode1=pNode1->next;
}
while(pNode2->next)
{
pNode2=pNode2->next;
}
if(pNode1==pNode2)
{
return 1;
}
return -1;
}
pNode GetCrossNode(pNode pHead1,pNode pHead2) //若两链表相交,求交点
{
if(IsCross(pHead1,pHead2)==1)
{
pNode pNode1=pHead1;
pNode pNode2=pHead2;
int len1=0;
int len2=0;
int step=0;
len1=Size(pHead1);
len2=Size(pHead2);
step=len1-len2;
if(step>0)
{
while(step--)
{
pNode1=pNode1->next;
}
}
else
{
step=0-step;
while(step--)
{
pNode2=pNode2->next;
}
}
while(pNode1!=pNode2)
{
pNode1=pNode1->next;
pNode2=pNode2->next;
}
return pNode1;
}
else
{
return NULL;
}
}
int Size(pNode pHead) //求链表中结点个数
{
int count=0;
pNode cur=pHead;
while(cur)
{
cur=cur->next;
count++;
}
return count;
}
pNode HasCircle(pNode pHead) //判断链表是否带环
{
pNode pSlow=pHead;
pNode pFast=pHead;
assert(pHead);
while(pFast&&pFast->next)
{
pFast=pFast->next->next;
pSlow=pSlow->next;
if(pSlow==pFast)
{
return pSlow;
}
}
return NULL;
}
int GetCircleLen(pNode pMeetNode) //求环的长度
{
int count=1;
pNode pNext=pMeetNode;
if(pMeetNode==NULL)
{
return 0;
}
while(pNext->next!=pMeetNode)
{
count++;
pNext=pNext->next;
}
return count;
}
pNode GetEnterNode(pNode pHead,pNode pMeetNode) //获取环的入口点
{
pNode pSlow=pHead;
pNode pFast=pMeetNode;
assert(pHead);
if(pMeetNode==NULL)
{
return NULL;
}
while(pSlow!=pFast)
{
pSlow=pSlow->next;
pFast=pFast->next;
}
return pSlow;
}
int IsCrossWithCircle(pNode pHead1,pNode pHead2) //判断两个带环链表是否相交
{
pNode PM1=HasCircle(pHead1);
pNode PM2=HasCircle(pHead2);
if(PM1!=NULL&&PM2!=NULL)
{
pNode pNext=PM1;
if(pNext==PM2)
{
return 1;
}
pNext=pNext->next;
while(pNext!=PM1)
{
if(pNext==PM2)
{
return 1;
}
pNext=pNext->next;
}
return 0;
}
}
pNode UnionSet(pNode pHead1,pNode pHead2) //求两个已排序单链表中相同的数据打印出来
{
pNode pNode1=pHead1;
pNode pNode2=pHead2;
pNode pNewNode=NULL;
pNode pTailNode=NULL;
if(pHead1==NULL||pHead2==NULL)
{
return;
}
while(pNode1->data!=pNode2->data)
{
if(pNode1==NULL||pNode2==NULL)
{
return;
}
if(pNode1->datadata)
{
pNode1=pNode1->next;
}
else
{
pNode2=pNode2->next;
}
}
pNewNode=pNode1;
pNode1=pNode1->next;
pNode2=pNode2->next;
pTailNode=pNewNode;
while(pNode1!=NULL&&pNode2!=NULL)
{
if(pNode1->datadata)
{
pNode1=pNode1->next;
}
else if(pNode1->data>pNode2->data)
{
pNode2=pNode2->next;
}
else
{
if(pNode1->data!=pTailNode->data)
{
pTailNode->next=pNode1;
pNode1=pNode1->next;
pNode2=pNode2->next;
pTailNode=pTailNode->next;
}
else
{
pNode1=pNode1->next;
pNode2=pNode2->next;
}
}
}
if(pNode1==NULL||pNode2==NULL)
{
pTailNode->next=NULL;
}
return pNewNode;
}
#include "LinkList.h"
void test1()
{
pNode pHead;
InitList(&pHead);
PushBack(&pHead,1);
PushBack(&pHead,2);
PushBack(&pHead,3);
PushBack(&pHead,4);
PushBack(&pHead,5);
PrintList(pHead);
PopBack(&pHead);
PrintList(pHead);
PopBack(&pHead);
PrintList(pHead);
DestroyList(&pHead);
}
void test2()
{
pNode pHead;
InitList(&pHead);
PushFront(&pHead,5);
PushFront(&pHead,4);
PushFront(&pHead,3);
PushFront(&pHead,2);
PushFront(&pHead,1);
PrintList(pHead);
PopFront(&pHead);
PrintList(pHead);
PopFront(&pHead);
PrintList(pHead);
DestroyList(&pHead);
}
void test3()
{
pNode pHead;
InitList(&pHead);
PushBack(&pHead,1);
PushBack(&pHead,2);
PushBack(&pHead,3);
PushBack(&pHead,4);
PushBack(&pHead,5);
Insert(Find(pHead,3),6);
PrintList(pHead);
Insert(Find(pHead,5),7);
PrintList(pHead);
DestroyList(&pHead);
}
void test4()
{
pNode pHead;
pNode mid;
InitList(&pHead);
PushBack(&pHead,1);
PushBack(&pHead,2);
PushBack(&pHead,3);
PushBack(&pHead,4);
PrintList(pHead);
//PrintFromT2H(pHead);
InsertNotHead(pHead,Find(pHead,4),5);
PrintList(pHead);
DeleteNotTail(Find(pHead,5));
PrintList(pHead);
mid=FindMidNode(pHead);
printf("%d\n",mid->data);
DestroyList(&pHead);
}
void test5()
{
pNode pHead;
pNode tail;
InitList(&pHead);
PushBack(&pHead,1);
PushBack(&pHead,2);
PushBack(&pHead,3);
PushBack(&pHead,4);
PushBack(&pHead,5);
PushBack(&pHead,6);
PushBack(&pHead,7);
PushBack(&pHead,8);
PrintList(pHead);
tail=Back(pHead);
tail->next=pHead;
JosphCircle(&pHead,3);
pHead->next=NULL;
PrintList(pHead);
DestroyList(&pHead);
}
void test6()
{
pNode pHead;
InitList(&pHead);
PushBack(&pHead,1);
PushBack(&pHead,7);
PushBack(&pHead,4);
PushBack(&pHead,3);
PushBack(&pHead,5);
PushBack(&pHead,2);
PushBack(&pHead,8);
PushBack(&pHead,6);
PrintList(pHead);
ReverseList(&pHead);
PrintList(pHead);
BubbleSort(pHead);
PrintList(pHead);
DestroyList(&pHead);
}
void test7()
{
pNode pHead1;
pNode pHead2;
pNode pHead;
InitList(&pHead1);
InitList(&pHead2);
PushBack(&pHead1,1);
PushBack(&pHead1,3);
PushBack(&pHead1,4);
PushBack(&pHead1,7);
PrintList(pHead1);
PushBack(&pHead2,2);
PushBack(&pHead2,5);
PushBack(&pHead2,6);
PushBack(&pHead2,8);
PrintList(pHead2);
pHead=MergeList(pHead1,pHead2);
PrintList(pHead);
DestroyList(&pHead);
}
void test8()
{
pNode pHead1;
pNode pHead2;
pNode pNode1;
pNode pNode2;
pNode Node;
InitList(&pHead1);
InitList(&pHead2);
PushBack(&pHead1,1);
PushBack(&pHead1,3);
PushBack(&pHead1,4);
PushBack(&pHead1,7);
pNode1=Back(pHead1);
PushBack(&pHead2,2);
PushBack(&pHead2,5);
PushBack(&pHead2,6);
PushBack(&pHead2,8);
pNode2=Find(pHead2,6);
pNode1->next=pNode2;
PrintList(pHead1);
PrintList(pHead2);
Node=GetCrossNode(pHead1,pHead2);
PrintList(Node);
DestroyList(&pHead1);
DestroyList(&pHead2);
}
void test9()
{
pNode pHead;
pNode Node1;
pNode Node2;
pNode Node3;
InitList(&pHead);
PushBack(&pHead,1);
PushBack(&pHead,2);
PushBack(&pHead,3);
PushBack(&pHead,4);
PushBack(&pHead,5);
PushBack(&pHead,6);
PushBack(&pHead,7);
PushBack(&pHead,8);
PrintList(pHead);
Node1=Find(pHead,5);
Node2=Back(pHead);
Node2->next=Node1;
printf("%d\n",GetCircleLen(HasCircle(pHead)));
Node3=GetEnterNode(pHead,HasCircle(pHead));
printf("%d\n",Node3->data);
}
void test10()
{
pNode pHead1,pHead2;
pNode Node1,Node2,Node3,Node4;
InitList(&pHead1);
InitList(&pHead2);
PushBack(&pHead1,1);
PushBack(&pHead1,2);
PushBack(&pHead1,3);
PushBack(&pHead1,4);
PushBack(&pHead1,5);
PushBack(&pHead1,6);
PushBack(&pHead1,7);
PushBack(&pHead1,8);
PushBack(&pHead2,9);
PushBack(&pHead2,0);
PushBack(&pHead2,1);
PushBack(&pHead2,2);
PrintList(pHead1);
PrintList(pHead2);
Node1=Find(pHead1,5);
Node2=Back(pHead1);
Node3=Find(pHead1,4);
Node4=Back(pHead2);
Node2->next=Node1;
Node4->next=Node3;
printf("%d\n",IsCrossWithCircle(pHead1,pHead2));
}
void test11()
{
pNode pHead1,pHead2;
InitList(&pHead1);
InitList(&pHead2);
PushBack(&pHead1,1);
PushBack(&pHead1,3);
PushBack(&pHead1,5);
PushBack(&pHead1,7);
PushBack(&pHead1,9);
PushBack(&pHead2,2);
PushBack(&pHead2,3);
PushBack(&pHead2,3);
PushBack(&pHead2,5);
PushBack(&pHead2,8);
PushBack(&pHead2,9);
PrintList(pHead1);
PrintList(pHead2);
PrintList(UnionSet(pHead1,pHead2));
DestroyList(&pHead1);
DestroyList(&pHead2);
}
int main()
{
//test1();
//test2();
//test3();
//test4();
//test5();
//test6();
//test7();
//test8();
test9();
test10();
test11();
system("pause");
return 0;
}