数据结构---带头结点的双向链表的增删查改1(C语言实现)

实现环境:LINUX

带头结点的增删查改相对而言比较简单,但是里边还是有些许坑,,稍不注意就掉进去,半天爬不出来。



                                                   将要实现的链表的图:

在双向链表中需要注意的是要注意两组指针的指向,即next和prev对应。双向链表已经可以说完成一半了。


在一个需要注意的坑是,在插入的时候需要注意的是一定要先new与node2然后在进行其他的操作,不然node1与node2之间指向断开,就会指向随机值,我就在这个坑了怕了一个多小时,才调试出来。

代码实现:

LinkList.c:

#include "LinkList.h"
#include<stdio.h>
#include<stdlib.h>

//实现创建
DLinkNode* DLinkListCreatNode(DLinkType value){
    DLinkNode* New_Node = (DLinkNode*)malloc(sizeof(DLinkNode));
    New_Node->data = value;
    New_Node->next = NULL;
    New_Node->prev = NULL;
    return New_Node;
}

//实现打印
void DLinkListPrint(DLinkNode* head,const char* msg){
    if(head == NULL){
        printf("非法输入\n");
        return;
    }
    printf("[*****%s*****]\n",msg);
    DLinkNode* cur = head->next;
    for(; cur != head; cur = cur->next){
        printf("[%c|%p]\t",cur->data,cur);
    }
    printf("\n");
    return;
}

//实现初始化
void DLinkListInit(DLinkNode** head){
    if(head == NULL){
        //非法输入
        return;
    } 
    *head =DLinkListCreatNode(0);
    (*head)->prev = *head;
    (*head)->next = *head;
    return;
}

//实现尾插
void DLinkListPushBack(DLinkNode* head, DLinkType value){
    if(head == NULL){
        //非法输入
        return;
    }
    DLinkNode* New_Node = DLinkListCreatNode(value);
    New_Node->data = value;
    DLinkNode* tail = head->prev;
   //此时三个值 tail(原来的末尾)  head(头)  New_Node(新加入的值,现在的末尾)
   //实现两组指针的指向prev和next的指向
   New_Node->next = head;
   head->prev = New_Node;
   New_Node->prev = tail;
   tail->next = New_Node;
}

//尾删
void DLinkListPopBack(DLinkNode* head){
    if(head == NULL){
        //非法输入
        return;
    }
    if(head->next == NULL){
        //空链表
        return;
    }
    DLinkNode* tailprev = head->prev->prev;
    free(tailprev->next);
    tailprev->next = head;
    head->prev = tailprev;
}

//头插
void DLinkListPushFront(DLinkNode*head, DLinkType value){
    if(head == NULL){
        //非法输入
        return;
    }
    DLinkNode* New_Node = DLinkListCreatNode(value);
    New_Node->next = head->next;
    New_Node->next->prev = New_Node;
    head->next = New_Node;
    New_Node->prev = head;
}

//头删
void DLinkListPopFront(DLinkNode* head){
    if(head == NULL){
        //非法输入
        return;
    }
    if(head->next == NULL){
        printf("空链表\n");
        return;
    }
    DLinkNode* to_deleted = head->next;
    head->next = to_deleted->next;
    to_deleted->next->prev = head;
    free(to_deleted);
}

//查找
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;
        }
            cur = cur->next;
    }
    return NULL;
}

//在指定位置之前插入一个元素
void DLinkListInsert(DLinkNode* pos,DLinkType value){
    if(pos == NULL){
        return;
    }
    DLinkNode* New_Node = DLinkListCreatNode(value);
    DLinkNode* cur = pos->prev;
    cur->next = New_Node;
    New_Node->prev = cur;
    New_Node->next = pos;
    pos->prev = New_Node;
}

//在制定元素位置之后插入一个元素
void DLinkListInsertAfter(DLinkNode* pos,DLinkType value){
    if(pos == NULL){
        return;
    }
    DLinkNode* New_Node = DLinkListCreatNode(value);
    DLinkNode* Next_Node =pos->next;
    New_Node->next = Next_Node;
    Next_Node->prev = New_Node;
    pos->next = New_Node;
    New_Node->prev = pos;
}


//////////////////////////////////////////////
//********************************************
//*********Test Code**************************
//////////////////////////////////////////////

//测试尾插
void TestDLinkListPushBack(){
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPrint(head,"尾插元素");
}

//测试尾删
void TestDLinkListPopBack(){
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPopBack(head);
    DLinkListPrint(head,"尾删元素");
}

//测试头插
void TestDLinkListPushFront(){
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushFront(head,'a');
    DLinkListPushFront(head,'b');
    DLinkListPushFront(head,'c');
    DLinkListPushFront(head,'d');
    DLinkListPrint(head,"头插元素");
}

//测试头删
void TestDLinkListPopFront(){
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPopFront(head);
    DLinkListPrint(head,"头删元素");
}

//测试在一个元素之前插入
void TestDLinkListInsert(){
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkNode* pos = DLinkListFind(head,'c');
    DLinkListInsert(pos,'x');
    DLinkListPrint(head,"在元素之前插入一个元素");
}


//测试在一个元素之后插入
void TestDLinkListInsertAfter(){
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkNode* pos = DLinkListFind(head,'c');
    DLinkListInsertAfter(pos,'x');
    DLinkListPrint(head,"在元素之后插入一个元素");
}

int main(){
    TestDLinkListPushBack();
    TestDLinkListPopBack();
    TestDLinkListPushFront();
    TestDLinkListPopFront();
    TestDLinkListInsert();
    TestDLinkListInsertAfter();
    return 0;
}

LinkList.h:

#pragma once

typedef char DLinkType;

typedef struct DLinkNode{
    DLinkType data;
    struct DLinkNode* next;     //指向下一个结点
    struct DLinkNode* prev;     //指向上一个结点
}DLinkNode;

//创建一个新结点
DLinkNode* DLinkListCreatNode(DLinkType value);

//打印
void DLinkListPrint(DLinkNode* head,const char* msg);

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

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

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

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

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


猜你喜欢

转载自blog.csdn.net/devil_net/article/details/79851461