头文件:
#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;
}