单链表全集简化

头文件:

#ifndef __LINKLIST_H__
#define __LINKLIST_H__


#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <malloc.h>

typedef int DataType;

typedef struct Node
{
	DataType _data;
	struct Node* _next;
}Node,*pNode,*pList;



void InitLinkList(pList* pplist);//初始化
void DestroyList(pList* pplist);//销毁单链表
void Display(pList plist);//遍历单链表

void PushBack(pList* pplist, DataType x);//尾插
void PopBack(pList* pplist);//尾删

void PushFront(pList* pplist, DataType x);//头插
void PopFront(pList* pplist);//头删

pNode Find(pList plist, DataType x);//查找元素的位置

void Insert(pList* pplist, pNode pos, DataType x);//指定位置插入
void Erase(pList* pplist, pNode pos);//指定位置删除

void Remove(pList* pplist, DataType x);//删除指定的元素
void RemoveAll(pList* pplist, DataType x);//删除指定元素的所有

void Sort(pList* pplist);//单向链表的排序

void ReversePrint(pList plist);//逆序打印单链表
void EraseNotTail(pNode pos);//删除无头单链表非尾结点

void InsertFrontNode(pNode pos, DataType x);//在无头单链表的非头结点前插入一个元素 

void JosephCycle(pList* pplist, int k);//约瑟夫环问题 

void ReverseList(pList* pplist); //逆序单向链表 

pList Merge(pList* p1, pList* p2); //合并两个有序链表 
pList Merge(const pList* p1, const pList* p2); //递归完成两个有序链表的合并

pNode FindMidNode(pList plist); //查找单链表的中间节点,要求只能遍历一次链表 
pNode FindKNode(pList plist, int k);//查找单链表的倒数第k个节点,要求只能遍历一次链表 

pNode CheckCircle(pList plist);//判断链表是否带环
int GetCircleLength(pNode meet);//求环的长度 

pNode GetCycleEntryNode(pList plist, pNode meet);//求环的入口点 

int CheckCross(pList list1, pList list2); //判断两条单向链表是否相交 

pNode GetCrossNode(pList list1, pList list2);//求两条链表相交的交点 


#endif



程序实现文件:

#include "linklist.h"

void InitLinkList(pList* pplist)
{
	assert(pplist);
	*pplist = NULL;
}


void DestroyList(pList* pplist)
{
	pNode cur = NULL;
	pNode del = NULL;
	assert(pplist);
	cur = *pplist;
	while(cur)
	{
		del = cur;
		cur = cur->_next;
		free(del);
	}
	free(cur);
	*pplist = NULL;
}



void PushBack(pList* pplist, DataType x)
{
	pNode cur = NULL;
	pNode newnode = NULL;
	assert(pplist);
	cur = *pplist;
	newnode = (pNode)malloc(sizeof(Node));
	newnode->_data = x;
	newnode->_next = NULL;
	if(*pplist == NULL)
	{
		*pplist = newnode;
		return;
	}
	while(cur->_next)
	{
		cur = cur->_next;
	}
	cur->_next = newnode;
}


void PopBack(pList* pplist)
{
	pNode cur = NULL;
	assert(pplist);
	cur = *pplist;
	if(*pplist == NULL)
	{
		return;
	}
	if(cur->_next == NULL)
	{
		free(cur);
		*pplist = NULL;
		return;
	}
	while(cur->_next->_next)
	{
		cur = cur->_next;
	}
	free(cur->_next);
	cur->_next = NULL;
}


void PushFront(pList* pplist, DataType x)
{
	pNode cur = NULL;
	pNode newnode = NULL;
	assert(pplist);
	cur = *pplist;
	newnode = (pNode)malloc(sizeof(Node));
	newnode->_data = x;
	newnode->_next = NULL;
	if(*pplist == NULL)
	{
		*pplist = newnode;
		return;
	}
	else
	{
		newnode->_next = cur;
		*pplist = newnode;
	}

}	


