SList.h
#pragma once
#include<stdio.h>
#include<assert.h>
#include<malloc.h>
typedef int DataType ;
typedef struct Node
{
DataType data;
struct Node* next;
}Node, *PLinkList;
void InitList(PLinkList* pplist); //初始化
void PrintList(PLinkList* pplist); //打印
int GetLength(PLinkList plist);//求长度
void PushBack(PLinkList* pplist, DataType x);//尾插
void PushFront(PLinkList* pplist, DataType x);//头插
void PopFront(PLinkList* pplist);//头删
void PopBack(PLinkList* pplist);//尾删
Node* Find(PLinkList plist, DataType x);
void Insert(PLinkList* pplist, Node * n, DataType x);
void InsertFrontNode(Node *n, DataType x);
void Reverse(PLinkList *pplist); // 翻转
void sort(PLinkList *plist);//排序
void PrintTailToHead(PLinkList plist);
PLinkList _CreateNode(DataType x)
{
PLinkList tmp = (PLinkList)malloc(sizeof(Node));
tmp->data = x;
tmp->next = NULL;
return tmp;
}
void InitList(PLinkList* pplist)
{
assert(pplist);
*pplist = 0;
}
void PrintList(PLinkList* pplist)
{
PLinkList begin = *pplist;
assert(pplist);
while (begin != NULL)
{
printf("%d->", begin->data);
begin = begin->next;
}
printf("NULL\n");
}
void PushBack(PLinkList* pplist, DataType x)
{
PLinkList tmp;
PLinkList begin = *pplist;
assert(pplist);
if (*pplist == NULL)
{
*pplist = _CreateNode(x);
}
else
{
tmp = _CreateNode(x);
while (begin->next != NULL)
{
begin = begin->next;
}
begin->next = tmp;
tmp->next = NULL;
}
}
void PushFront(PLinkList* pplist, DataType x)
{
PLinkList tmp;
assert(pplist);
if (*pplist == NULL)
{
*pplist = _CreateNode(x);
}
else
{
tmp = _CreateNode(x);
tmp->next = *pplist;
*pplist = tmp;
}
}
int GetLength(PLinkList plist)
{
int count = 0;
PLinkList begin = plist;
assert(plist);
while (begin != NULL)
{
begin = begin->next;
count++;
}
return count;
}
void PopFront(PLinkList* pplist)
{
PLinkList tmp;
assert(pplist);
if (*pplist == NULL)
{
printf("SList is empty\n");
return;
}
else
{
tmp = *pplist;
*pplist = (*pplist)->next;
free(tmp);
}
}
void PopBack(PLinkList* pplist)
{
PLinkList prev = *pplist,end = *pplist;
assert(pplist);
if (*pplist == NULL)
{
printf("SList is empty\n");
return;
}
else if ((*pplist)->next == NULL)//只有一个节点
{
free(*pplist);
*pplist = NULL;
printf("delet success\n");
return;
}
else //有多个节点
{
while (end->next != NULL)
{
prev = end;
end = end->next;
}
prev->next = NULL;
free(end);
}
}
Node* Find(PLinkList plist, DataType x)
{
PLinkList begin = plist;
assert(plist);
if (plist == NULL)
{
printf("SList is empty\n");
return begin;
}
else
{
while (begin != NULL)
{
if (begin->data == x)
{
printf("find %d\n", x);
return begin;
}
begin = begin->next;
}
}
printf("not find %d\n", x);
return NULL;
}
void Insert(PLinkList* pplist, Node * n, DataType x)
{
PLinkList tmp;
assert(pplist);
if (*pplist == NULL)
{
*pplist = _CreateNode(x);
return;
}
else
{
tmp = _CreateNode(x);
tmp->next = n->next;
n->next = tmp;
}
}
void DelMidNode(Node* n)
{
assert(n);
if ( n == NULL)
{
printf("node is NULL\n");
return;
}
else if (n->next == NULL)
{
printf("n is trail node\n");
}
else
{
Node* tmp = n->next;
n->data = tmp->data;
n->next = tmp->next;
free(tmp);
}
}
int Remove(PLinkList* pplist, Node * n)
{
assert(pplist);
if ((n->next) == NULL)
{
PopBack(pplist);
return 0;
}
else
{
DelMidNode(n);
return 0;
}
}
void Erase(PLinkList* pplist, DataType x, int all)
{
Node* ret = *pplist;
assert(pplist);
do
{
ret = Find(ret,x);
if (ret != NULL)
{
Remove(pplist, ret);
}
} while (ret != 0 && all != 0);
}
void InsertFrontNode(Node *n, DataType x)
{
Node *tmp;
assert(n);
if (n == NULL)
{
printf("n is NULL\n");
return;
}
else
{
tmp = _CreateNode(n->data);
tmp->next = n->next;
n->next = tmp;
n->data = x;
}
}
//逆置/反转单链表
void Reverse(PLinkList *pplist)
{
Node* NewHead = NULL;
Node* begin = (*pplist)->next;
assert(pplist);
if (*pplist != NULL)
{
// 取第一个节点做新的头结点
NewHead = *pplist;
NewHead->next = NULL;
}
while (begin != NULL)
{
// 取节点进行头插
Node* tmp = begin;
begin = begin->next;
tmp->next = NewHead;
NewHead = tmp;
}
*pplist = NewHead;
}
//链表排序
void sort(PLinkList *pplist)
{
int count = 0;
int exchange = 0;
PLinkList tmp = *pplist;
assert(pplist);
if (*pplist == NULL)
{
printf("SList is empty\n");
return;
}
else
{
while (count < GetLength(*pplist))
{
exchange = 0;
while (tmp->next != NULL)
{
if (tmp->data > tmp->next->data)
{
DataType x = tmp->data;
tmp->data = tmp->next->data;
tmp->next->data = x;
exchange = 1;
}
tmp = tmp->next;
}
if (exchange == 0)
{
return;
}
tmp = *pplist; //又从头开始检查
count++;
}
}
}
//从尾到头打印单链表
void PrintTailToHead(PLinkList pList)
{
if(pList)
{
PrintTailToHead(pList->next); //递归调用
printf("%d->", pList->data);
}
}
//单链表实现约瑟夫环
void JosephCycle(PLinkList* ppList, int k)
{
Node* begin = *ppList;
assert(ppList);
if (*ppList == NULL)
{
return;
}
else
{
while (1)
{
if (begin->next == begin) //只剩下一个节点
{
break;
}
Node* del = NULL;
int x = k;
while (--x)
{
begin = begin->next;
}
//应用删除一个无头无尾的中间节点的思想
printf("delete node is %d\n", begin->data);
begin->data = begin->next->data;
del = begin->next;
begin->next = del->next;
free(del);
}
*ppList = begin;
}
}
//合并两个有序链表,合并后依然有序
PLinkList Merge(PLinkList pList1, PLinkList pList2)
{
PLinkList pList = pList1; //新的头节点
PLinkList end;
assert(pList1);
assert(pList2);
if (pList1 == NULL)
{
return pList2;
}
if (pList2 == NULL)
{
return pList1;
}
if (pList1 == pList2)
{
return pList1;
}
//选择一个小的作为头节点
if (pList1->data < pList2->data)
{
pList = pList1;
pList1 = pList1->next;
}
else
{
pList = pList2;
pList2 = pList2->next;
}
end = pList; //链接下一个节点
while (pList1 && pList2)
{
Node* tmp = NULL;
if (pList1->data < pList2->data)
{
tmp = pList1;
pList1 = pList1->next;
}
else
{
tmp = pList2;
pList2 = pList2->next;
}
end->next = tmp;
end = tmp;
}
if (pList1)
{
end->next = pList1;
}
if (pList2)
{
end->next = pList2;
}
return pList;
}
//查找单链表的中间节点,要求只能遍历一次链表
Node* FindMidNode(PLinkList *ppList)
{
PLinkList slow = *ppList;
PLinkList fast = *ppList;
assert(ppList);
if (*ppList == NULL)
{
return NULL;
}
else
{
while (fast && fast->next)
{
fast = fast->next->next; //快指针一次走两步
slow = slow->next; //慢指针一次走一步
}
printf("MidNode is %d\n", slow->data);
return slow;
}
}
//查找单链表的倒数第k个节点,要求只能遍历一次链表
Node* FindKNode(PLinkList *ppList,DataType k)
{
int x = k;
PLinkList slow = *ppList;
PLinkList fast = *ppList;
assert(ppList);
if (*ppList == NULL)
{
return NULL;
}
else
{
while (fast && x--) //快指针先走k步
{
fast = fast->next;
}
if (x > 0)//链表总共都没有k个节点
{
return NULL;
}
while (fast) //当快指针走到结尾慢指针走到倒数第k个节点
{
fast = fast->next;
slow = slow->next;
}
printf("The last %d node is %d\n", k, slow->data);
return slow;
}
}
//判断单链表是否带环
bool IsCycle(PLinkList pList, PLinkList *ppMeetNode)
{
assert(pList);
PLinkList slow = pList;
PLinkList fast = pList;
while (fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
{
*ppMeetNode = slow;
return true;
}
}
*ppMeetNode = NULL;
return false;
}
main.cpp
#include"Slist.h"
void test()
{
int ret;
PLinkList plist;
InitList(&plist);
PushFront(&plist, 1);
PushFront(&plist, 2);
PushFront(&plist, 3);
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PrintList(&plist);
PopFront(&plist);
PrintList(&plist);
PopBack(&plist);
PrintList(&plist);
PopBack(&plist);
PrintList(&plist);
PopBack(&plist);
Find(plist, 4);
ret = GetLength(plist);
printf("length= %d\n", ret);
}
void test2()
{
PLinkList ret;
PLinkList plist;
InitList(&plist);
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PrintList(&plist);
ret = Find(plist, 1);
if (ret != NULL)
{
Insert(&plist, ret, 10);
}
PrintList(&plist);
}
void test3()
{
PLinkList ret;
PLinkList plist;
Node* no = NULL;
InitList(&plist);
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PrintList(&plist);
ret = Find(plist, 3);
DelMidNode(ret);
PrintList(&plist);
ret = Find(plist, 1);
Remove(&plist, ret);
PrintList(&plist);
}
void test4()
{
PLinkList plist;
InitList(&plist);
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PushBack(&plist, 1);
PushBack(&plist, 1);
PushBack(&plist, 3);
PrintList(&plist);
Erase(&plist, 1, 0);
PrintList(&plist);
Erase(&plist, 1, 1);
PrintList(&plist);
}
void test5()
{
PLinkList plist,ret;
InitList(&plist);
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PrintList(&plist);
ret = Find(plist, 2);
InsertFrontNode(ret, 10);
PrintList(&plist);
Reverse(&plist);
PrintList(&plist);
PrintTailToHead(plist);
}
void test6()
{
PLinkList plist;
InitList(&plist);
PushBack(&plist, 6);
PushBack(&plist, 4);
PushBack(&plist, 2);
PushBack(&plist, 1);
PushBack(&plist, 5);
PushBack(&plist, 3);
PrintList(&plist);
sort(&plist);
PrintList(&plist);
PrintTailToHead(plist);
}
void test7()
{
PLinkList plist,ret;
InitList(&plist);
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PushBack(&plist, 4);
PushBack(&plist, 5);
PushBack(&plist, 6);
PrintList(&plist);
//构建约瑟夫环
ret = Find(plist, 6);
ret->next = plist;
JosephCycle(&ret, 3);
}
void test8()
{
PLinkList plist, plist1, plist2;
InitList(&plist1);
PushBack(&plist1, 1);
PushBack(&plist1, 2);
PushBack(&plist1, 4);
PushBack(&plist1, 6);
PushBack(&plist1, 9);
PushBack(&plist1, 10);
PrintList(&plist1);
InitList(&plist2);
PushBack(&plist2, 3);
PushBack(&plist2, 5);
PushBack(&plist2, 7);
PushBack(&plist2, 8);
PushBack(&plist2, 14);
PushBack(&plist2, 17);
PrintList(&plist2);
plist = Merge(plist1, plist2);
PrintList(&plist);
FindMidNode(&plist);
FindKNode(&plist, 4);
}
void test9()
{
char *tag = NULL;
Node* entry, *end, *pMeetNode;
PLinkList plist;
InitList(&plist);
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PushBack(&plist, 4);
PushBack(&plist, 5);
PushBack(&plist, 6);
PrintList(&plist);
entry = Find(plist, 4);
end = Find(plist, 6);
end->next = entry;
*tag = IsCycle(plist, &pMeetNode);
printf("Is Cycle %s\n",*tag);
}
int main()
{
test9();
getchar();
return 0;
}