单链表的面试题系列

在这里简单实现了单链表的基本操作,重点实现单链表的各种面试题。

代码如下:

头文件LinkList.h:

#ifndef __LinkList_H__
#define __LinkList_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

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__


实现文件LinkList.c:

#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->data<pNode2->data)
		{
			pNode1=pNode1->next;
		}
		else
		{
			pNode2=pNode2->next;
		}
	}
	pNewNode=pNode1;
    pNode1=pNode1->next;
	pNode2=pNode2->next;
	pTailNode=pNewNode;
	while(pNode1!=NULL&&pNode2!=NULL)
	{
		if(pNode1->data<pNode2->data)
		{
			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;
}


测试文件test.c:

#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;
}





你可能感兴趣的:(单链表的面试题系列)