void PopFront(pList* pplist)
{
	pNode cur = NULL;
	pNode del = NULL;
	assert(pplist);
	cur = *pplist;
	if(*pplist == NULL)
	{
		return;
	}
	if(cur->_next == NULL)
	{
		free(cur);
		*pplist = NULL;
		return;
	}
	del = cur;
	cur = cur->_next;
	free(del);
	*pplist = cur;
}


pNode Find(pList plist, DataType x)
{
	pNode pos = plist;
	while(pos)
	{
		if(pos->_data == x)
		{
			return pos;
		}
		pos = pos->_next;
	}
	return NULL;
}


void Insert(pList* pplist, pNode pos, DataType x)
{
	pNode cur = NULL;
	pNode newnode = NULL;
	assert(pplist);
	cur = *pplist;
	newnode = (pNode)malloc(sizeof(Node));
	newnode->_data = x;
	newnode->_next = NULL;
	if(*pplist == NULL)
	{
		*pplist = newnode;
		return;
	}
	if(pos == *pplist)
	{
		*pplist = newnode;
		newnode->_next = cur;
		return;
	}
	while(cur->_next != pos)
	{
		cur = cur->_next;
	}
	newnode->_next = pos;
	cur->_next = newnode;
}


void Erase(pList* pplist, pNode pos)
{
	pNode cur = NULL;
	assert(pplist);
	cur = *pplist;
	if(*pplist == NULL)
	{
		return;
	}
	if((pos == *pplist))
	{
		pNode del = pos;
		*pplist = pos->_next;
		free(del);
		return;
	}
	while((cur->_next != pos)&&cur)
	{
		cur = cur->_next;
	}
	cur->_next = pos->_next ;
	free(pos);
}



void Remove(pList* pplist, DataType x)
{
	pNode pos = NULL;
	assert(pplist);
	pos = Find(*pplist,x);
	Erase(pplist, pos);

}


void RemoveAll(pList* pplist, DataType x)
{
	pNode cur = NULL;//第一个节点
	pNode dec = NULL;//指向第一个节点前的一个节点
	assert(pplist);
	cur = *pplist;
	while(cur)//当链表还有之时
	{
		if(cur->_data == x)//如果当前指向接点的数据等于x
		{
			pNode del = cur;//设置一个删除节点
			if(cur == *pplist)//如果要删除的是第一个节点
			{
				*pplist = cur->_next;//后一个节点为整个单链表的起始位置
			}
			else
			{
				dec->_next = cur->_next;//如果不是单链表的第一个节点,执行正常的删除操作
			}
			cur = cur->_next;
			free(del);
		}
		else
		{
			dec = cur;
			cur = cur->_next;
		}
	}
}



void Sort(pList* pplist)
{
	pNode cur = NULL;//指向第一个节点
	pNode dec = NULL;//指向cur节点的后一个节点
	assert(pplist);
	cur = *pplist;
	for(; cur; cur = cur->_next)//冒泡排序
	{
		for(dec = cur->_next; dec; dec = dec->_next)
		{
			if(cur->_data > dec->_data)
			{	
				DataType tmp;
				tmp = cur->_data;
				cur->_data = dec->_data;
				dec->_data = tmp;
			}
		}
	}
}





void Display(pList plist)
{
	pNode cur = plist;
	while(cur)
	{
		printf("%d->",cur->_data);
		cur = cur->_next;
	}
	printf("NULL\n");
}




void ReversePrint(pList plist)
{
	pNode cur = plist;
	if(cur == NULL)
	{
		return;
	}
	if(cur->_next != NULL)
	{
		ReversePrint(cur->_next);
	}
	printf("%d ",cur->_data);
}




void EraseNotTail(pNode pos)
{
	pNode del = NULL; 
	assert(pos);
	assert(pos->_next != NULL);
	del = pos->_next;
	pos->_data = del->_data;
	pos->_next = del->_next;
	free(del);
	del = NULL;
}




void InsertFrontNode(pNode pos, DataType x)
{
	pNode newnode = NULL;
	DataType tmp = NULL;
	assert(pos);
	newnode = (pNode)malloc(sizeof(Node));
	newnode->_data = x;
	newnode->_next = NULL;
	newnode->_next = pos->_next;
	pos->_next = newnode;
	tmp = pos->_data;
	pos->_data = newnode->_data;
	newnode->_data = tmp;
}



