数据结构02:双链表

构建双链表

建立双链表结构、初始化含有头结点的双链表
typedef double elementType;
typedef struct DNode{
    elementType data;
    struct DNode *prior,*next;
}D_LNode,*D_linkedList;


bool Init_D_linkList(D_linkedList *L){
    *L = (D_LNode*) malloc(sizeof(D_LNode));
    /*设置头节点*/
    if(*L == nullptr){
        return false;/*内存分配失败*/
    }
    (*L)->prior = nullptr;
    (*L)->next = nullptr;
    return true;
}
初始化之后用尾插法建立双链表
bool Init_D_list_end(D_linkedList *L){
    if((*L) == nullptr){
        return false;
    }
    D_LNode* p = *L;
    int x = 0;
    std::cin >> x;
    while(x != -10000){
        D_LNode* s = (D_LNode*)malloc(sizeof(D_LNode));
        s->data = x;
        p->next = s;
        s->prior = p;
        s->next = nullptr;
        p = s;
        std::cin >> x;
    }
    return true;
}
初始化之后使用头插法建立双链表
bool Init_D_list_first(D_linkedList *L){
    if((*L) == nullptr){
        return false;
    }
    D_LNode* p = *L;
    D_LNode* q = *L;
    int x = 0;
    std::cin >> x;
    while(x != -10000){
        D_LNode* s = (D_LNode*)malloc(sizeof(D_LNode));
        s->data = x;
        if(q->next == nullptr){
            p->next = s;
            s->prior = p;
            s->next = nullptr;
        }
        else{
            p = q->next;
            p->prior = s;
            s->next = p;
            s->prior = q;
            q->next = s;
        }
        std::cin >> x;
    }
    return true;
}

从某个结点出发向后打印i个结点的数据(如果打印到末尾了就停止)

bool D_linkedList_Print(D_LNode *L,int i){
    /*从p结点开始打印i个结点,如果不够i个则打印到该链表的最后一个*/
    D_LNode* p = L;
    if(p == nullptr){
        return false;
    }
    int number = 0;
    D_LNode *q = p;
    for (int j = 0; j < i; j++) {
        q = q->next;
        if (q == nullptr) {
            break;
        }
        std::cout << q->data << "  ";
    }
    std::cout << std::endl;
    return true;
}

获取链表长度

获取从某个结点开始往后直到末尾的长度(包括这个结点)
int getNextLength(D_LNode* L){
    /*统计p结点开始,后面还有多少个结点
     * (如果P不是头结点则,则计入P)*/
    D_LNode* p = L;
    if(p == nullptr){
        return -1;
    }
    int number = 1;
    if(p->prior == nullptr){
        /*p是头结点*/
        number = 0;
    }
    while(p != nullptr){
        p = p->next;
        if(p != nullptr){
            number++;
        }
    }
    return number;
}
从某个结点开始获取从它出发到第一个数据结点的结点总数(不包括头结点)
int getPriorLength(D_LNode* L){
    /*统计p结点之前有多少数据结点(包括p本身,但是不计入头结点)*/
    D_LNode* p = L;
    if(p == nullptr){
        return -1;
    }
    int number = 1;
    if(p->prior == nullptr){
        /*如果p是头结点*/
        return 0;
    }
    while(p != nullptr){
        p = p->prior;
        if(p != nullptr){
            number++;
        }
    }
    return number;
}

根据指定索引位置查找结点

D_LNode* getD_LNode_Index(D_linkedList *L, int i){
    /*按位查找*/
    if(i < 0 || (*L) == nullptr){
        return nullptr;
    }
    int j = 0;
    D_LNode* p = *L;
    while(p != nullptr && j < i){
        p = p->next;
        j++;
    }
    return p;
}

插入结点

在P结点之后插入结点s
bool insertNextD_LNode(D_LNode* p, D_LNode* s){
    /*在结点p之后插入结点s*/
    if(p == nullptr || s == nullptr){
        return false;
    }
    s->next = p->next;
    s->prior = p;
    if(p->next != nullptr){
        p->next->prior = s;
    }
    p->next = s;
    return true;
}
在P结点之前插入结点s
bool insertPriorD_LNode(D_LNode* p, D_LNode* s){
    /*在结点p(p不是头结点)之前插入结点s*/
    if(p == nullptr || s == nullptr || p->prior == nullptr){
        /*p的前驱结点如果不存在,则p也就是头结点,
         * 不可能在头结点之前在插入新的数据结点*/
        return false;
    }
    p->prior->next = s;
    s->prior = p->prior;
    p->prior = s;
    s->next = p;
}
在指定索引位置之后插入新数据构成的结点
bool insertD_LNode_index_new(D_linkedList *L, int i, elementType element){
    D_LNode* q = *L;
    D_LNode* s = (D_LNode*)malloc(sizeof(D_LNode));
    s->data = element;
    D_LNode* p = getD_LNode_Index(&q,i-1);
    return insertNextD_LNode(p,s);
}

