关闭

C实现单链表的常见功能

431人阅读 评论(0) 收藏 举报

以下是本次实现的一些功能:

///////////////////////////////////////////////////////////////////////////////

普通功能的实现:


void InitLinkList(pList* pHead);

void Destroy(pList *pHead);

void PushBack(pList* pHead, DataType x);

void PopBack(pList* pHead);

void PushFront(pList* pHead, DataType x);

void PopFront(pList* pHead);

void PrintList(pList list);


int GetListLength(pList head);

pLinkNode Find(pList head, DataType x);

void Insert(pList *pHead, pLinkNode pos, DataType x);

void Remove(pList *pHead, DataType x);

void RemoveAll(pList *pHead, DataType x);

void Erase(pList *pHead, pLinkNode pos)

///////////////////////////////////////////////////////////////////////////////

常见的笔试问题:



//删除非尾节点-----1

void EraseNotTail(pLinkNode pos);


//反转(逆序)链表--2

void ReverseList(pList* pplist);


//排序链表(冒泡)--3

void BubbleSort(pList * pplist);


// 删除非尾结点----4

void DelNonTailNode(pLinkNode pos);


// 在当前节点前插入一个数据x-----5

void InsertFrontNode(pLinkNode pos, DataType x);


//合并两个有序列表-----6

pLinkNode Merge(pList l1, pList l2);


//查找链表的中间节点---7

pLinkNode FindMidNode(pList head);


// 删除单链表的倒数第k个节点(k > 1 && k < 链表的总长度)----9

// 时间复杂度O(N)

void DelKNode(pList *pplist, int k);


// 【链表带环问题】-----10

// 判断链表是否带环, 若链表带环则求环的长度和相遇节点,不带环返回-1

pLinkNode CheckCycle(pList pList);

int GetCircleLength(pLinkNode meet);

//FindEntryNode()

// 获取环入口点

pLinkNode GetCycleEntryNode(pList list, pLinkNode meetNode);


// 【链表相交问题】

//

// 判断两个链表是否相交,假设两个链表都不带环。

// 求环的交点,长链表先走n步(n为两链表的长度差),然后再一起走,第一个相遇点则为交点。

//

int CheckCross(pList list1, pList list2);

////////////////////////////////////////////////////////////////////////////////////////


