本章主要实现一个带头双向循环链表: 具体实现的部分如下:
目录
初始化:
一开始先创建头结点,并且让哨并位的头结点指向自己,才能满足循环
创建结点:
//创建结点
LTNode* BuyListNode(LTDataType x)
{
LTNode* node = (LTNode*)malloc(sizeof(LTNode));
if (node == NULL)
{
printf("malloc fail");
exit(-1);
}
node->next = NULL;
node->prev = NULL;
node->data = x;
return node;
}
初始化:
因为phead会被改变,所以这里传二级指针
void ListInit(LTNode** pphead)
{
assert(pphead);
*pphead = BuyListNode(0);
(*pphead)->next = *pphead;
(*pphead)->prev = *pphead;
}
//用返回值的方法初始化:
LTNode* ListInit()
{
LTNode*phead = BuyListNode(0);
phead->next = phead;
phead->prev = phead;
return phead;
}
查找某个数:
LTNode* ListFind(LTNode* phead, LTDataType x)
{
LTNode*cur = phead->next;
while (cur != phead)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
在pos位置之前插入某个数:
//在pos位置之前插入某个数
void ListInsert(LTNode* pos, LTDataType x)
{
assert(pos);
LTNode* newnode = BuyListNode(x);
LTNode* prev = pos->prev;
prev->next = newnode;
newnode->prev = prev;
newnode->next = pos;
pos->prev = newnode;
//思考:如果pos是在头或者尾会不会有问题?
//答:不会
}
思考:如果pos是在头或者尾会不会有问题?
答:不会
头插:
这里直接调用ListInsert接口
void ListPushFront(LTNode* phead, LTDataType x)
{
assert(phead);
ListInsert(phead->next, x);
}
尾插:
void ListPushBack(LTNode* phead, LTDataType x)
{
assert(phead);
LTNode*tail = phead->prev;
LTNode*newnode = BuyListNode(x);
tail->next = newnode;
newnode->prev = tail;
newnode->next = phead;
phead->prev = newnode;
//思考:如果链表为空,能否搞定
}
思考:如果链表为空,能否搞定?
答:可以
调用ListInsert接口:
void ListPushBack(LTNode* phead, LTDataType x)
{
assert(phead);
ListInsert(phead, x);
}
删除pos位置的数:
void ListErase(LTNode*pos)
{
assert(pos);
assert(!ListEmpty(pos));
LTNode*posnext = pos->next;
LTNode*posprev = pos->prev;
free(pos);
posprev->next = posnext;
posnext->prev = posprev;
}
头删:
调用ListErase接口
void ListPopFront(LTNode* phead)
{
assert(phead);
ListErase(phead->next);
}
尾删:
void ListPopBack(LTNode* phead)
{
assert(phead);
assert(!ListEmpty(phead));
LTNode*tail = phead->prev;
LTNode*ptail = tail->prev;
free(tail);
phead->prev = ptail;
ptail->next = phead;
}
调用ListErase接口
void ListPopBack(LTNode* phead)
{
assert(phead);
ListErase(phead->prev);
}
判空:
bool ListEmpty(LTNode*phead)
{
assert(phead);
return phead->next == phead;
}
双链表数据个数:
size_t ListSize(LTNode*phead)
{
assert(phead);
size_t n = 0;
LTNode*cur = phead->next;
while (cur != phead)
{
n++;
cur = cur->next;
}
return n;
}
打印双链表:
void ListPrint(LTNode* phead)
{
assert(phead);
LTNode*cur = phead->next;
while (cur != phead)
{
printf("%d ",cur->data);
cur = cur->next;
}
printf("\n");
}
销毁双链表:
传二级指针,防止销毁destroy后,plist会出现野指针的问题
//传二级指针,防止销毁destroy后,plist会出现野指针的问题
void ListDestroy(LTNode** pphead)
{
LTNode*cur = (*pphead)->next;
while (cur != *pphead)
{
LTNode*next = cur->next;
free(cur);
cur = next;
}
free(*pphead);
*pphead = NULL;
}
List.h和Test.c文件:
List.h:
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int LTDataType;
typedef struct ListNode
{
struct ListNode* next;
struct ListNode* prev;
LTDataType data;
}LTNode;
LTNode* BuyListNode(LTDataType x);
//void ListInit(LTNode** pphead);
LTNode* ListInit();
void ListPrint(LTNode* phead);
void ListPushBack(LTNode* phead,LTDataType x);
void ListPushFront(LTNode* phead, LTDataType x);
void ListPopBack(LTNode* phead);
void ListPopFront(LTNode* phead);
void ListErase(LTNode*pos);
LTNode* ListFind(LTNode* phead, LTDataType x);
void ListInsert(LTNode* pos, LTDataType x);
bool ListEmpty(LTNode*phead);
size_t ListSize(LTNode*phead);
void ListDestroy(LTNode** pphead);
Test.c:
#include"List.h"
void TestList1()
{
LTNode* plist = NULL;
//ListInit(&plist);
plist = ListInit();
ListPushBack(plist,1);
ListPushBack(plist, 2);
ListPushBack(plist, 3);
ListPushBack(plist, 4);
ListPushBack(plist, 5);
ListPushFront(plist, 200);
ListPushFront(plist, 100);
ListPushBack(plist, 500);
printf("%d\n", ListSize(plist));
ListPrint(plist);
ListPopBack(plist);
ListPrint(plist);
ListPopFront(plist);
ListPrint(plist);
LTNode*pos = ListFind(plist, 3);
if (pos)
{
ListInsert(pos, 300);
}
ListPrint(plist);
if (pos)
{
ListErase(pos);
}
ListPrint(plist);
ListDestroy(&plist);
}
int main()
{
TestList1();
return 0;
}