链表试题总结

// 倒叙打印链表
void ReversePrint(SListNode *pFirst);

// 逆置链表
SListNode * ReverseList(SListNode *pFirst);

// 删除非尾无头链表
void RemoveNodeNotTail(SListNode *pos);

// 无头链表前插入
void InsertNoHead(SListNode *pos, int data);

/*
约瑟夫环
*/
SListNode * JocephCircle(SListNode *pFirst, int k);

// 冒泡排序
void BubbleSort(SListNode *pFirst);

// 合并两个有序链表
SListNode * MergeOrderedList(SListNode *p1First, SListNode *p2First);

// 遍历一次,找到中间结点
SListNode * FindMid(SListNode *pFirst);

// 遍历一次,找到倒数第 k 个结点(k从1开始)
SListNode * FindK(SListNode *pFirst, int k);

// 遍历一次,删除倒数第 k 个结点(k从1开始),不能用替换删除法
void RemoveK(SListNode *pFirst, int k)          
引入单链表操作可见:单链表操作
#pragma once//防止头文件重定义

#include<stdio.h>
#include<Windows.h>
#include<assert.h>

typedef int DataType;

typedef struct CLinkList{
	struct CLinkList *pNext;
	struct CLinkList *pRandom;
	DataType data;
}CLinkList;

#include"sLinkList.h"
#include"ComplexLinkList.h"

//从尾到头打印单链表(不带头、无循环)
//方法1:每次遍历找出pEnd
void PrintR(SLinkListNode *pFirst)
{
	SLinkListNode *pNode, *pEnd = NULL;
	pNode = pFirst;
	while (pEnd != pFirst){
		while (pNode->pNext != pEnd){
			pNode = pNode->pNext;
		}
		pEnd = pNode;
		printf("%d -> ", pNode->data);
		pNode = pFirst;
	}
	printf("NULL\n");
}
//方法2:递归
void PrintD(SLinkListNode *pNode)
{
	if (pNode->pNext){
		PrintD(pNode->pNext);
	}
	printf("%d ", pNode->data);
}

//逆置单链表
SLinkListNode * ReverseList(SLinkListNode *pFirst)
{
	//方法1:原链表头删+新链表头插
	/*SLinkListNode *pNewFirst = NULL;
	SLinkListNode *pNode;
	pNode = pFirst;
	while (pNode){
		SLinkListPushFront(&pNewFirst, pNode->data);
		pNode = pNode->pNext;
		PopFront(&pFirst);
	}
	return pNewFirst;*/
	//方法2:三个指针遍历
	SLinkListNode *pre = NULL;
	SLinkListNode *pNode = pFirst;
	SLinkListNode *next = pNode->pNext;
	while (pNode){
		pNode->pNext = pre;
		pre = pNode;
		pNode = next;
		if (next){
			next = next->pNext;
		}
		else{
			next = NULL;
		}
	}
	return pre;
}

//删除一个无头单链表的非尾结点(不能遍历链表)
void DeleteNode(SLinkListNode *pPos)
{
	//将pPos的pNext的data赋给pPos结点的data
	//删除pPos的后一个结点
	SLinkListNode *pNode;
	pPos->data = pPos->pNext->data;
	pNode = pPos->pNext->pNext;
	free(pPos->pNext);
	pPos->pNext = pNode;
}

//在无头单链表的一个节点前插入一个节点(不能遍历链表)
void InsertNode(SLinkListNode *pPos, DataType data)
{
	//方法原理同上
	//在当前节点位置的后面插入一个节点,交换data
	SLinkListNode *pNewNode = CreatNewNode(data);
	pNewNode->data = pPos->data;
	pNewNode->pNext = pPos->pNext;
	pPos->pNext = pNewNode;
	pPos->data = data;
}

//合并两个有序链表,合并后依然有序
SLinkListNode * MergeSort(SLinkListNode *List1, SLinkListNode *List2)
{
	SLinkListNode *pNode1 = List1;
	SLinkListNode *pNode2 = List2;
	SLinkListNode *pNewFirst = NULL;

	while (pNode1 != NULL && pNode2 != NULL){
		if (pNode1->data < pNode2->data){
			SLinkListPushBack(&pNewFirst, pNode1->data);
			pNode1 = pNode1->pNext;
		}
		else if (pNode1->data > pNode2->data){
			SLinkListPushBack(&pNewFirst, pNode2->data);
			pNode2 = pNode2->pNext;
		}
		else{
			SLinkListPushBack(&pNewFirst, pNode1->data);
			pNode1 = pNode1->pNext;
		}
	}
	if (pNode1){
		while (pNode1){
			SLinkListPushBack(&pNewFirst, pNode1->data);
			pNode1 = pNode1->pNext;
		}
	}
	else{
		while (pNode2){
			SLinkListPushBack(&pNewFirst, pNode2->data);
			pNode2 = pNode2->pNext;
		}
	}
	return pNewFirst;
}

//求已排序的两个链表中相同的数据
void GetSameSet(SLinkListNode *List1, SLinkListNode *List2)
{
	if (List1 == NULL || List2 == NULL){
		printf("Null");
		return;
	}
	SLinkListNode *pNode1 = List1;
	SLinkListNode *pNode2 = List2;
	while (pNode1 && pNode2){
		if (pNode1->data == pNode2->data){
			printf("%d ", pNode1->data);
			pNode1 = pNode1->pNext;
			pNode2 = pNode2->pNext;
			continue;
		}
		else if (pNode1->data < pNode2->data){
			pNode1 = pNode1->pNext;
		}
		else{
			pNode2 = pNode2->pNext;
		}
	}
}

