目录
概述:
要实现带头的双向循环链表,我们需要知道什么是头节点,如何循环。
首先,头节点是一个不存任何数据的节点,链表为空,也就是指此链表只有一个头节点。
其次,循环,则是指头指向尾,尾指向头,当链表尾空时,其头节点既是表头,也是表尾。
最后,双向,则是指其可以向前访问,也可以向后访问,这也说明了双向链表是由两个指针的,一个指向头,一个指向尾。
初始工作
定义
接下来我们定义一个双向循环链表,为了更方便的表示,我们对其进行再次封装
#include <stdlib.h>
#include <stdio.h>
typedef int LNElemType;
typedef struct ListNode{
LNElemType val;
struct ListNode* prev;
struct ListNode* next;
}ListNode;
typedef struct BidList{
ListNode* head;
size_t size;
}BidList;
考虑到数据的类型时不固定的,所以我们给出函数指针,对于不同的数据类型,由用户进行处理,我们只对基础数据类型进行处理
typedef void(*PRINT)(LNElemType* val);
typedef bool(*COMPARE)(LNElemType* src, LNElemType* des);
typedef void(*ASSIG)(LNElemType* src, LNElemType* des);
void printChar(char* val){
printf("%c", *val);
}
void printShort(short* val){
printf("%h", *val);
}
void printInt(int* val){
printf("%d", *val);
}
void printLong(long* val){
printf("%ld", *val);
}
void printfLongLong(long long* val){
printf("%lld", *val);
}
void printFloat(float* val){
printf("%f", *val);
}
void printDouble(double* val){
printf("%lf", *val);
}
void printString(char** val){
printf("%s", *val);
}
void IsEqual(LNElemType* src, LNElemType* des){
return *src == *des;
}
void MoreThan(LNElemType* src, LNElemType* des){
return *src < *des;
}
void LessThan(LNElemType* src, LNElemType* des){
return *src > *des;
}
void setValue(LNElemType* src, LNElemType* des){
*src = *des;
}
功能实现
初始化
void BidListInit(BidList* phead)
{
assert(phead != NULL);
phead->head = (ListNode*)malloc(sizeof(ListNode));
if (phead->head == NULL)
{
perror("Init fail");
exit(1);
}
phead->head->next = phead->head;
phead->head->prev = phead->head;
//考虑到链表的初始数据可能会是一个结构,所以我们不为头节点赋初始值,防止发生错误
}
获取新节点
ListNode* BuyNode(){
ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
assert(newNode);
return newNode;
}
头插
void BidListPushFront(BidList* phead, LNElemType val, ASSIG setValue){
assert(phead != NULL);
//创建节点
ListNode* newNode = BuyNode();
setValue(&newNode->val, &val);
ListNode* first = phead->head->next;
first->prev = newNode;
newNode->next = first;
newNode->prev = phead->head;
phead->head->next = newNode;
phead->size++;
}
尾插
void BidListPushBack(BidList* phead, LNElemType val, ASSIG setValue){
assert(phead != NULL);
ListNode* newNode = BuyNode();
setValue(&newNode->val, &val);
ListNode* tail = phead->head->prev;
tail->next = newNode;
newNode->next = phead->head;
newNode->prev = tail;
phead->head->prev = newNode;
phead->size++;
}
随即插入
void BidListInert(BidList* phead, ListNode* pos, LNElemType val, ASSIG setValue){
assert(pos != NULL);
assert(phead != NULL);
ListNode* newNode = BuyNode();
setValue(&newNode->val, &val);
ListNode* cur = pos->prev;
cur->next = newNode;
newNode->prev = cur;
newNode->next = pos;
pos->prev = newNode;
phead->size++;
}
头删
void BidListPopFront(BidList* phead){
assert(phead != NULL);
if (phead->size == 0)
{
return;
}
ListNode* head = phead->head->next;
phead->head->next = head->next;
head->next->prev = phead->head;
free(head);
phead->size--;
}
尾删
void BidListPopBack(BidList* phead){
assert(phead != NULL);
if (phead->size == 0)
{
return;
}
ListNode* tail = phead->head->prev;
tail->prev->next = phead->head;
phead->head->next = tail->prev;
free(tail);
phead->size--;
}
随机删除
void BidListErase(BidList* phead, ListNode* pos){
assert(pos != NULL);
assert(phead != NULL);
ListNode* next = pos->next;
ListNode* prev = pos->prev;
next->prev = prev;
prev->next = next;
free(pos);
phead->size--;
}
修改
void BidListModify(BidList* phead, LNElemType src, LNElemType des, COMPARE IsEqual, ASSIG setValue){
assert(phead != NULL);
ListNode* p = phead->head->next;
while (p != phead->head){
if (IsEqual(&p->val, &src))
{
setValue(&p->val, &des);
break;
}
p = p->next;
}
}
查找元素
ListNode* BidListFind(BidList* phead, LNElemType val, COMPARE IsEqual){
assert(phead);
ListNode* p = phead->head->next;
while (p != phead->head){
if (IsEqual(&p->val, &val)){
return p;
}
p = p->next;
}
return NULL;
}
打印链表
void BidListPrint(BidList* phead, PRINT print){
assert(phead);
ListNode* head = phead->head->next;
printf("guard<->");
while (head != phead->head){
print(&head->val);
printf("<->");
head = head->next;
}
printf("guard\n");
}
销毁
void BidListDestory(BidList* phead){
assert(phead != NULL);
ListNode* p = phead->head->next;
ListNode* t = p;
while (p->next != phead->head){
p = t->next;
free(t);
t = p;
}
free(phead->head);
phead->head = NULL;
phead->size = 0;
}
清空
void BidListClear(BidList* phead){
assert(phead != NULL);
ListNode* p = phead->head->next;
ListNode* t = p;
while (p->next != phead->head){
p = t->next;
free(t);
t = p;
}
phead->head->next = phead->head;
phead->head->prev = phead->head;
phead->size = 0;
}
判断为空
bool BidListIsEmpty(BidList* phead)
{
assert(phead != NULL);
return phead->size == 0;
}
测试
void test01()
{
BidList list;
BidListInit(&list);
BidListPushBack(&list, 1, setValue);
BidListPushBack(&list, 2, setValue);
BidListPushBack(&list, 3, setValue);
BidListPushFront(&list, 10, setValue);
BidListPushFront(&list, 20, setValue);
BidListPushFront(&list, 30, setValue);
BidListPrint(&list, printInt);
ListNode* pos = BidListFind(&list, 2, IsEqual);
BidListInert(&list, pos, 200, setValue);
BidListErase(&list, pos);
BidListModify(&list, 200, 100, IsEqual, setValue);
BidListPrint(&list, printInt);
BidListClear(&list);
BidListPrint(&list,printInt);
BidListPopBack(&list);
BidListDestory(&list);
}
int main()
{
test01();
system("pause");
return 0;
}