C实现单链表的常见功能

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

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

普通功能的实现:


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__





你可能感兴趣的:(c,单链表,常见功能)