void JosephCycle(pList* pplist, int k)
{
	pNode cur = NULL;
	pNode del = NULL;
	int i = 0;
	assert(pplist);
	cur = *pplist;
	while(cur->_next != cur)
	{
		del = cur;
		for(i=0; i<k-1; i++)
		{
			del = del->_next;
		}
		printf("%d ",del->_data);
		cur->_next->_next = del->_next;
		cur = cur->_next->_next;
		free(del);
		del = NULL;
	}
	printf("%d\n",cur->_data);
}






void ReverseList(pList* pplist)
{
	pNode cur = NULL;
	pNode dec = NULL;
	assert(pplist);
	cur = *pplist;
	for(; cur; cur = cur->_next)
	{
		for(dec = cur->_next; dec; dec = dec->_next)
		{
			DataType tmp;
			tmp = cur->_data;
			cur->_data = dec->_data;
			dec->_data = tmp;
		}
	}
}







pList Merge(const pList* p1, const pList* p2)
{
	pList l1 = NULL;
	pList l2 = NULL;
	pList newplist = NULL;
	assert(p1);
	assert(p2);
	l1 = *p1;
	l2 = *p2;
	if(NULL == l1)
	{
		return l2;
	}
	if(NULL == l2)
	{
		return l1;
	}
	if(l1->_data < l2->_data)
	{
		newplist = l1;
		newplist->_next = Merge(&(l1->_next), &l2);
	}
	else
	{
		newplist = l2;
		newplist->_next = Merge(&l1, &(l2->_next));
	}
	return newplist;
}





pNode FindMidNode(pList plist)
{
	pNode fast = NULL;
	pNode slow = NULL;
	if(plist == NULL)
	{
		return NULL;
	}
	slow = plist;
	fast = plist;
	while(fast&&(fast->_next))
	{
		slow = slow->_next;
		fast = fast->_next->_next;
	}
	return slow;
}


pNode FindKNode(pList plist, int k)
{
	pNode fast = NULL;
	pNode slow = NULL;
	int i = 0;
	if(plist == NULL)
	{
		return NULL;
	}
	slow = plist;
	fast = plist;
	for(i=0; i<k-1; i++)
	{
		if((fast->_next) == NULL)
		{
			return NULL;
		}
		fast = fast->_next;
	}
	while(fast->_next)
	{
		slow = slow->_next;
		fast = fast->_next;
	}
	return slow;
}




pNode CheckCircle(pList plist)
{
	pNode fast = NULL;
	pNode slow = NULL;
	int i = 0;
	if(plist == NULL)
	{
		return NULL;
	}
	slow = plist;
	fast = plist;
	/*slow = plist;
	fast = slow->_next;
	if(fast == NULL)
	{
		return NULL;
	}*/
	while(/*(slow != fast)&&*/(fast)&&(fast->_next))
	{
		slow = slow->_next;
		fast = fast->_next->_next;
		if(fast == slow)
		{
			return slow;
		}
	}
	return NULL;
}





int GetCircleLength(pNode meet)
{
	pNode cur = NULL;
	int i = 1;
	cur = meet->_next;
	while(cur != meet)
	{
		cur = cur->_next;
		i++;
	}
	return i;
}


pNode GetCycleEntryNode(pList plist, pNode meet)
{
	pNode pos = meet;
	pNode cur = plist;
	while(pos != cur)
	{
		pos = pos->_next;
		cur = cur->_next;
	}
	return pos;
}





int CheckCross(pList list1, pList list2)
{
	pList l1 = list1;
	pList l2 = list2;
	if((l1 == NULL) || (l2 == NULL))
	{
		return 0;
	}
	while(l1->_next)
	{
		l1 = l1->_next;
	}
	while(l2->_next)
	{
		l2 = l2->_next;
	}
	if(l1 == l2)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}



