文章目录
双向链表概念
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向前一块的地址和后一块的地址。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表
双向链表结构
typedef int LTDateType;
typedef struct ListNode
{
LTDateType val;
struct ListNode* next;
struct ListNode* prev;
}L
双向链表初始化
void ListInit(LTNode* head)
{
head->next = head;
head->prev = head;
}
创建节点函数
LTNode* BuyNewNode(LTDateType x)
{
LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
newnode->val = x;
newnode->next = NULL;
newnode->prev = NULL;
return newnode;
}
双向链表插入和删除
头插
void ListPushFront(LTNode* head, LTDateType x)
{
LTNode* newnode = BuyNewNode(x);
LTNode* cur = head;
LTNode* next = cur->next;
cur->next = newnode;
newnode->prev = newnode;
newnode->next = next;
next->prev = newnode;
}
尾插
void ListPushBack(LTNode* head, LTDateType x)
{
LTNode* newnode = BuyNewNode(x);
LTNode* cur = head;
LTNode* tail = cur->prev;
tail->next = newnode;
newnode->prev = tail;
cur->prev = newnode;
newnode->next = cur;
}
头删
void ListPopFront(LTNode* head)
{
assert(head);
assert(head->next != head);
LTNode* cur = head;
LTNode* next = cur->next;
LTNode* Nextnext = next->next;
cur->next = Nextnext;
Nextnext->prev = cur;
free(next);
}
尾删
void ListPopBack(LTNode* head)
{
assert(head);
assert(head->next != head);
LTNode* cur = head;
LTNode* tail = cur->prev;
LTNode* posPrev = tail->prev;
posPrev->next = cur;
cur->prev = posPrev;
free(tail);
}
指定位置插入
void ListInser(LTNode* head, LTNode* pos, LTDateType x)
{
LTNode* newnode = BuyNewNode(x);
LTNode* posprve = pos->prev;
//LTNode* next = pos->next;
posprve->next = newnode;
newnode->prev = posprve;
newnode->next = pos;
pos->prev = newnode;
}
指定位置删除
void ListErase(LTNode* head, LTNode* pos)
{
assert(head);
assert(head->next != head);
LTNode* posprve = pos->prev;
LTNode* next = pos->next;
posprve->next = next;
next->prev = posprve;
free(pos);
}
双向链表打印和寻找
打印
void ListPrin(LTNode* head)
{
assert(head);
LTNode* cur = head->next;
while (cur != head)
{
printf("%d ", cur->val);
cur = cur->next;
}
printf("\n");
}
寻找
LTNode* ListFind(LTNode* head, LTDateType x)
{
assert(head);
LTNode* cur = head->next;
while (cur != head)
{
if (cur->val == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
双向链表销毁
void ListDestory(LTNode* head)
{
assert(head);
LTNode* cur = head->next;
while (cur != head)
{
LTNode* next = cur->next;
free(cur);
cur = next;
}
free(head);
}
完整版代码
Test.c
#include "DList.h"
void TestList1()
{
LTNode* plist = (LTNode*)malloc(sizeof(LTNode));
ListInit(plist);
ListPushBack(plist, 1);
ListPushBack(plist, 2);
ListPushBack(plist, 3);
ListPushBack(plist, 4);
ListPrin(plist);
ListPopBack(plist);
ListPopBack(plist);
ListPopBack(plist);
ListPopBack(plist);
//ListPopBack(plist);
ListPrin(plist);
ListPushFront(plist, 1);
ListPushFront(plist, 2);
ListPushFront(plist, 3);
ListPushFront(plist, 4);
ListPrin(plist);
ListPopFront(plist);
ListPopFront(plist);
//ListPopFront(plist);
//ListPopFront(plist);
//ListPopFront(plist);
ListPrin(plist);
LTNode* pos = ListFind(plist, 2);
printf("%d\n", pos->val);
ListInser(plist, plist->next, 5);
ListPrin(plist);
ListInser(plist, plist, 5);
ListPrin(plist);
ListErase(plist, plist->next);
ListPrin(plist);
ListErase(plist, plist->prev);
ListPrin(plist);
}
int main()
{
TestList1();
return 0;
}
DList.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int LTDateType;
typedef struct ListNode
{
LTDateType val;
struct ListNode* next;
struct ListNode* prev;
}LTNode;
void ListInit(LTNode* head);
void ListPrin(LTNode* head);
void ListPushBack(LTNode* head,LTDateType x);
void ListPopBack(LTNode* head);
void ListPushFront(LTNode* head, LTDateType x);
void ListPopFront(LTNode* head);
LTNode* ListFind(LTNode* head, LTDateType x);
void ListInser(LTNode* head, LTNode* pos, LTDateType x);
void ListErase(LTNode* head, LTNode* pos);
LTNode* BuyNewNode(LTDateType x);
DList.c
#include "DList.h"
void ListInit(LTNode* head)
{
head->next = head;
head->prev = head;
}
void ListPrin(LTNode* head)
{
assert(head);
LTNode* cur = head->next;
while (cur != head)
{
printf("%d ", cur->val);
cur = cur->next;
}
printf("\n");
}
LTNode* BuyNewNode(LTDateType x)
{
LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
newnode->val = x;
newnode->next = NULL;
newnode->prev = NULL;
return newnode;
}
void ListPushBack(LTNode* head, LTDateType x)
{
LTNode* newnode = BuyNewNode(x);
LTNode* cur = head;
LTNode* tail = cur->prev;
tail->next = newnode;
newnode->prev = tail;
cur->prev = newnode;
newnode->next = cur;
}
void ListPopBack(LTNode* head)
{
assert(head);
assert(head->next != head);
LTNode* cur = head;
LTNode* tail = cur->prev;
LTNode* posPrev = tail->prev;
posPrev->next = cur;
cur->prev = posPrev;
free(tail);
}
void ListPushFront(LTNode* head, LTDateType x)
{
LTNode* newnode = BuyNewNode(x);
LTNode* cur = head;
LTNode* next = cur->next;
cur->next = newnode;
newnode->prev = newnode;
newnode->next = next;
next->prev = newnode;
}
void ListPopFront(LTNode* head)
{
assert(head);
assert(head->next != head);
LTNode* cur = head;
LTNode* next = cur->next;
LTNode* Nextnext = next->next;
cur->next = Nextnext;
Nextnext->prev = cur;
free(next);
}
LTNode* ListFind(LTNode* head, LTDateType x)
{
assert(head);
LTNode* cur = head->next;
while (cur != head)
{
if (cur->val == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
void ListInser(LTNode* head, LTNode* pos, LTDateType x)
{
LTNode* newnode = BuyNewNode(x);
LTNode* posprve = pos->prev;
//LTNode* next = pos->next;
posprve->next = newnode;
newnode->prev = posprve;
newnode->next = pos;
pos->prev = newnode;
}
void ListErase(LTNode* head, LTNode* pos)
{
assert(head);
assert(head->next != head);
LTNode* posprve = pos->prev;
LTNode* next = pos->next;
posprve->next = next;
next->prev = posprve;
free(pos);
}