h"
#include<stdio.h>
void test1()//初始化
{
	PlinkList pmylinklist;
	InitLinkList(&pmylinklist);

}
void test2()//打印																																																												
{
	PlinkList pmylinklist;
	InitLinkList(&pmylinklist);
	PrintLinkList(pmylinklist);
}
void test3()//尾插
{
	PlinkList pmylinklist;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PrintLinkList(pmylinklist);
}
void test4()//头插
{
	PlinkList pmylinklist;
	InitLinkList(&pmylinklist);
	PushFront(&pmylinklist, 1);
	PushFront(&pmylinklist, 2);
	PushFront(&pmylinklist, 3);
	PushFront(&pmylinklist, 4);
	PrintLinkList(pmylinklist);

}
void test5()//尾删
{
	PlinkList pmylinklist;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PopBack(&pmylinklist);
	PrintLinkList(pmylinklist);

}
void test6()//头删
{
	PlinkList pmylinklist;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PopFront(&pmylinklist);
	PrintLinkList(pmylinklist);
	PopFront(&pmylinklist);
	PrintLinkList(pmylinklist);

}
void test7()//删除链表
{
	PlinkList pmylinklist;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	Destroy(&pmylinklist);
}
void test8()
{
	PlinkList pmylinklist;
	PlinkList ret;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PushBack(&pmylinklist, 1);
	ret = Find(pmylinklist, 2);
	if (ret != NULL)
	{
		printf("找到了\n");
	}
	else
	{
		printf("没找到\n");
	}
}
void test9()//删除一个指定元素
{
	PlinkList pmylinklist;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 4);
	PushBack(&pmylinklist, 3);
	PushBack(&pmylinklist, 1);
	Remove(&pmylinklist, 4);
	PrintLinkList(pmylinklist);

}
void test10()//删除指定元素的全部
{
	PlinkList pmylinklist;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PushBack(&pmylinklist, 1);
	RemoveAll(&pmylinklist, 1);
	PrintLinkList(pmylinklist);
}
void test11()//某元素后插入节点
{
	PlinkList pmylinklist;
	PlinkNode pos;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PushBack(&pmylinklist, 4);
	pos = Find(pmylinklist, 3);
	Insert(&pmylinklist, pos, 5);
	PrintLinkList(pmylinklist);
}
void test12()//指定位置删除
{
	PlinkList pmylinklist;
	PlinkNode pos;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PushBack(&pmylinklist, 4);
	pos = Find(pmylinklist, 3);
	Erase(&pmylinklist, pos);
	PrintLinkList(pmylinklist);

	
}
void test13()//删除无头非尾部节点
{
	PlinkList pmylinklist;
	PlinkNode pos;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PushBack(&pmylinklist, 4);
	pos=Find(pmylinklist, 3);
	EraseNotTail(pos);
	PrintLinkList(pmylinklist);
}
void test14()////获取链表长度
{
	PlinkList pmylinklist;
	PlinkNode pos;
	int ret;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PushBack(&pmylinklist, 4);
	ret=GetListLength(pmylinklist);
	printf("%d\n", ret);
}
void test15()//逆序列表
{
	PlinkList pmylinklist;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PushBack(&pmylinklist, 4);
	ReverseList(&pmylinklist);
	PrintLinkList(pmylinklist);

}
void test16()//排序链表(冒泡)
{
	PlinkList pmylinklist;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PushBack(&pmylinklist, 4);
	BubbleSort(&pmylinklist);
	PrintLinkList(pmylinklist);

}
void test17()//在当前结点前插入一个数据
{
	PlinkNode pos = NULL;
	PlinkList pmylinklist;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PushBack(&pmylinklist, 4);
	pos = Find(pmylinklist, 4);
	InsertFrontNode(pos,5);
	PrintLinkList(pmylinklist);

}
void test18()//合并两个有序列表
{
	PlinkNode ret;
	PlinkList pmylinklist1;
	PlinkList pmylinklist2;
	InitLinkList(&pmylinklist1);
	PushBack(&pmylinklist1, 1);
	PushBack(&pmylinklist1, 3);
	PushBack(&pmylinklist1, 5);
	PushBack(&pmylinklist1, 7);
	InitLinkList(&pmylinklist2);
	PushBack(&pmylinklist2, 2);
	PushBack(&pmylinklist2, 4);
	PushBack(&pmylinklist2, 6);
	PushBack(&pmylinklist2, 8);
	ret=Merge(pmylinklist1, pmylinklist2);
	PrintLinkList(ret);
}
void test19()//查找链表的中间节点
{
	PlinkList pmylinklist;
	PlinkNode ret;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PushBack(&pmylinklist, 4);
	PushBack(&pmylinklist, 5);
	PushBack(&pmylinklist, 6); 
	//PushBack(&pmylinklist, 7);
	ret=FindMidNode(pmylinklist);
	printf("%d\n",ret->Data);
}
void test20()//删除链表的倒数第K个节点
{
	PlinkList pmylinklist;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PushBack(&pmylinklist, 4);
	PushBack(&pmylinklist, 5);
	PushBack(&pmylinklist, 6);
	DelKNode(&pmylinklist, 2);
	PrintLinkList(pmylinklist);

}
void test21()//判断链表是否带环
{
	PlinkList pmylinklist;
	PlinkNode pos;
	InitLinkList(&pmylinklist);
	PushBack(&pmylinklist, 2);
	PushBack(&pmylinklist, 1);
	PushBack(&pmylinklist, 3);
	PushBack(&pmylinklist, 4);
	PushBack(&pmylinklist, 5);
	PushBack(&pmylinklist, 6);
	PlinkNode start = Find(pmylinklist, 3);
	PlinkNode end = Find(pmylinklist, 6);
	end->next = start;//构建一个环
	pos=CheckCycle(pmylinklist);//快慢指针在环上的相遇点
	printf("%d\n",pos->Data);
	PlinkNode meet = pos;
	printf("%d\n",GetCycleLength(meet));//得出环的长度
	PlinkNode meetNode;
	meetNode=GetCycleEntry(pmylinklist, meet);//获取环的入口点
	printf("%d\n",meetNode->Data);
}
void test22()//判断两链表是否相交
{
	PlinkList pmylinklist1;
	PlinkList pmylinklist2;
	InitLinkList(&pmylinklist1);
	InitLinkList(&pmylinklist2);
	PushBack(&pmylinklist1, 1);
	PushBack(&pmylinklist1, 3);
	PushBack(&pmylinklist1, 5);
	PushBack(&pmylinklist1, 7);
	PushBack(&pmylinklist1, 9);
	PushBack(&pmylinklist1, 11);
	PushBack(&pmylinklist2, 2);
	PushBack(&pmylinklist2, 2);
	PushBack(&pmylinklist2, 4);
	PushBack(&pmylinklist2, 6);
	PushBack(&pmylinklist2, 8);
	PushBack(&pmylinklist2, 10);
	int ret = CheckCross(pmylinklist1, pmylinklist2);
	if (ret == 1)
	{
		printf("yes\n");
	}
	else
		printf("no\n");
}
int main()
{
	test22();
	system("pause");
	return 0;
}