pNode GetCrossNode(pList list1, pList list2)
{
	pList l1 = list1;
	pList l2 = list2;
	if((l1 == NULL)||(l2 == NULL))
	{
		return NULL;
	}
	while(l1)
	{
		pNode cur = l2;
		while(cur)
		{
			if((l1 == cur)&&(cur))
			{
				return l1;
			}
			cur = cur->_next;
		}
		l1 = l1->_next;
	}
	return NULL;
}

简单测试:

#include "linklist.h"

void test()
{
	pNode plist;
	InitLinkList(&plist);
	PushBack(&plist, 1);
	PushBack(&plist, 2);
	PushBack(&plist, 3);
	PushBack(&plist, 4);
	Display(plist);//尾插输入1234
	PopBack(&plist);
	Display(plist);//尾删一个
	PopBack(&plist);
	Display(plist);//尾删一个
	PopBack(&plist);
	Display(plist);//尾删一个
	PopBack(&plist);
	Display(plist);//尾删一个
	PopBack(&plist);
	Display(plist);//尾删一个
	DestroyList(&plist);
	Display(plist);
}


void test1()
{
	pNode plist;
	InitLinkList(&plist);
	PushFront(&plist, 1);
	PushFront(&plist, 2);
	PushFront(&plist, 3);
	PushFront(&plist, 4);
	Display(plist);//头插输入1234
	PopFront(&plist);
	Display(plist);//头删一个
	PopFront(&plist);
	Display(plist);//头删一个
	PopFront(&plist);
	Display(plist);//头删一个
	PopFront(&plist);
	Display(plist);//头删一个
	PopFront(&plist);
	Display(plist);//头删一个
	DestroyList(&plist);
	Display(plist);
}

void test2()
{
	pNode plist;
	pNode pos = NULL;
	InitLinkList(&plist);
	PushFront(&plist, 1);
	PushFront(&plist, 2);
	PushFront(&plist, 3);
	PushFront(&plist, 4);
	Display(plist);
	pos = Find(plist, 3);//找到3的位置
	printf("%d\n",pos->_data);
	Insert(&plist, pos, 5);//在3元素的位置处插入元素5
	Display(plist);
	Erase(&plist, pos);//删除3元素位置处的元素
	Display(plist);
	Remove(&plist, 5);//删除元素5
	Display(plist);
	DestroyList(&plist);
	Display(plist);
}




void test3()
{
	pNode plist;
	InitLinkList(&plist);
	PushFront(&plist, 3);
	PushFront(&plist, 1);
	PushFront(&plist, 3);
	PushFront(&plist, 2);
	PushFront(&plist, 3);
	PushFront(&plist, 4);
	PushFront(&plist, 3);
	Display(plist);
	RemoveAll(&plist, 3);//删除指定的所有相同的元素
	Display(plist);
	DestroyList(&plist);
	Display(plist);
}



void test4()
{
	pNode plist;
	InitLinkList(&plist);
	PushFront(&plist, 2);
	PushFront(&plist, 1);
	PushFront(&plist, 6);
	PushFront(&plist, 4);
	PushFront(&plist, 5);
	PushFront(&plist, 9);
	PushFront(&plist, 4);
	Display(plist);
	Sort(&plist);//排序单链表
	Display(plist);
	DestroyList(&plist);
	Display(plist);
}


void test5()
{
	pNode plist;
	InitLinkList(&plist);
	PushFront(&plist, 1);
	PushFront(&plist, 2);
	PushFront(&plist, 3);
	PushFront(&plist, 4);
	Display(plist);
	ReversePrint(plist);//逆序打印单链表
	DestroyList(&plist);
	Display(plist);
}


void test6()
{
	pNode plist;
	pNode pos = NULL;
	InitLinkList(&plist);
	PushFront(&plist, 1);
	PushFront(&plist, 2);
	PushFront(&plist, 3);
	PushFront(&plist, 4);
	Display(plist);
	pos = Find(plist, 3);
	EraseNotTail(pos);
	Display(plist);
	InsertFrontNode(pos, 5);
	Display(plist);
	DestroyList(&plist);//删除非尾结点
	Display(plist);
}