删除结点

删除P结点的后继结点
bool deleteNextD_LNode(D_LNode* p){
    /*删除p结点的后继结点*/
    if(p == nullptr || p->next == nullptr){
        return false;
    }
    D_LNode* q = p->next;
    if(q->next != nullptr){
        q->next->prior = p;
    }
    p->next = q->next;
    free(q);
    return true;
}
删除P结点的前驱结点
bool deletePriorD_LNode(D_LNode* p){
    /*删除p结点的前驱结点
     * 只能删除从索引2-n的结点前驱结点*/
    if(p == nullptr || p->prior == nullptr || p->prior->prior == nullptr){
        return false;
    }
    D_LNode* q = p->prior;
    q->prior->next = p;
    p->prior = q->prior;
    free(q);
    return true;
}
删除指定结点P
bool deleteD_LNode(D_LNode* p){
    /*删除结点p*/
    if(p == nullptr || p->prior == nullptr){
        return false;
    }
    D_LNode* s = p->prior;
    s->next = p->next;
    p->next->prior = s;
    free(p);
    return true;
}
根据指定索引位置删除结点
bool deleteD_LNode_index_new(D_linkedList *L, int i){
    D_LNode* q = *L;
    D_LNode* p = getD_LNode_Index(&q,i-1);
    return deleteNextD_LNode(p);
}

测试结果

E:\CODING__ALAN_CF\cmake-build-debug\Double_linkList_test.exe
尾插法构建双链表:
1 2 3 4 5 6 7 8 9 -10000
打印该链表:1  2  3  4  5  6  7  8  9

头插法构建双链表:
1 2 -10000
打印该链表:2  1

在头结点之后,插入新数据结点s:
输入新节点的数据:195778
打印该链表:195778  1  2  3  4  5  6  7  8  9
此时链表总长度为:10

在第一个数据结点之前,插入新数据结点s:
输入新节点的数据:195779
打印该链表:195779  195778  1  2  3  4  5  6  7  8
此时链表总长度为:11

在指定索引位置之后插入新数据(位置3):
打印该链表:195779  195778  195781  1  2  3  4  5  6  7
此时链表总长度为:12

删除指定结点的后继结点(删除第三个数据结点):
打印该链表:195779  195778  1  2  3  4  5  6  7  8
此时链表总长度为:11

删除指定结点的前驱结点(删除第二个数据结点的前驱结点):
打印该链表:195778  1  2  3  4  5  6  7  8  9
此时链表总长度为:10

