实现一个有头结点有环的双链表

        在之前的博客里我们讲到了不带头节点不带环的单向链表,今天我们来实现一个有头结点有环的双向链表。

        我们首先设置一个头结点,这个头结点的数据是无意义的,我们再设置一个环,让这个链表的尾巴指向头称为一个带环链表。相比于之前的单向链表,这次我们多加了一个prev指针,成为双向链表。如图就是我们的有头有环的双向链表。画的太丑了....

        

        话不多说,直接看代码


        DLinkList.h

        

#pragma once
#include <stdio.h>
#include <stdlib.h>
typedef char DLinkType;
typedef struct DLinkNode{
        DLinkType data;
        struct DLinkNode* next;
        struct DLinkNode* prev;
}DLinkNode;

void DLinkListInit(DLinkNode** head);//初始化

void DLinkListPushBack(DLinkNode* head,DLinkType value);//尾插

void DLinkListPopBack(DLinkNode* head);//尾删

void DLinkListPushFront(DLinkNode* head,DLinkType value);//头插

void DLinkListPopFront(DLinkNode* head);//头删

DLinkNode* DLinkListFind(DLinkNode* head,DLinkType to_find);//查找

void DLinkListInsertBefore(DLinkNode* pos,DLinkType value);//任意位置之前插入

void DLinkListInsertAfter(DLinkNode* pos,DLinkType value);//任意位置之后插入

void DLinkListErase(DLinkNode* pos);//任意位置删除

void DLinkListRemove(DLinkNode* head,DLinkType to_delete);//根据元素删除链表中第一个指定元素

void DLinkListRemoveAll(DLinkNode* head,DLinkType to_delete);//根据元素删除链表中所有指定元素

size_t DLinkListSize(DLinkNode* head);//链表长度

int DLinkListEmpty(DLinkNode* head);//判断链表是否为空
DLinkList.c
#include <stdio.h>
#include <stdlib.h>
#include "DLinkList.h"

DLinkNode* CreatDNode(DLinkType value){//创建新结点
    DLinkNode* ptr = (DLinkNode*)malloc(sizeof(DLinkNode));
    ptr->data = value;
    ptr->next = ptr;
    ptr->prev = ptr;
    return ptr;


}

void DLinkListPrint(DLinkNode* head){//打印函数
    DLinkNode* cur1 = head->next;
    DLinkNode* cur2 = head->prev;
    while(cur1 != head){
        printf("[%c|%p] ",cur1->data,cur1);
        cur1 = cur1->next;

    }
    printf("\n");
    while(cur2 != head){
        printf("[%c|%p] ",cur2->data,cur2);
        cur2 = cur2->prev;

    }
    printf("\n");

}

void DLinkListInit(DLinkNode** head){//初始化
    if(head == NULL){
        return;

    }
    *head = CreatDNode(0);

}

void DLinkListPushBack(DLinkNode* head,DLinkType value){//尾插
    if(head == NULL){
        return;

    }
    DLinkNode* tail = head->prev;
    DLinkNode* new_node = CreatDNode(value);
    tail->next = new_node;
    new_node->prev = tail;
    head->prev = new_node;
    new_node->next = head;

}

void Destory(DLinkNode* cur)//销毁函数
{
        free(cur);
}

void DLinkListPopBack(DLinkNode* head)//尾删
{
    if(head == NULL)
    {
        return;
    }
    DLinkNode* delete = head->prev;
    DLinkNode* tail = delete->prev;
    tail->next = head;
    head->prev = tail;
    Destory(delete);

}
void DLinkListPushFront(DLinkNode* head,DLinkType value)//头插
{
    if(head == NULL)
    {
        return;
    }
    DLinkNode* new_node = CreatDNode(value);
    DLinkNode* after = head->next;
    head->next = new_node;
    new_node->prev = head;
    new_node->next = after;
    after->prev = new_node;

}

void DLinkListPopFront(DLinkNode* head)//头删
{
    if(head == NULL)
    {
        return;
    }
    DLinkNode* delete = head->next;
    DLinkNode* after = delete->next;
    head->next = after;
    after->prev = head;
    Destory(delete);
}

DLinkNode* DLinkListFind(DLinkNode* head,DLinkType to_find)//查找元素
{
    if(head == NULL)
    {
        return;
    }
    DLinkNode* cur = head->next;
    while(cur != head)
    {
        if(cur->data == to_find)
        {
            return cur;
        }
        else
        {
            cur = cur->next;
        }

    }
    return NULL;
}

void DLinkListInsertBefore(DLinkNode* pos,DLinkType value)//任意位置之前插入
{
    if(pos == NULL)
    {
        return;
    }
    DLinkNode* before = pos->prev;
    DLinkNode* new_node = CreatDNode(value);
    before->next = new_node;
    new_node->prev = before;
    new_node->next = pos;
    pos->prev = new_node;
}