void test7()
{
	pNode plist;
	pNode pos = NULL;
	InitLinkList(&plist);
	PushFront(&plist, 1);
	PushFront(&plist, 2);
	PushFront(&plist, 3);
	PushFront(&plist, 4);
	PushFront(&plist, 5);
	Find(plist, 1)->_next = Find(plist, 5);
	JosephCycle(&plist, 3);//约瑟夫环
}



void test8()
{
	pNode plist;
	pNode pos = NULL;
	InitLinkList(&plist);
	PushFront(&plist, 1);
	PushFront(&plist, 2);
	PushFront(&plist, 3);
	PushFront(&plist, 4);
	PushFront(&plist, 5);
	Display(plist);
	ReverseList(&plist);
	Display(plist);
	DestroyList(&plist);
	Display(plist);
}


void test9()
{
	pNode plist1;
	pNode plist2;
	pList newplist;
	InitLinkList(&plist1);
	InitLinkList(&plist2);
	PushBack(&plist1, 1);
	PushBack(&plist1, 3);
	PushBack(&plist1, 5);
	PushBack(&plist1, 7);
	PushBack(&plist2, 2);
	PushBack(&plist2, 4);
	PushBack(&plist2, 6);
	PushBack(&plist2, 8);
	PushBack(&plist2, 10);
	PushBack(&plist2, 12);
	Display(plist1);
	Display(plist2);
	newplist = Merge(&plist1, &plist2);
	Display(newplist);
	//DestroyList(&plist);
	//Display(plist);
}


void test10()
{
	pNode plist;
	pNode pos = NULL;
	InitLinkList(&plist);
	PushFront(&plist, 1);
	PushFront(&plist, 2);
	PushFront(&plist, 3);
	PushFront(&plist, 4);
	PushFront(&plist, 5);
	Display(plist);
	//pos = FindMidNode(plist);
	pos = FindKNode(plist, 5);
	if(pos == NULL)
	{
		printf("NULL\n");
	}
	else
	{
		printf("%d ",pos->_data);
	}
	DestroyList(&plist);
	Display(plist);
}


void test11()
{
	pNode plist;
	pNode pos = NULL;
	DataType i = 0;
	pNode env = NULL;
	InitLinkList(&plist);
	PushFront(&plist, 1);
	PushFront(&plist, 2);
	PushFront(&plist, 3);
	PushFront(&plist, 4);
	PushFront(&plist, 5);
	PushFront(&plist, 6);
	PushFront(&plist, 7);
	PushFront(&plist, 8);
	PushFront(&plist, 9);
	Find(plist, 1)->_next = Find(plist, 6);
	pos = CheckCircle(plist);
	printf("%d\n",pos->_data);
	i = GetCircleLength(pos);
	printf("%d\n",i);
	env = GetCycleEntryNode(plist, pos);
	printf("%d\n",env->_data);
	//DestroyList(&plist);
	//Display(plist);
}



void test12()
{
	pNode plist1;
	pNode plist2;
	int ret = 0;
	pNode pos = NULL;
	InitLinkList(&plist1);
	InitLinkList(&plist2);
	PushBack(&plist1, 1);
	PushBack(&plist1, 3);
	PushBack(&plist1, 5);
	PushBack(&plist1, 7);
	PushBack(&plist2, 2);
	PushBack(&plist2, 4);
	PushBack(&plist2, 6);
	PushBack(&plist2, 8);
	PushBack(&plist2, 10);
	PushBack(&plist2, 12);
	Find(plist1, 7)->_next = Find(plist2, 8);
	ret = CheckCross(plist1, plist2);
	if(ret == 1)
	{
		printf("两条链表相交\n");
	}
	else
	{
		printf("链表不相交\n");
	}
	pos = GetCrossNode(plist1, plist2);
	printf("%d\n",pos->_data);
}

int main()
{
	//test();
	//test1();
	//test2();
	//test3();
	//test4();
	//test5();
	//test6();
	//test7();
	//test8();
	//test9();
	//test10();
	//test11();
	//test12();
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值