//单链表实现约瑟夫环
SLinkListNode * JosephCircle(SLinkListNode *pFirst, int num)
{
	//单链表形成环
	assert(pFirst);
	SLinkListNode *pNode = pFirst;
	while (pNode->pNext){
		pNode = pNode->pNext;
	}
	pNode->pNext = pFirst;

	SLinkListNode *pDNode = pFirst;
	SLinkListNode *pPreNode = pDNode;
	//根据num删除结点
	while (pPreNode->pNext != pPreNode){
		for (int i = 0; i < num; i++){
			pPreNode = pDNode;
			pDNode = pDNode->pNext;
		}
		pPreNode->pNext = pDNode->pNext;
		free(pDNode);
		pDNode = pPreNode->pNext;
	}
	return pPreNode;
}

//查找单链表的中间节点,要求只能遍历一次单链表
SLinkListNode * FindMiddle(SLinkListNode *pFirst)
{
	//快慢指针,块指针是慢指针的二倍,快指针走到末尾,慢指针就指向中间节点
	assert(pFirst);
	
	SLinkListNode *pFast = pFirst;
	SLinkListNode *pSlow = pFirst;
	while (pFast){
		pSlow = pSlow->pNext;
		pFast = pFast->pNext;
		if (!pFast){
			break;
		}
		pFast = pFast->pNext;
	}
	return pSlow;
}

//查找单链表的倒数第k个节点,要求只能遍历一次单链表
SLinkListNode * FindLastkNode(SLinkListNode *pFirst, int k)
{
	//前后指针,两个相同的指针,相隔k个节点一次遍历
	assert(pFirst);
	SLinkListNode *pPre = pFirst;
	SLinkListNode *pBack = pFirst;

	for (int i = 0; i < k; i++){
		pBack = pBack->pNext;
	}
	while (pBack){
		pPre = pPre->pNext;
		pBack = pBack->pNext;
	}
	return pPre;
}

//删除链表倒数第k个节点
SLinkListNode * DeteleLastkNode(SLinkListNode *pFirst, int k)
{
	//前后指针,记住前指针的前一个指针
	assert(pFirst);

	if (k == 1){
		PopBack(&pFirst);
	}
	else{
		SLinkListNode *pPreD = pFirst;
		SLinkListNode *pPre = pFirst;
		SLinkListNode *pBack = pFirst;

		for (int i = 0; i < k; i++){
			pBack = pBack->pNext;
		}
		while (pBack){
			pPreD = pPre;
			pPre = pPre->pNext;
			pBack = pBack->pNext;
		}
		pPreD->pNext = pPre->pNext;
		free(pPre);
	}
	return pFirst;
}

//复杂链表的复制
CLinkList * CmpLinkListCopy(CLinkList *pCFirst)
{
	/*
	1、复制节点(复制date和pNext),将新节点放在老节点的后面
	2、遍历老节点,赋值pRandom
	3、将链表拆分
	*/
	assert(pCFirst);
	CLinkList *pNode = NULL;
	CLinkList *pNewNode = NULL;
	for (pNode = pCFirst; pNode; pNode = pNode->pNext->pNext){
		pNewNode = (CLinkList *)malloc(sizeof(CLinkList));
		assert(pNewNode);
		pNewNode->data = pNode->data;
		pNewNode->pNext = pNode->pNext;
		pNewNode->pRandom = NULL;
		pNode->pNext = pNewNode;
	}

	CLinkList *oldRandom = NULL;
	for (pNode = pCFirst; pNode; pNode = pNode->pNext->pNext){
		pNewNode = pNode->pNext;
		oldRandom = pNode->pRandom;
		if (oldRandom){
			pNewNode->pRandom = oldRandom->pNext;
		}
	}

	CLinkList *pNewFirst = NULL;
	for (pNode = pCFirst; pNode; pNode = pNode->pNext->pNext){
		pNewNode = pNode->pNext;
		pNode->pNext = pNewNode->pNext;
		if (pNode->pNext != NULL){
			pNewNode->pNext = pNode->pNext->pNext;
		}
		else{
			pNewNode->pNext = NULL;
		}
	}
	return pNewNode;
}

int main()
{
	CLinkList *pCFirst = NULL;

	/*SLinkListNode *pFirst = NULL;

	SLinkListPushFront(&pFirst, 8);
	SLinkListPushFront(&pFirst, 6);
	SLinkListPushFront(&pFirst, 4);
	SLinkListPushFront(&pFirst, 2);
	SLinkListPushFront(&pFirst, 9);
	SLinkListPushFront(&pFirst, 5);
	Print(pFirst);*/

	//Print(DeteleLastkNode(pFirst, 2));

	//Print(FindLastkNode(pFirst, 3));

	//Print(FindMiddle(pFirst));

	//printf("%d\n", JosephCircle(pFirst, 4)->data);

	/*SLinkListNode *pFirst1 = NULL;

	SLinkListPushFront(&pFirst1, 7);
	SLinkListPushFront(&pFirst1, 5);
	SLinkListPushFront(&pFirst1, 4);
	SLinkListPushFront(&pFirst1, 1);
	Print(pFirst1);

	Print(MergeSort(pFirst, pFirst1));
	GetSameSet(pFirst, pFirst1);*/

	//PrintR(pFirst);
	//PrintD(pFirst);
	//Print(ReverseList(pFirst));
	
	//DeleteNode(pFirst->pNext);
	/*InsertNode(pFirst->pNext, 8);
	Print(pFirst);*/

	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/tec_1535/article/details/80862218