链表的面试题

SList.h
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

typedef int DataType;
typedef struct ListNode
{
	struct ListNode* pNext;//指向链表中下一个结点
	 DataType data;//当前结点所保存的元素
}Node,*PNode;

//生成一个新结点
PNode BuySListNode(DataType data);

//打印链表
void PrintSList(PNode PHead);

//尾插
void SListPushBack(PNode* pHead, DataType data);
PNode SListFind(PNode pHead, DataType data);

// 逆序打印单链表 
void PrintSListFromTail2Head(PNode pHead); 

// 删除链表的非尾结点,要求:不能遍历链表 
void DeleteListNotTailNode(PNode pos); 

// 在链表pos位置前插入值到data的结点 
void InesrtPosFront(PNode pos, DataType data); 

// 查找链表的中间结点,要求只能遍历一次链表 
PNode FindMiddleNode(PNode pHead); 

// 查找链表的倒数第K个结点,要求只能遍历一次链表 
PNode FindLastKNode(PNode pHead, int K); 

// 删除链表的倒数第K个结点,要求只能遍历一次链表 
void DeleteLastKNode(PNode pHead, int K); 

// 用单链表实现约瑟夫环 
void JosephCircle(PNode* pHead, const int M); 

// 链表的逆置--三个指针 
void ReverseSList(PNode* pHead); 

// 链表的逆置--头插法 
PNode ReverseSListOP(PNode pHead); 

// 用冒泡排序思想对单链表进行排序 
void BubbleSort(PNode pHead); 

// 合并两个有序单链表,合并后依然有序 
PNode MergeSList(PNode pHead1, PNode pHead2); 

// 判断两个单链表是否相交---链表不带环 
int IsSListCross(PNode pHead1, PNode pHead2); 

// 求两个单链表相交的交点---链表不带环 
PNode GetCorssNode(PNode pHead1, PNode pHead2); 

//////////////////////////////////
//测试
void testPrintSListFromTail2Head();
void testDeleteListNotTailNode();
void testInesrtPosFront();
void testFindMiddleNode();
void testFindLastKNodeAndDeleteLastKNode();
void testJosephCircleAndReverseSList();
void testMergeSListAndGetCorssNode();

SList.c
#include "SList.h"

void PrintSList(PNode pHead)
{
	PNode pCur=pHead;
	if(pHead==NULL)
	{
		printf("链表为空\n");
		return ;
	}
	while(pCur)
	{
		printf("%d->",pCur->data);
		pCur=pCur->pNext ;
	}
	printf("NULL\n");
}

void SListInit(PNode* pHead)
{
	assert(pHead);
	*pHead=NULL;
}

PNode BuySListNode(DataType data)
{
	PNode pNewNode=(PNode)malloc(sizeof(Node));	
	if(pNewNode==NULL)
	{
		assert(0);
		return NULL;
	}

	pNewNode->data =data;
	pNewNode->pNext =NULL;

	return pNewNode;
}

void SListPushBack(PNode* pHead, DataType data)
{
	PNode pCur=*pHead;

	assert(pHead);
	//链表为空
	if(*pHead==NULL)
	{
		*pHead=BuySListNode(data);
	}
	//链表中有结点
	else 
	{
		while(pCur->pNext)
		{
			pCur=pCur->pNext;
		}
		pCur->pNext =BuySListNode(data);
	}
}


PNode SListFind(PNode pHead, DataType data)
{
	if(pHead==NULL)
	{
		printf("链表为空\n");
		return NULL;
	}
	while(pHead)
	{
		if(pHead->data ==data)
		{
			return pHead;
		}
		pHead=pHead->pNext ;
	}
	return NULL;
}

void PrintSListFromTail2Head(PNode pHead)
{
	PNode ptail=NULL;
	PNode pcur=pHead;
	PNode ppre=NULL;

	if(pHead==NULL)
	{
		return;
	}
	while(pcur)
	{
		ptail=pcur;
		pcur=pcur->pNext ;
	}
	while(ptail!=pHead)
	{
		pcur=pHead;
		while(pcur!=ptail)
		{
			ppre=pcur;
			pcur=pcur->pNext ;
		}
		printf("%d->",ptail->data );
		ptail=ppre;
	}
	printf("%d->NULL",pHead->data );
}

void DeleteListNotTailNode(PNode pos)
{
	PNode next=NULL;
	next =pos->pNext ;
	pos->data =next->data ;
	pos->pNext =next->pNext ;
	free(next);
	next=NULL;
}

void InesrtPosFront(PNode pos, DataType data)
{
	PNode newNode=BuySListNode(data);
	int tmp=0;
	if(pos==NULL)
		return;
	newNode->pNext =pos->pNext ;
	pos->pNext =newNode;
	newNode->data =pos->data ;
	pos->data =data;
}