删除指定结点(给结点,没给结点位置(测试中删除第二个数据结点):
打印该链表:195778  2  3  4  5  6  7  8  9
此时链表总长度为:9

获取指定索引位置的结点(位置3):
该结点的数据为:3
打印该链表:195778  2  3  4  5  6  7  8  9
此时链表总长度为:9

删除指定索引位置的结点(位置3):
打印该链表:195778  2  4  5  6  7  8  9
此时链表总长度为:8

进程已结束,退出代码为 0

.h双链表文件

//
// Created by 15328 on 2022/1/21.
//

#ifndef CODING__ALAN_CF_DOUBLE_LINKEDLIST_H
#define CODING__ALAN_CF_DOUBLE_LINKEDLIST_H
#include<bits/stdc++.h>
typedef double elementType;
typedef struct DNode{
    elementType data;
    struct DNode *prior,*next;
}D_LNode,*D_linkedList;
bool Init_D_linkList(D_linkedList *L){
    *L = (D_LNode*) malloc(sizeof(D_LNode));
    /*设置头节点*/
    if(*L == nullptr){
        return false;/*内存分配失败*/
    }
    (*L)->prior = nullptr;
    (*L)->next = nullptr;
    return true;
}
bool isEmpty(D_linkedList *L){
    if((*L)->next == nullptr && (*L)->prior == nullptr){
        return true;
    }
    return false;
}
bool insertNextD_LNode(D_LNode* p, D_LNode* s){
    /*在结点p之后插入结点s*/
    if(p == nullptr || s == nullptr){
        return false;
    }
    s->next = p->next;
    s->prior = p;
    if(p->next != nullptr){
        p->next->prior = s;
    }
    p->next = s;
    return true;
}
bool insertPriorD_LNode(D_LNode* p, D_LNode* s){
    /*在结点p(p不是头结点)之前插入结点s*/
    if(p == nullptr || s == nullptr || p->prior == nullptr){
        /*p的前驱结点如果不存在,则p也就是头结点,
         * 不可能在头结点之前在插入新的数据结点*/
        return false;
    }
    p->prior->next = s;
    s->prior = p->prior;
    p->prior = s;
    s->next = p;
}
bool insertNextD_LNode_index(D_linkedList *L,int i,elementType element){
    /*在指定索引位置的结点之后插入新数据的结点
     * 从头结点之后的第一个数据结点计数为1*/
    if(i < 1){
        return false;
    }
    int j = 0;
    D_LNode* p = *L;
    D_LNode* s = (D_LNode*)malloc(sizeof(D_LNode));
    s->data = element;
    while(p != nullptr && j < i - 1){
        p = p->next;
        j++;
    }
    if(p == nullptr){
        return false;
    }
    insertNextD_LNode(p,s);
    return true;
}
bool deleteNextD_LNode(D_LNode* p){
    /*删除p结点的后继结点*/
    if(p == nullptr || p->next == nullptr){
        return false;
    }
    D_LNode* q = p->next;
    if(q->next != nullptr){
        q->next->prior = p;
    }
    p->next = q->next;
    free(q);
    return true;
}
bool deletePriorD_LNode(D_LNode* p){
    /*删除p结点的前驱结点
     * 只能删除从索引2-n的结点前驱结点*/
    if(p == nullptr || p->prior == nullptr || p->prior->prior == nullptr){
        return false;
    }
    D_LNode* q = p->prior;
    q->prior->next = p;
    p->prior = q->prior;
    free(q);
    return true;
}
bool deleteD_LNode(D_LNode* p){
    /*删除结点p*/
    if(p == nullptr || p->prior == nullptr){
        return false;
    }
    D_LNode* s = p->prior;
    s->next = p->next;
    p->next->prior = s;
    free(p);
    return true;
}
bool deleteD_LNode_index(D_linkedList *L, int i){
    /*删除第i个数据结点*/
    if(i < 1 || (*L) == nullptr){
        return false;
    }
    int j = 0;
    D_LNode* p = *L;
    while(p != nullptr && j < i - 1){
        p = p->next;
        j++;
    }
    return deleteNextD_LNode(p);
}
D_LNode* getD_LNode_Index(D_linkedList *L, int i){
    /*按位查找*/
    if(i < 0 || (*L) == nullptr){
        return nullptr;
    }
    int j = 0;
    D_LNode* p = *L;
    while(p != nullptr && j < i){
        p = p->next;
        j++;
    }
    return p;
}
bool insertD_LNode_index_new(D_linkedList *L, int i, elementType element){
    D_LNode* q = *L;
    D_LNode* s = (D_LNode*)malloc(sizeof(D_LNode));
    s->data = element;
    D_LNode* p = getD_LNode_Index(&q,i-1);
    return insertNextD_LNode(p,s);
}
bool deleteD_LNode_index_new(D_linkedList *L, int i){
    D_LNode* q = *L;
    D_LNode* p = getD_LNode_Index(&q,i-1);
    return deleteNextD_LNode(p);
}
int getNextLength(D_LNode* L){
    /*统计p结点开始,后面还有多少个结点
     * (如果P不是头结点则,则计入P)*/
    D_LNode* p = L;
    if(p == nullptr){
        return -1;
    }
    int number = 1;
    if(p->prior == nullptr){
        /*p是头结点*/
        number = 0;
    }
    while(p != nullptr){
        p = p->next;
        if(p != nullptr){
            number++;
        }
    }
    return number;
}
int getPriorLength(D_LNode* L){
    /*统计p结点之前有多少数据结点(包括p本身,但是不计入头结点)*/
    D_LNode* p = L;
    if(p == nullptr){
        return -1;
    }
    int number = 1;
    if(p->prior == nullptr){
        /*如果p是头结点*/
        return 0;
    }
    while(p != nullptr){
        p = p->prior;
        if(p != nullptr){
            number++;
        }
    }
    return number;
}
bool D_linkedList_Print(D_LNode *L,int i){
    /*从p结点开始打印i个结点,如果不够i个则打印到该链表的最后一个*/
    D_LNode* p = L;
    if(p == nullptr){
        return false;
    }
    int number = 0;
    D_LNode *q = p;
    for (int j = 0; j < i; j++) {
        q = q->next;
        if (q == nullptr) {
            break;
        }
        std::cout << q->data << "  ";
    }
    std::cout << std::endl;
    return true;
}
bool Init_D_list_end(D_linkedList *L){
    if((*L) == nullptr){
        return false;
    }
    D_LNode* p = *L;
    int x = 0;
    std::cin >> x;
    while(x != -10000){
        D_LNode* s = (D_LNode*)malloc(sizeof(D_LNode));
        s->data = x;
        p->next = s;
        s->prior = p;
        s->next = nullptr;
        p = s;
        std::cin >> x;
    }
    return true;
}
bool Init_D_list_first(D_linkedList *L){
    if((*L) == nullptr){
        return false;
    }
    D_LNode* p = *L;
    D_LNode* q = *L;
    int x = 0;
    std::cin >> x;
    while(x != -10000){
        D_LNode* s = (D_LNode*)malloc(sizeof(D_LNode));
        s->data = x;
        if(q->next == nullptr){
            p->next = s;
            s->prior = p;
            s->next = nullptr;
        }
        else{
            p = q->next;
            p->prior = s;
            s->next = p;
            s->prior = q;
            q->next = s;
        }
        std::cin >> x;
    }
    return true;
}
#endif //CODING__ALAN_CF_DOUBLE_LINKEDLIST_H

.cpp测试文件

//
// Created by 15328 on 2022/1/21.
//
#include"Double_linkedList.h"
void test(){
    D_linkedList L1,L2;

    std::cout << "尾插法构建双链表:\n";
    Init_D_linkList(&L1);
    Init_D_list_end(&L1);
    std::cout << "打印该链表:";
    D_linkedList_Print(L1,10);

    std::cout << "\n头插法构建双链表:\n";
    Init_D_linkList(&L2);
    Init_D_list_first(&L2);
    std::cout << "打印该链表:";
    D_linkedList_Print(L2,10);

    D_LNode* p = L1;
    D_LNode* q = L2;

    std::cout << "\n在头结点之后,插入新数据结点s:\n";
    D_LNode* p1 = p;
    D_LNode* s1 = (D_LNode*)malloc(sizeof(D_LNode));
    std::cout << "输入新节点的数据:";
    int element = 0;
    std::cin >> element;
    s1->data = element;
    insertNextD_LNode(p1,s1);
    std::cout << "打印该链表:";
    D_linkedList_Print(p,10);
    std::cout << "此时链表总长度为:" << getNextLength(p) << std::endl;

    std::cout << "\n在第一个数据结点之前,插入新数据结点s:\n";
    D_LNode* p2 = p->next;
    D_LNode* s2 = (D_LNode*)malloc(sizeof(D_LNode));
    std::cout << "输入新节点的数据:";
    std::cin >> element;
    s2->data = element;
    insertPriorD_LNode(p2,s2);
    std::cout << "打印该链表:";
    D_linkedList_Print(p,10);
    std::cout << "此时链表总长度为:" << getNextLength(p) << std::endl;

    std::cout << "\n在指定索引位置之后插入新数据(位置3):\n";
    D_LNode* px = p;
    insertD_LNode_index_new(&px,3,195781);
    std::cout << "打印该链表:";
    D_linkedList_Print(p,10);
    std::cout << "此时链表总长度为:" << getNextLength(p) << std::endl;

    std::cout << "\n删除指定结点的后继结点(删除第三个数据结点):\n";
    D_LNode* p3 = p->next->next;
    deleteNextD_LNode(p3);
    std::cout << "打印该链表:";
    D_linkedList_Print(p,10);
    std::cout << "此时链表总长度为:" << getNextLength(p) << std::endl;

    std::cout << "\n删除指定结点的前驱结点(删除第二个数据结点的前驱结点):\n";
    D_LNode* p4 = p->next->next;
    deletePriorD_LNode(p4);
    std::cout << "打印该链表:";
    D_linkedList_Print(p,10);
    std::cout << "此时链表总长度为:" << getNextLength(p) << std::endl;

    std::cout << "\n删除指定结点(给结点,没给结点位置(测试中删除第二个数据结点):\n";
    D_LNode* p5 = p->next->next;
    deleteD_LNode(p5);
    std::cout << "打印该链表:";
    D_linkedList_Print(p,10);
    std::cout << "此时链表总长度为:" << getNextLength(p) << std::endl;

    std::cout << "\n获取指定索引位置的结点(位置3):\n";
    D_LNode* p6 = p;
    std::cout << "该结点的数据为:" << getD_LNode_Index(&p6,3)->data << std::endl;
    std::cout << "打印该链表:";
    D_linkedList_Print(p,10);
    std::cout << "此时链表总长度为:" << getNextLength(p) << std::endl;

    std::cout << "\n删除指定索引位置的结点(位置3):\n";
    D_LNode* p7 = p;
    deleteD_LNode_index_new(&p7,3);
    std::cout << "打印该链表:";
    D_linkedList_Print(p,10);
    std::cout << "此时链表总长度为:" << getNextLength(p) << std::endl;
}
int main(){
    test();
}
posted @ 2022-07-21 18:02  在天边偷看小天使  阅读(4)  评论(0)    收藏  举报  来源