/**************************************************************************/

#ifndef __LINK_LIST_H__
#define __LINK_LIST_H__
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int DataType;
typedef struct LinkNode
{
	DataType Data;
	struct LinkNode *next;
}LinkNode, *PlinkNode, *PlinkList;
/*****************************************************************/
void InitLinkList(PlinkList *phead);
void PrintLinkList(PlinkList phead);
void PushBack(PlinkList *phead, DataType x);
void PushFront(PlinkList *phead, DataType x);
void PopBack(PlinkList *phead);
void PopFront(PlinkList *phead);
void Destroy(PlinkList *phead);
void Remove(PlinkList *phead, DataType x);
PlinkNode Find(PlinkList phead, DataType x);
void RemoveAll(PlinkList *phead, DataType x);
void Insert(PlinkList *phead, PlinkNode pos, DataType x);
void Erase(PlinkList *phead, PlinkNode pos);
void EraseNotTail(PlinkNode pos);
int GetListLength(PlinkList phead);
void ReverseList(PlinkList *phead);
void BubbleSort(PlinkList *phead);
void InsertFrontNode(PlinkNode pos, DataType x);
PlinkNode Merge(PlinkList phead1, PlinkList phead2);
PlinkNode FindMidNode(PlinkList phead);
void DelKNode(PlinkList *phead, int k);
PlinkNode CheckCycle(PlinkList phead);
int GetCycleLength(PlinkNode meet);
PlinkNode GetCycleEntry(PlinkList phead, PlinkNode meet);
int CheckCross(PlinkList phead1,PlinkList phead2);

/*****************************************************************/