//如果节点数为偶数返回的是中间数的后一个
PNode FindMiddleNode(PNode pHead)
{
	PNode fast=pHead;
	PNode slow=pHead;
	 if(pHead==NULL)
	 {
		 return NULL;
	 }
	 else if(pHead->pNext==NULL )
	 {
		 return pHead;
	 }
	 else
	 {
		while(fast && fast->pNext)
		{
			fast=fast->pNext ->pNext ;
			slow=slow->pNext ;
		}
	 }
	return slow;
}

PNode FindLastKNode(PNode pHead, int K)
{
	PNode fast=pHead;
	PNode slow=pHead;
	if(pHead==NULL || K<=0)
	{
		return NULL;
	}
	while(K--)
	{
		fast=fast->pNext ;
	}
	while(fast)
	{
		fast=fast->pNext ;
		slow=slow->pNext ;
	}
	return slow;
}

void DeleteLastKNode(PNode pHead, int K)
{
	PNode fast=pHead;
	PNode slow=pHead;
	PNode pre=NULL;
	if(pHead==NULL || K<=0)
	{
		return ;
	}
	while(K--)
	{
		fast=fast->pNext ;
	}
	while(fast)
	{
		fast=fast->pNext ;
		pre=slow;
		slow=slow->pNext ;
	}
	pre->pNext =slow->pNext ;
	free(slow);
	slow=NULL;
}

void JosephCircle(PNode* pHead, const int M)
{
	PNode pcur=*pHead;
	assert(pHead);
	if(*pHead==NULL || M<=0)
	{
		return;
	}
	//先遍历链表,让尾指向头
	while(pcur->pNext )
	{
		pcur=pcur->pNext ;
	}

	pcur->pNext =*pHead;
	pcur=*pHead;
	//环内只剩一个元素时停止
	while((pcur->pNext) !=pcur)
	{
		int count=M;
		PNode del=NULL;
		while(--count)
		{
			pcur=pcur->pNext ;
		}
		//删除节点
		del=pcur->pNext ;
		pcur->data =del->data ;
		pcur->pNext =del->pNext ;
		free(del);
		del=NULL;
	}
	//解环
	pcur->pNext =NULL;
	printf("%d\n",pcur->data );
}

void ReverseSList(PNode* pHead)
{
	PNode pcur=NULL;
	PNode pre=NULL;
	PNode next=NULL;
	assert(*pHead);
	if(*pHead==NULL)
	{
		return;
	}
	pcur=*pHead;
	while(pcur)
	{
		next=pcur->pNext ;
		pcur->pNext =pre;
		pre=pcur;
		pcur=next;
	}
	*pHead=pre;
}

PNode ReverseSListOP(PNode pHead)
{
	PNode pcur=pHead;
	PNode newNode=NULL;
	if(pHead==NULL)
	{
		return NULL;
	}

	while(pHead)
	{
		pcur=pHead;
		pHead=pcur->pNext ;
		pcur->pNext =newNode;
		newNode=pcur;
	}
	pHead=pcur;
	return pHead;
}

void BubbleSort(PNode pHead)
{
	PNode pcur=pHead;
	PNode ptail=NULL;
	
	if(pHead==NULL ||pHead->pNext ==NULL )
		return;
	while(pHead!=ptail)
	{
		int flag=0;
		pcur=pHead;
		while(pcur->pNext!=ptail)
		{
			if((pcur->data) > (pcur->pNext ->data) )
			{
				int tmp=pcur->data ;
				pcur->data =pcur->pNext ->data ;
				pcur->pNext ->data =tmp;
				flag=1;
			}
			pcur=pcur->pNext ;
		}
		ptail=pcur;
		if(flag==0)
			break;
	}
	PrintSList(pHead);
}

PNode MergeSList(PNode pHead1, PNode pHead2)
{
	PNode pcur=NULL;
	PNode newNode=NULL;
	if(pHead1==NULL)
		return pHead2;
	if(pHead2==NULL)
		return pHead1;
	//找出newNode节点
	if(pHead1->data >=pHead2->data )
	{
		newNode=BuySListNode(pHead2->data);
		pHead2=pHead2->pNext ;
		pcur=newNode;
	}
	else if(pHead1->data <pHead2->data)
	{
		newNode=BuySListNode(pHead1->data);
		pHead1=pHead1->pNext ;
		pcur=newNode;
	}

	while(pHead1&&pHead2)
	{
		if(pHead1->data >=pHead2->data )
		{
			pcur->pNext =BuySListNode(pHead2->data);
			pHead2=pHead2->pNext ;
			pcur=pcur->pNext ;
		}
		else if((pHead1->data )<(pHead2->data))
		{
			pcur->pNext =BuySListNode(pHead1->data);
			pHead1=pHead1->pNext ;
			pcur=pcur->pNext ;
		}
	}
	while(pHead1)//判断pHead1节点是否为空,如若不空则继续
	{
		pcur->pNext =BuySListNode(pHead1->data);
		pHead1=pHead1->pNext ;
		pcur=pcur->pNext ;
	}
	while(pHead2)
	{
		pcur->pNext =BuySListNode(pHead2->data);
		pHead2=pHead2->pNext ;
		pcur=pcur->pNext ;
	}
	PrintSList(newNode);
	return newNode;
}

