带头双向循环链表的建立
- 前言
- 一、Doubly_linked_list.h头文件的建立
- 二、Doubly_linked_list.c功能函数的定义
- 三、Doubly_linked_list_test.c测试函数的定义
- 四、代码运行测试
- 五、Doubly_linked_list完整代码演示
- 总结
前言
今天我们来学习带头双向循环链表!
不知道链表详细分类的同学可以看一看之前的博客!
链接在这里:链表的分类
一、Doubly_linked_list.h头文件的建立
1.头文件的声明
c
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
2.双向链表接口实现
c
typedef int LTDataType;
typedef struct ListNode
{
struct ListNode* next;
struct ListNode* prev;
LTDataType data;
}LTNode;
3.双向链表的结点建立、初始化、打印函数的声明
c
LTNode* BuyLTNode(LTDataType x);
LTNode* LTInit();
void LTPrint(LTNode* phead);
4.尾插、尾删函数的声明
c
void LTPushBack(LTNode* phead, LTDataType x);
void LTPopBack(LTNode* phead);
5.头插、头删函数的声明
c
void LTPushFront(LTNode* phead, LTDataType x);
void LTPopFront(LTNode* phead);
6.链表长度计算函数的声明
c
int LTSize(LTNode* phead);
7.进阶功能函数的声明
c
//在pos位置插入函数的声明
void LTInsert(LTNode* pos, LTDataType x);
//在pos位置删除函数的声明
void LTErase(LTNode* pos);
二、Doubly_linked_list.c功能函数的定义
1.头文件的声明
c
#include"Doubly_linked_list.h"
2.初始化函数、打印函数以及创建结点函数的定义
c
LTNode* BuyLTNode(LTDataType x)
{
LTNode* node = (LTNode*)malloc(sizeof(LTNode));
if (node == NULL)
{
perror("malloc fail");
exit(-1);
}
node->data = x;
node->next = NULL;
node->prev = NULL;
return node;
}
LTNode* LTInit()
{
LTNode* phead = BuyLTNode(-1);
phead->next = phead;
phead->prev = phead;
return phead;
}
void LTPrint(LTNode* phead)
{
assert(phead);
printf("phead<=>");
LTNode* cur = phead->next;
while (cur != phead)
{
printf("%d<=>", cur->data);
cur = cur->next;
}
printf("\n");
}
3.尾插、尾删函数的定义
c
void LTPushBack(LTNode* phead, LTDataType x)
{
assert(phead);
LTNode* tail = phead->prev;
LTNode* newnode = BuyLTNode(x);
newnode->prev = tail;
tail->next = newnode;
newnode->next = phead;
phead->prev = newnode;
}
void LTPopBack(LTNode* phead)
{
assert(phead);
assert(phead->next != phead);
LTNode* tail = phead->prev;
LTNode* tailPrev = tail->prev;
free(tail);
tailPrev->next = phead;
phead->prev = tailPrev;
}
4.头插、头删函数的定义
c
void LTPushFront(LTNode* phead, LTDataType x)
{
assert(phead);
LTNode* newnode = BuyLTNode(x);
LTNode* first = phead->next;
phead->next = newnode;
newnode->prev = phead;
newnode->next = first;
first->prev = newnode;
}
void LTPopFront(LTNode* phead)
{
assert(phead);
assert(phead->next != phead);
LTNode* first = phead->next;
LTNode* second = first->next;
free(first);
phead->next = second;
second->prev = phead;
}
5.长度计算函数的定义
c
int LTSize(LTNode* phead)
{
assert(phead);
int size = 0;
LTNode* cur = phead->next;
while (cur != phead)
{
++size;
cur = cur->next;
}
return size;
}
6.进阶功能函数的定义
c
void LTInsert(LTNode* pos, LTDataType x)
{
assert(pos);
LTNode* posPrev = pos->prev;
LTNode* newnode = BuyLTNode(x);
posPrev->next = newnode;
newnode->prev = posPrev;
newnode->next = pos;
pos->prev = newnode;
}
void LTErase(LTNode* pos)
{
assert(pos);
LTNode* posPrev = pos->prev;
LTNode* posNext = pos->next;
free(pos);
posPrev->next = posNext;
posNext->prev = posPrev;
}
三、Doubly_linked_list_test.c测试函数的定义
1.头文件的声明
c
#include"Doubly_linked_list.h"
2.测试调用函数的定义
c
void TestList()
{
LTNode* plist = LTInit();
LTPushBack(plist, 1);
LTPushBack(plist, 2);
LTPushBack(plist, 3);
LTPushBack(plist, 4);
LTPushBack(plist, 5);
LTPrint(plist);
LTPopFront(plist);
LTPrint(plist);
LTPopBack(plist);
LTPrint(plist);
}
3.主函数定义
c
int main()
{
TestList();
return 0;
}
四、代码运行测试
示例一:
c
void TestList1()
{
LTNode* plist = LTInit();
LTPushBack(plist, 1);
LTPushBack(plist, 2);
LTPushBack(plist, 3);
LTPushBack(plist, 4);
LTPushBack(plist, 5);
LTPrint(plist);
LTPushFront(plist, 10);
LTPushBack(plist, 10);
LTPrint(plist);
}
运行结果:
示例二:
c
void TestList2()
{
LTNode* plist = LTInit();
LTPushBack(plist, 1);
LTPushBack(plist, 2);
LTPushBack(plist, 3);
LTPushBack(plist, 4);
LTPushBack(plist, 5);
LTPrint(plist);
LTPopBack(plist);
LTPopFront(plist);
LTPrint(plist);
LTPopFront(plist);
LTPopFront(plist);
LTPopFront(plist);
//LTPopFront(plist);
LTPrint(plist);
}
运行结果:
示例三:
c
void TestList3()
{
LTNode* plist = LTInit();
LTPushBack(plist, 1);
LTPushBack(plist, 2);
LTPushBack(plist, 3);
LTPushBack(plist, 4);
LTPushBack(plist, 5);
LTPrint(plist);
LTPushFront(plist, 10);
LTPushFront(plist, 20);
LTPushFront(plist, 30);
LTPushFront(plist, 40);
LTPrint(plist);
}
运行结果:
示例四:
c
void TestList4()
{
LTNode* plist = LTInit();
LTPushBack(plist, 1);
LTPushBack(plist, 2);
LTPushBack(plist, 3);
LTPushBack(plist, 4);
LTPushBack(plist, 5);
LTPrint(plist);
LTPopFront(plist);
LTPrint(plist);
LTPopBack(plist);
LTPrint(plist);
}
运行结果:
五、Doubly_linked_list完整代码演示
1.Doubly_linked_list.h
c
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//双向链表接口定义
typedef int LTDataType;
typedef struct ListNode
{
struct ListNode* next;
struct ListNode* prev;
LTDataType data;
}LTNode;
//双向链表的建立、初始化、打印函数的声明
LTNode* BuyLTNode(LTDataType x);
LTNode* LTInit();
void LTPrint(LTNode* phead);
//尾插、尾删函数的声明
void LTPushBack(LTNode* phead, LTDataType x);
void LTPopBack(LTNode* phead);
//头插、头删函数的声明
void LTPushFront(LTNode* phead, LTDataType x);
void LTPopFront(LTNode* phead);
//链表长度计算函数的声明
int LTSize(LTNode* phead);
//链表查找函数的声明
LTNode* LTFind(LTNode* phead, LTDataType x);
//在pos位置插入函数的声明
void LTInsert(LTNode* pos, LTDataType x);
//在pos位置删除函数的声明
void LTErase(LTNode* pos)
2.Doubly_linked_list.c
c
#include"Doubly_linked_list.h"
LTNode* BuyLTNode(LTDataType x)
{
LTNode* node = (LTNode*)malloc(sizeof(LTNode));
if (node == NULL)
{
perror("malloc fail");
exit(-1);
}
node->data = x;
node->next = NULL;
node->prev = NULL;
return node;
}
LTNode* LTInit()
{
LTNode* phead = BuyLTNode(-1);
phead->next = phead;
phead->prev = phead;
return phead;
}
void LTPrint(LTNode* phead)
{
assert(phead);
printf("phead<=>");
LTNode* cur = phead->next;
while (cur != phead)
{
printf("%d<=>", cur->data);
cur = cur->next;
}
printf("\n");
}
void LTPushBack(LTNode* phead, LTDataType x)
{
assert(phead);
LTNode* tail = phead->prev;
LTNode* newnode = BuyLTNode(x);
newnode->prev = tail;
tail->next = newnode;
newnode->next = phead;
phead->prev = newnode;
}
void LTPopBack(LTNode* phead)
{
assert(phead);
assert(phead->next != phead);
LTNode* tail = phead->prev;
LTNode* tailPrev = tail->prev;
free(tail);
tailPrev->next = phead;
phead->prev = tailPrev;
}
void LTPushFront(LTNode* phead, LTDataType x)
{
assert(phead);
/*LTNode* newnode = BuyLTNode(x);
newnode->next = phead->next;
phead->next->prev = newnode;
phead->next = newnode;
newnode->prev = phead;*/
LTNode* newnode = BuyLTNode(x);
LTNode* first = phead->next;
phead->next = newnode;
newnode->prev = phead;
newnode->next = first;
first->prev = newnode;
}
void LTPopFront(LTNode* phead)
{
assert(phead);
assert(phead->next != phead);
LTNode* first = phead->next;
LTNode* second = first->next;
free(first);
phead->next = second;
second->prev = phead;
}
int LTSize(LTNode* phead)
{
assert(phead);
int size = 0;
LTNode* cur = phead->next;
while (cur != phead)
{
++size;
cur = cur->next;
}
return size;
}
void LTInsert(LTNode* pos, LTDataType x)
{
assert(pos);
LTNode* posPrev = pos->prev;
LTNode* newnode = BuyLTNode(x);
posPrev->next = newnode;
newnode->prev = posPrev;
newnode->next = pos;
pos->prev = newnode;
}
void LTErase(LTNode* pos)
{
assert(pos);
LTNode* posPrev = pos->prev;
LTNode* posNext = pos->next;
free(pos);
posPrev->next = posNext;
posNext->prev = posPrev;
}
3.Doubly_linked_list_test.c
c
#include"Doubly_linked_list.h"
void TestList()
{
LTNode* plist = LTInit();
LTPushBack(plist, 1);
LTPushBack(plist, 2);
LTPushBack(plist, 3);
LTPushBack(plist, 4);
LTPushBack(plist, 5);
LTPrint(plist);
LTPushFront(plist, 10);
LTPushBack(plist, 10);
LTPrint(plist);
}
int main()
{
TestList();
return 0;
}
总结
今天的双向链表学习就到这里啦!
希望大家好好学习!
天天都有进步!