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;
}