int IsSListCross(PNode pHead1, PNode pHead2)
{
	if(pHead1==NULL || pHead2==NULL)
	{
		return 0;
	}
	//找到链表的最后一个结点
	while(pHead1->pNext )
	{
		pHead1=pHead1->pNext ;
	}
	while(pHead2->pNext )
	{
		pHead2=pHead2->pNext ;
	}
	if(pHead1 ==pHead2 )
		return 1;
	return 0;
}

PNode GetCorssNode(PNode pHead1, PNode pHead2)
{
	int size1=0;
	int size2=0;
	int gap=0;
	PNode pcur1=pHead1;
	PNode pcur2=pHead2;
	if(pHead1==NULL || pHead2==NULL)
	{
		return NULL;
	}
	while(pcur1)
	{
		size1++;
		pcur1=pcur1->pNext ;
	}
	while(pcur2)
	{
		size2++;
		pcur2=pcur2->pNext ;
	}
	pcur1=pHead1;
	pcur2=pHead2;
	gap=size1-size2;
	if(gap>0)
	{
		while(gap--)
		{
			pcur1=pcur1->pNext ;
		}
	}
	else
	{
		while(gap++)
		{
			pcur2=pcur2->pNext ;
		}
	}
	while(pcur2!=pcur1)
	{
		pcur1=pcur1->pNext ;
		pcur2=pcur2->pNext ;
	}
	return pcur1;
}
//////////////////////////////////
//测试
void testPrintSListFromTail2Head()
{
	PNode pHead;
	SListInit(&pHead);
	SListPushBack(&pHead,1);
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,4);
	PrintSList(pHead);
	PrintSListFromTail2Head(pHead);
}

void testDeleteListNotTailNode()
{
	PNode pHead,pcur;
	SListInit(&pHead);
	SListPushBack(&pHead,1);
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,4);
	PrintSList(pHead);
	pcur=SListFind(pHead,2);
	DeleteListNotTailNode(pcur);
	PrintSList(pHead);
}

void testInesrtPosFront()
{
	PNode pHead,pcur;
	SListInit(&pHead);
	SListPushBack(&pHead,1);
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,4);
	PrintSList(pHead);
	pcur=SListFind(pHead,2);
	InesrtPosFront(pcur,6);
	PrintSList(pHead);
}

void testFindMiddleNode()
{
	PNode pHead,pcur;
	SListInit(&pHead);
	SListPushBack(&pHead,1);
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,4);
	SListPushBack(&pHead,5);
	PrintSList(pHead);
	pcur=FindMiddleNode(pHead);
	printf("%d \n",pcur->data);
}

void testFindLastKNodeAndDeleteLastKNode()
{
	PNode pHead,pcur;
	SListInit(&pHead);
	SListPushBack(&pHead,1);
	SListPushBack(&pHead,2);
	SListPushBack(&pHead,3);
	SListPushBack(&pHead,4);
	SListPushBack(&pHead,5);
	PrintSList(pHead);
	/*pcur=FindLastKNode(pHead,2);
	printf("%d\n",pcur->data);*/
    DeleteLastKNode(pHead,3);
	PrintSList(pHead);
}

void testJosephCircleAndReverseSList()
{
	PNode pHead,pcur;
	SListInit(&pHead);
	SListPushBack(&pHead,1);
	SListPushBack(&pHead,8);
	SListPushBack(&pHead,6);
	SListPushBack(&pHead,4);
	SListPushBack(&pHead,9);
	SListPushBack(&pHead,7);
	PrintSList(pHead);
	//JosephCircle(&pHead,3);
	//ReverseSList(&pHead);
	//PrintSList(pHead);
	//pcur=ReverseSListOP(pHead);
	//PrintSList(pcur);
	BubbleSort(pHead);
}

void testMergeSListAndGetCorssNode()
{
	PNode pHead1,pHead2,pcur;
	SListInit(&pHead1);
	SListInit(&pHead2);
	SListPushBack(&pHead1,1);
	SListPushBack(&pHead1,3);
	SListPushBack(&pHead1,5);
	SListPushBack(&pHead1,7);
	SListPushBack(&pHead1,9);
	PrintSList(pHead1);
	SListPushBack(&pHead2,2);
	SListPushBack(&pHead2,4);
	//MergeSList(pHead1,pHead2);
	pHead2->pNext ->pNext =SListFind(pHead1,5);
	PrintSList(pHead2);
	pcur=GetCorssNode(pHead1,pHead2);
	printf("%d\n",pcur->data );
}

test.c
#include "SList.h"

int main()
{
	//testPrintSListFromTail2Head();
	//testDeleteListNotTailNode();
	//testInesrtPosFront();
	//testFindMiddleNode();
	//testFindLastKNodeAndDeleteLastKNode();
	//testJosephCircleAndReverseSList();
	testMergeSListAndGetCorssNode();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/lw__sunshine/article/details/80262473