void InitLinkList(PlinkList *phead)//初始化
{
	*phead = NULL;
}
void PrintLinkList(PlinkList phead)//打印
{
	PlinkNode cur = phead;
	assert(phead);
	while (cur)
	{
		printf("%d ", cur->Data);
		cur = cur->next;
	}
	printf("\n");
}
void PushBack(PlinkList *phead, DataType x)//尾插
{
	PlinkNode cur = *phead;
	assert(phead);
	PlinkNode NewNode = (PlinkNode)malloc(sizeof(LinkNode));
	NewNode->Data = x;
	NewNode->next = NULL;
	if (cur == NULL)
	{
		*phead = NewNode;
		return;
	}
	while (cur->next)
	{
		cur = cur->next;
	}
	cur->next = NewNode;
}
void PushFront(PlinkList *phead, DataType x)//头插
{
	PlinkNode NewNode;
	assert(phead);
	NewNode = (PlinkNode)malloc(sizeof(LinkNode));
	NewNode->Data = x;
	NewNode->next = NULL;
	if (*phead == NULL)
	{
		*phead = NewNode;
		return;
	}
	NewNode->next = *phead;
	*phead = NewNode;
}
void PopBack(PlinkList *phead)//尾删
{
	PlinkNode cur = *phead;
	assert(phead);
	if (*phead == NULL)
	{
		return;
	}
	else if ((*phead)->next == NULL)
	{
		free(*phead);
		*phead = NULL;
	}
	else
	{
		PlinkNode del;
		while (cur->next->next)
		{
			cur = cur->next;
		}
		del = cur->next;
		cur->next = NULL;
		free(del);

	}
}
void PopFront(PlinkList *phead)//头删
{
	PlinkNode cur = *phead;
	assert(phead);
	if (*phead == NULL)
	{
		return;
	}
	else if ((*phead)->next == NULL)
	{
		free(*phead);
		*phead = NULL;
	}
	else
	{
		PlinkNode del;
		del = *phead;
		(*phead) = (*phead)->next;
		free(del);
		del = NULL;
	}
}
void Destroy(PlinkList *phead)//删除链表
{
	PlinkNode cur = *phead;
	assert(phead);
	if (*phead == NULL)
	{
		return;
	}
	else
	{
		while (cur)
		{
			PlinkNode del = cur;
			cur = cur->next;
			free(del);
		}
	}
}
PlinkNode Find(PlinkList phead, DataType x)//查找
{
	PlinkNode cur = phead;
	while (cur)
	{
		if (cur->Data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}
void Remove(PlinkList *phead, DataType x)//删除一个指定元素
{
	PlinkNode prev = NULL;
	PlinkNode del = NULL;
	PlinkNode cur = *phead;
	assert(phead);
	while (cur)
	{
		if (cur->Data == x)
		{
			del = cur;
			if (cur == *phead)
			{
				*phead = (*phead)->next;
			}
			else
			{
				prev->next = cur->next;
				del = cur;
			}
			free(del);
			del = NULL;
			break;
		}
		prev = cur;
		cur = cur->next;
	}
}
void RemoveAll(PlinkList *phead, DataType x)//删除指定元素的全部
{
	PlinkNode prev = NULL;
	PlinkNode del = NULL;
	PlinkNode cur = *phead;
	assert(phead);
	while (cur)
	{
		if (cur->Data == x)
		{
			del = cur;
			if (cur == *phead)
			{
				*phead = (*phead)->next;
				cur = (*phead)->next;
			}
			else
			{
				prev->next = cur->next;
				del = cur;
				cur = prev->next;
			}
			free(del);
			del = NULL;
		}
		else
		{
			prev = cur;
			cur = cur->next;
		}	
	}
}

void Insert(PlinkList *phead, PlinkNode pos, DataType x)//某元素后插入节点
{
	PlinkNode NewNode;
	assert(phead);
	NewNode = (PlinkNode)malloc(sizeof(LinkNode));
	NewNode->Data = x;
	NewNode->next = pos->next;
	pos->next = NewNode;
}
void Erase(PlinkList *phead, PlinkNode pos)//指定位置删除
{
	PlinkNode prev = NULL;
	PlinkNode cur=*phead;
	assert(phead);
	if (*phead == NULL)
	{
		return;
	}
	else
	{
		PlinkNode del = NULL;;
		while (cur)
		{
			if (cur == pos)
			{
				del = cur;
				prev->next = cur->next;
				break;
			}
			prev = cur;
			cur = cur->next;
		}
		free(del);
		del = NULL;
	}

}
void EraseNotTail(PlinkNode pos)//删除无头非尾节点
{
	PlinkNode del=pos->next;
	pos->Data = pos->next->Data;
	pos->next = del->next;                                                                                                                                                                                                                                                                                                                                                   
	free(del);
	del = NULL;
}
int GetListLength(PlinkList phead)//获取链表长度
{
	PlinkNode cur=phead;
	int count = 0;
	assert(phead);
	while (cur)
	{
		count++;
		cur = cur->next;
	}
	return count;
}
void ReverseList(PlinkList *phead)//反转,逆序列表(头摘头插法)
{
	PlinkNode cur = *phead;
	PlinkNode prev = NULL;
	PlinkList pNewhead = NULL;
	assert(*phead);
	while (cur)
	{
		prev = cur;
		cur = cur->next;
		prev->next = pNewhead;
		pNewhead = prev;
	}
	*phead = pNewhead;
}
void BubbleSort(PlinkList *phead)//排序链表(冒泡)
{
	PlinkNode cur = *phead;
	PlinkNode end = NULL;
	assert(*phead);
	while (cur!=end)
	{
		while (cur&&(cur->next!=end))
		{
			if (cur->Data > cur->next->Data)
			{
				DataType tmp;
				tmp = cur->Data;
				cur->Data = cur->next->Data;
				cur->next->Data = tmp;
			}
			cur = cur->next;
		}
		end = cur;
		cur = *phead;	
	}
}
void InsertFrontNode(PlinkNode pos, DataType x)//在当前节点前插入一个数据
{
	PlinkNode NewNode;//现在该节点后插入然后再将节点内的两数交换
	assert(pos);
	NewNode = (PlinkNode)malloc(sizeof(LinkNode));
	NewNode->Data = x;
	NewNode->next = pos->next;
	pos->next = NewNode;
	DataType tmp;
	tmp = pos->Data;
	pos->Data=NewNode->Data;
	NewNode->Data = tmp;
}
PlinkNode Merge(PlinkList phead1, PlinkList phead2)//合并两个有序列表
{
	PlinkNode cur1 = phead1;
	PlinkNode cur2 = phead2;
	PlinkList  Newhead = NULL;
	assert(phead1);
	assert(phead2);
	if (cur1 == cur2)
	{
		return cur1;
	}
	else if (cur1 == NULL)
	{
		return cur2;
	}
	else if (cur2 == NULL)
	{
		return cur1;
	}
	else
	{
		PlinkNode cur = NULL;
		
		if (cur1->Data > cur2->Data)
		{
			Newhead = cur2;
			cur2 = cur2->next;
		}
		else if (cur1->Data <= cur2->Data)
		{
			Newhead = cur1;
			cur1 = cur1->next;
		}
		cur = Newhead;
		while (cur1&&cur2)
		{
			if (cur1->Data > cur2->Data)
			{
				cur->next = cur2;
				cur2 = cur2->next;
			}
			else
			{
				cur -> next = cur1;
				cur1 = cur1->next;
			}
			cur = cur->next;
		}
		if (cur1)
		{
			cur->next = cur1;
		}
		if (cur2)
		{
			cur->next = cur2;
		}
	}
	return Newhead;
}
PlinkNode FindMidNode(PlinkList phead)//查找中间节点(快慢指针法)
{
	PlinkNode Fast = phead;
	PlinkNode Slow = phead;
	while (Fast&&Fast->next)
	{
		Fast = Fast->next->next;
		Slow = Slow->next;
	}
	return Slow;
}
void DelKNode(PlinkList *phead, int k)//删除链表的倒数第K个节点(快慢指针法)
{
	PlinkNode Fast = *phead;
	PlinkNode Slow = *phead;
	assert(*phead);
	while (--k)
	{
		Fast = Fast->next;
	}
	while (Fast->next)
	{
		Fast = Fast->next;
		Slow = Slow->next;
	}
	PlinkNode del=Slow->next;
	Slow->Data = del->Data;
	Slow->next = del->next;
	free(del);
	del = NULL;
}
PlinkNode CheckCycle(PlinkList phead)//判断链表是否带环(快慢指针法)
{
	PlinkNode Fast = phead;
	PlinkNode Slow = phead;
	while (Fast->next)
	{
		Fast = Fast->next->next;
		Slow = Slow->next;
		if (Slow == Fast)
		{
			return Slow;
		}
	}
}
int GetCycleLength(PlinkNode meet)//求取环的长度
{
	PlinkNode start= meet;
	int count = 0;
	assert(meet);
	do
	{
		start = start->next;
		count++;
	} while (start != meet);
	return count;
}
PlinkNode GetCycleEntry(PlinkList phead, PlinkNode meet)//获取环的入口点
{
	PlinkNode start = phead;
	PlinkNode end=meet;
	assert(phead);
	while (start !=end)
	{
		start = start->next;
		end = end->next;
	}
	return end;
}
int CheckCross(PlinkList phead1, PlinkList phead2)//判断两链表是否相交(如果相交则最后一个节点相同)
{
	if (phead1 || phead2)
	{
		return 0;
	}
	else
	{
		while (phead1)
		{
			phead1 = phead1->next;
		}
		while (phead2)
		{
			phead2 = phead2->next;
		}
		if (phead1 == phead2)
		{
			return 1;
		}
		else
		{
			return 0;
		}
	}
}
#endif  //__LINK_LIST_H__






本文出自 “anser” 博客,请务必保留此出处http://674353165.blog.51cto.com/10786549/1738411

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:15512次
    • 积分:330
    • 等级:
    • 排名:千里之外
    • 原创:32篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类