带头循环双链表
链表的概念及结构:
概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。
带头循环双链表比一般无头单链表多一个头节点和还带有一个前置指针,
这里要注意有个头结点,且有前后指针才可以实现循环,写功能时思路必须要清晰。
头文件 功能定义
// 带头+双向+循环链表增删查改实现
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int LTDataType;
typedef struct ListNode
{
LTDataType data;
struct ListNode* next;
struct ListNode* prev;
}ListNode;
// 创建返回链表的头结点.
ListNode* ListCreate();
//创建节点
ListNode* Buynode(LTDataType x);
// 双向链表销毁
void ListDestory(ListNode* plist);
// 双向链表打印
void ListPrint(ListNode* plist);
// 双向链表尾插
void ListPushBack(ListNode* plist, LTDataType x);
// 双向链表尾删
void ListPopBack(ListNode* plist);
// 双向链表头插
void ListPushFront(ListNode* plist, LTDataType x);
// 双向链表头删
void ListPopFront(ListNode* plist);
// 双向链表查找
ListNode* ListFind(ListNode* plist, LTDataType x);
// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x);
// 双向链表删除pos位置的节点
void ListErase(ListNode* pos);
函数功能实现
#include"DSList.h"
// 创建返回链表的头结点.
ListNode* ListCreate()
{
ListNode* head = (ListNode*)malloc(sizeof(ListNode));
if (head != NULL)//申请空间成功
{//头节点前后指针都指向自己
head->next = head;
head->prev = head;
}
return head;
}
//创建节点
ListNode* Buynode(LTDataType x)
{
ListNode* node = (ListNode*)malloc(sizeof(ListNode));
if (node != NULL)//申请空间成功
node->data = x;
node->prev = NULL;
node->next = NULL;
return node;
}
// 双向链表销毁
void ListDestory(ListNode* plist)
{
ListNode* cur = plist->next;
while (cur!= plist)
{
ListNode* Next = cur->next;//先保留下一个节点
free(cur);
cur = NULL;
cur=Next;//迭代着
}
}
// 双向链表打印
void ListPrint(ListNode* plist)
{
assert(plist);
ListNode* cur = plist->next;
while (cur != plist)
{
printf("%d->", cur->data);
cur = cur->next;
}
printf("\n");
}
// 双向链表尾插
void ListPushBack(ListNode* plist, LTDataType x)
{
assert(plist);
ListNode* newnode = Buynode(x);
// phead tail newnode
ListNode* tail = pHead->prev;
tail->next = newnode;
newnode->prev = tail;
newnode->next = pHead;
pHead->prev = newnode;
}
// 双向链表尾删
void ListPopBack(ListNode* plist)
{
ListNode* cur= plist->prev->prev;
ListNode* tail = plist->prev;
if (plist->next == plist)//只有一个头结点
{
return ;
}
else
//头节点 tail 尾节点
{
cur->next = plist;
plist->prev = cur;
free(tail);
tail = NULL;
}
}
// 双向链表头插
void ListPushFront(ListNode* plist, LTDataType x)
{
ListNode* newnode = Buynode(x);
ListNode* first = pHead->next;
pHead->next = newnode;
newnode->prev = pHead;
newnode->next = first;
first->prev = newnode;
}
// 双向链表头删
void ListPopFront(ListNode* plist)
{
ListNode* first= plist->next;
if (plist->next == plist)//只有一个头节点
return;
else
{
plist->next = first->next;
first->next->prev = plist;
free(first);
first = NULL;
}
}
// 双向链表查找
ListNode* ListFind(ListNode* plist, LTDataType x)
{
assert(plist);
ListNode* head = plist->next;
if (head == plist)
return;
while (head != plist)
{
if (head->data == x)
{
return head;
}
head = head->next;
}
}
// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x)
{
assert(pos);
// pos->prev newnode pos
ListNode* newnode = Buynode(x);
newnode->next = pos;
pos->prev->next= newnode;
pos->prev = newnode;
newnode->prev = pos->prev;
}
// 双向链表删除pos位置的节点
void ListErase(ListNode* pos)
{
// pos->prev 删除pos pos->next
pos->prev->next = pos->next;
pos->next->prev = pos->prev;
free(pos);
pos = NULL;
}
功能测试
#include <stdio.h>
#include "DSList.h"
void TestDSList1()
{
ListNode* plist = NULL;
plist=ListCreate();
ListPushBack(plist, 1);
ListPushBack(plist, 2);
ListPushBack(plist, 3);
ListPushBack(plist, 4);
ListPrint(plist);
}
void TestDSList2()
{
ListNode* plist = ListCreate();
ListPushFront(plist, 1);
ListPushFront(plist, 2);
ListPushFront(plist, 3);
ListPushFront(plist, 4);
ListPrint(plist);
}
void TestDSList3()
{
ListNode* plist = ListCreate();
ListPushBack(plist, 1);
ListPushBack(plist, 2);
ListPushBack(plist, 3);
ListPushFront(plist, 4);
ListPopFront(plist);
ListPopBack(plist);
ListPrint(plist);
}
void TestDSList4()
{
ListNode* plist = ListCreate();
ListPushBack(plist, 1);
ListPushBack(plist, 2);
ListPushBack(plist, 3);
ListPushBack(plist, 4);
ListInsert(ListFind(plist, 1), 100);
//ListErase(ListFind(plist, 2));
ListPrint(plist);
}
int main()
{
TestDSList4();
return 0;
}