void DLinkListInsertAfter(DLinkNode* pos,DLinkType value)//任意位置之后插入
{
    if(pos == NULL)
    {

        return;
    }
    DLinkNode* after = pos->next;
    DLinkNode* new_node = CreatDNode(value);
 pos->next = new_node;
    new_node->prev = pos;
    new_node->next = after;
    after->prev = new_node;
}

void DLinkListErase(DLinkNode* pos)//任意位置删除
{
    if(pos == NULL)
    {
        return;

    }
    DLinkNode* after = pos->next;
    DLinkNode* before = pos->prev;
    before->next = after;
    after->prev = before;
    Destory(pos);

}
void DLinkListRemove(DLinkNode* head,DLinkType value)//根据元素删除链表中第一个指定元素
{
    if(head == NULL)
    {
        return;
    }
    DLinkListErase(DLinkListFind(head,value));
}
void DLinkListRemoveAll(DLinkNode* head,DLinkType value)//根据元素删除链表中所有指定元素
{
    if(head == NULL)
    {
        return;
    }
    DLinkNode* cur = head->next;
    while(cur!=head)
    {
        DLinkListErase(DLinkListFind(head,value));
        cur = cur->next;


    }
}

size_t DLinkListSize(DLinkNode* head)//链表长度
{
    if(head == NULL)
    {
        return;
    }
    size_t i = 0;
    DLinkNode* cur = head->next;
    while(cur!= head)
    {
        i++;
        cur = cur->next;
    }
    return i;
}

int DLinkListEmpty(DLinkNode* head)//判断链表是否为空
{
    if(head == NULL)
    {
        return -1;
    }
    if(head->next == head)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}
//test.c 测试函数
void test_DLinkListPushBack(){
    printf("*******尾插*******\n");
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPrint(head);
}


void test_DLinkListPopBack(){
    printf("*******尾删*******\n");
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPrint(head);
    DLinkListPopBack(head);
    DLinkListPrint(head);
}

void test_DLinkListPushFront(){
    printf("*******头插*******\n");
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushFront(head,'a');
    DLinkListPushFront(head,'b');
    DLinkListPushFront(head,'c');
    DLinkListPushFront(head,'d');
    DLinkListPrint(head);
}
void test_DLinkListPopFront(){
    printf("*******头删*******\n");
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPrint(head);
    DLinkListPopFront(head);
    DLinkListPrint(head);
}
void test_DLinkListFind(){
    printf("*******查找元素*******\n");
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPrint(head);
    DLinkNode* i = DLinkListFind(head,'b');
    printf("找到b元素的地址为:%p\n",i);
}
void test_DLinkListInsertBefore(){
    printf("*******任意位置之前插入元素*******\n");
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPrint(head);
    DLinkListInsertBefore(DLinkListFind(head,'c'),'m');
    DLinkListPrint(head);
}
void test_DLinkListInsertAfter(){
    printf("*******任意位置之后插入元素*******\n");
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPrint(head);
    DLinkListInsertAfter(DLinkListFind(head,'c'),'m');
    DLinkListPrint(head);
}
void test_DLinkListErase(){
    printf("*******任意位置删除元素*******\n");
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPrint(head);
    DLinkListErase(DLinkListFind(head,'b'));
    DLinkListPrint(head);
}
void test_DLinkListRemove(){
    printf("*******根据元素值删除链表中第一个指定元素*******\n");
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPrint(head);
    DLinkListRemove(head,'b');
    DLinkListPrint(head);
}
void test_DLinkListRemoveAll(){
    printf("*******根据元素值删除链表中所有指定元素*******\n");
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPrint(head);
    DLinkListRemoveAll(head,'b');
    DLinkListPrint(head);
}
void test_DLinkListSize(){
    printf("*******链表长度*******\n");
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPrint(head);
    size_t i = DLinkListSize(head);
    printf("链表长度为:%d\n",i);
}
void test_DLinkListEmpty()
{
    printf("*******判断链表是否为空*******\n");
    DLinkNode* head;
    DLinkListInit(&head);
    int i = DLinkListEmpty(head);
    printf("返回值为:%d\n",i);
}
int main()        //main函数
{
    test_DLinkListPushBack();
    test_DLinkListPopBack();
    test_DLinkListPushFront();
    test_DLinkListPopFront();
    test_DLinkListFind();
    test_DLinkListInsertBefore();
    test_DLinkListInsertAfter();
    test_DLinkListErase();
    test_DLinkListRemove();
    test_DLinkListRemoveAll();
    test_DLinkListSize();
    test_DLinkListEmpty();
}

        运行结果

        

        

猜你喜欢

转载自blog.csdn.net/yummy_alice/article/details/79833975
今日推荐