单向循环链表
说明1:以下代码在VS2017中编译通过,读者使用时可以直接将头文件(CLinkList.h),源文件(CLinkList.c),主文件(main.c)中的内容直接拷贝过去,即可编译运行!
说明2:图示
头文件:CLinkList.h(函数的声明)
#ifndef _CLINKLIST_H_
#define _CLINKLIST_H_
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include <stdbool.h>
#define ElemType int
typedef struct ListNode
{
ElemType data;
struct ListNode* next;
}ListNode,*pListNode;
typedef struct LinkList
{
pListNode head;
pListNode tail;
size_t size;
}LinkList;
/
void InitList(LinkList* list);
ListNode* CreateNode(ElemType data);
void push_back(LinkList* list, ElemType data);
void push_front(LinkList* list, ElemType data);
void ShowList(LinkList* list);
void pop_back(LinkList* list);
void pop_front(LinkList* list);
bool Empty(LinkList* list);
void Insert_By_Value(LinkList* list, ElemType data);
pListNode Find_data(LinkList* list, ElemType Key);
int Length(LinkList* list);
void Delete_By_Value(LinkList* list, ElemType Key);
void Delete_By_Value_Traditaonal(LinkList* list, ElemType Key);
void Sort(LinkList* list);
void Reverse(LinkList* list); //数据反转
void Clear(LinkList* list);
void Destory(LinkList* list);
pListNode Find(LinkList* list, ElemType Key);
pListNode Prior(LinkList* list, ElemType PosData); //求PosData结点的前驱
pListNode Next(LinkList* list, ElemType PosData); //求PosData结点的后继
#endif // ! _CLINKLIST_H_
源文件:CLinkList.c(函数的定义)
#include "CLinkList.h"
void InitList(LinkList* list)
{
list->head = list->tail = (pListNode)malloc(sizeof(ListNode));
assert(list->head != NULL);
list->tail->next = list->head;
list->size = 0;
}
ListNode * CreateNode(ElemType data)
{
ListNode* NewNode = (pListNode)malloc(sizeof(ListNode));
assert(NewNode != NULL);
NewNode->data = data;
NewNode->next = NULL;
return NewNode;
}
void push_back(LinkList* list, ElemType data)
{
pListNode NewNode = CreateNode(data);
list->tail->next = NewNode;
list->tail = NewNode;
list->tail->next = list->head;
list->size++;
}
void push_front(LinkList* list, ElemType data)
{
pListNode NewNode = CreateNode(data);
NewNode->next = list->head->next;
list->head->next = NewNode;
if (list->size == 0)
list->tail = NewNode;
list->size++;
}
void ShowList(LinkList* list)
{
pListNode pMove = list->head->next;
while (pMove != list->head)
{
printf("%d--->", pMove->data);
pMove = pMove->next;
}
printf(".Nul\n");
}
void pop_back(LinkList* list)
{
if (list->size == 0)
return;
pListNode pMove = list->head;
while (pMove->next != list->tail)
{
pMove = pMove->next;
}
free(list->tail);
list->tail = pMove;
list->tail->next = list->head;
list->size--;
}
void pop_front(LinkList* list)
{
if (list->size == 0)
return;
pListNode pMove = list->head->next;
list->head->next = pMove->next;
free(pMove);
if (list->size == 1)
list->tail = list->head;
list->size--;
}
bool Empty(LinkList* list)
{
return list->size == 0;
}
void Insert_By_Value(LinkList* list, ElemType data)
{
pListNode pMove = list->head;
while (pMove->next != list->tail && pMove->next->data < data)
{
pMove = pMove->next;
}
if (pMove->next == list->tail && pMove->next->data < data) //最后面插入
{
push_back(list, data);
}
else
{
pListNode NewNode = CreateNode(data);
NewNode->next = pMove->next;
pMove->next = NewNode;
list->size++;
}
}
pListNode Find_data(LinkList* list, ElemType Key)
{
if (list->size == 0)
return NULL;
pListNode pMove = list->head->next;
while (pMove != list->head && pMove->data != Key)
{
pMove = pMove->next;
}
if (pMove == list->head)
return NULL;
return pMove;
}
int Length(LinkList* list)
{
return list->size;
}
void Delete_By_Value(LinkList* list, ElemType Key)
{
if (list->size == 0)
return;
pListNode pFind = Find_data(list, Key);
if (pFind == NULL)
{
printf("查无此数,无法删除!\n");
return;
}
if (pFind == list->tail)
{
pop_back(list);
}
else if (pFind->next == list->tail) //倒数第二个结点(必须单独考虑,list->tail指向要发生改变)
{
pListNode q = pFind->next;
pFind->data = q->data;
pFind->next = q->next;
list->tail = pFind;
free(q);
q = NULL;
list->size--;
}
else
{
pListNode q = pFind->next;
pFind->data = q->data;
pFind->next = q->next;
if (pFind->next == list->tail)
list->tail = pFind;
free(q);
q = NULL;
list->size--;
}
}
void Delete_By_Value_Traditaonal(LinkList* list, ElemType Key)
{
if (list->size == 0)
return;
pListNode pFind = Find_data(list, Key);
if (pFind == NULL)
{
printf("查无此数,无法删除!\n");
return;
}
if (pFind == list->head->next) //删除的是第一个结点
pop_front(list);
else if (pFind == list->tail) //删除的是最后一个结点
pop_back(list);
else
{
pListNode pPrior = Prior(list, pFind->data);
pPrior->next = pFind->next;
free(pFind);
pFind = NULL;
list->size--;
}
}
void Sort(LinkList* list)
{
if (list->size == 0 || list->size == 1)
return;
//首先分割
pListNode pMove1 = list->head->next;
pListNode pMove2 = pMove1->next;
list->tail->next = NULL;
list->tail = pMove1;
list->tail->next = list->head;
//然后进行插入及其连接
while (pMove2 != NULL)
{
pMove1 = pMove2;
pMove2 = pMove2->next;
pListNode pMove = list->head;
while (pMove->next != list->tail && pMove->next->data < pMove1->data)
{
pMove = pMove->next;
}
if (pMove->next == list->tail && pMove->next->data < pMove1->data)
{
pMove1->next = list->tail->next;
list->tail->next = pMove1;
list->tail = pMove1;
}
else
{
pMove1->next = pMove->next;
pMove->next = pMove1;
}
}
}
void Reverse(LinkList* list)
{
if (list->size == 0 || list->size == 1)
return;
pListNode pMove1 = list->head->next;
pListNode pMove2 = pMove1->next;
list->tail->next = NULL;
list->tail = pMove1;
list->tail->next = list->head;
while (pMove2 != NULL)
{
pMove1 = pMove2;
pMove2 = pMove2->next;
pMove1->next = list->head->next;
list->head->next = pMove1;
}
}
void Clear(LinkList* list)
{
if (list->size == 0)
return;
pListNode pMove = list->head->next;
while (pMove != list->head)
{
list->head->next = pMove->next;
free(pMove);
pMove = list->head->next;
}
list->tail = list->head;
list->size = 0;
}
void Destory(LinkList* list)
{
Clear(list);
free(list->head);
list->head = list->tail = NULL;
}
pListNode Find(LinkList* list, ElemType Key)
{
ListNode* pFind = Find_data(list, Key);
if (pFind == NULL || list->size == 0 || list->size == 1 || list->head->next->data == Key)
return NULL;
pListNode pMove = list->head->next;
while (pMove->next != list->head && pMove->next->data != Key)
{
pMove = pMove->next;
}
return pMove;
}
pListNode Prior(LinkList* list, ElemType PosData)
{
return Find(list,PosData);
}
pListNode Next(LinkList* list, ElemType PosData)
{
ListNode* pFind = Find_data(list, PosData);
if (pFind == NULL)
return NULL;
if (pFind->next == list->head)
return NULL;
return pFind->next;
}
主文件:main.c(测试文件)
#include "CLinkList.h"
int main()
{
LinkList MyLinkList;
InitList(&MyLinkList);
push_back(&MyLinkList, 3);
push_back(&MyLinkList, 1);
push_back(&MyLinkList, 10);
push_back(&MyLinkList, 7);
ShowList(&MyLinkList);
//push_front(&MyLinkList, 6);
//push_front(&MyLinkList, 7);
//push_front(&MyLinkList, 8);
//ShowList(&MyLinkList);
//pop_back(&MyLinkList);
//pop_front(&MyLinkList);
//ShowList(&MyLinkList);
Insert_By_Value(&MyLinkList, 0);
ShowList(&MyLinkList);
//pListNode pFind = Find_data(&MyLinkList, 7);
//Delete_By_Value(&MyLinkList, 7);
//Delete_By_Value(&MyLinkList, 0);
//Delete_By_Value(&MyLinkList, 3);
ShowList(&MyLinkList);
Sort(&MyLinkList);
ShowList(&MyLinkList);
Reverse(&MyLinkList);
ShowList(&MyLinkList);
//Clear(&MyLinkList);
pListNode pNext = Next(&MyLinkList, 10);//7
pNext = Next(&MyLinkList, 3);//1
pNext = Next(&MyLinkList, 0);//NULL
pListNode pPrior = Prior(&MyLinkList, 10);//NULL
pPrior = Prior(&MyLinkList, 3);//7
pPrior = Prior(&MyLinkList, 0);//1
Delete_By_Value_Traditaonal(&MyLinkList, 10);
Delete_By_Value_Traditaonal(&MyLinkList, 3);
Delete_By_Value_Traditaonal(&MyLinkList, 0);
ShowList(&MyLinkList);
return 0;
}