数据结构01:单链表(C/C++语言)

初始化单链表

使用C语言结构体描述该单链表的基础结构
typedef double elementType;
typedef struct LNode {
    elementType data;/*数据域*/
    struct LNode *next;/*指针域*/
} LNode, *linkedList;
初始化一个带头结点的单链表
bool InitList_Head(linkedList *L) {
    /*初始化一个空的带头结点的单链表*/
    *L = (LNode *) malloc(sizeof(LNode));/*分配一个头结点,头结点不存储数据*/
    if (*L == nullptr) {
        return false;/*内存不足,分配失败*/
    }
    (*L)->next = nullptr;
    return true;
}

计算从某个结点p开始直到链表末尾的结点总数(包括此结点p)

int listLength(LNode *p) {
    /*从结点p开始计数,统计后面链接的结点数量(包括p本身)*/
    if (p == nullptr) {
        return 0;
    }
    int number = 0;
    while (p != nullptr) {
        number++;
        p = p->next;
    }
    return number;
}

从某个结点P开始,打印N个结点的数据(如果只剩余M个,不够N个,则打印到末尾,即打印M个)

bool listPrint_linkedList(LNode *p, int i) {
    /*从p开始打印i个节点*/
    if (p == nullptr) {
        return false;
    }
    LNode *q = p;/*p不变,依然指向头结点*/
    for (int j = 0; j < i; j++) {
        q = q->next;
        if (q == nullptr) {
            break;
        }
        std::cout << q->data << "  ";
    }
    std::cout << endl;
    return true;
}

单链表插入

在指定节点p之后插入指定数据元素
bool listInsert_nextNode_newElement(LNode *p, elementType element) {
    /*在指定节点p后插入元素e*/
    if (p == nullptr) {
        return false;
    }
    LNode *s = (LNode *) malloc(sizeof(LNode));
    if (s == nullptr) {
        return false;/*内存分配失败*/
    }
    s->data = element;
    s->next = p->next;
    p->next = s;
    return true;
}
在指定节点p之后插入指定节点s
bool listInsert_nextNode_newLNode(LNode *p, LNode *s) {
    /*在p结点之后插入s结点*/
    if (p == nullptr || s == nullptr) {
        return false;
    }
    s->next = p->next;
    p->next = s;
    return true;
}
在指定的链表的索引位置插入指定的数据元素(带头结点链表)
bool listInsert_nextNode_Index_head(linkedList *L, int i, elementType element) {
    /*含有头结点的单链表中,从0计数,头结点为第0个节点
     * 要求在第i个位置上插入指定元素E
     * 也就是需要第i-1个节点后,插入新元素*/
    if (i < 1) {
        /*>=1 :因为头结点位置索引为0,且不能被替换*/
        return false;
    }
    LNode *p;
    int j = 0;
    p = *L;
    while (p != nullptr && j < i - 1) {
        /*p指向i-1位置*/
        p = p->next;
        j++;
    }
    return listInsert_nextNode_newElement(p, element);
    /*在指定节点p后插入元素element,以下注释内容可用此函数代替*/
    /*如果p为空,也就是第i-1个位置已经为空,链表已经结束,则第i个位置不存在*/
    /*if (p == nullptr) {
        return false;
    }
    //插入动作:在i-1位置之后插入新节点s
    LNode *s = (LNode *) malloc(sizeof(LNode));
    if (s == nullptr) {
        return false;
        //内存分配失败
    }
    s->data = element;
    s->next = p->next;
    p->next = s;
    return true;*/
}
在指定的链表结点p之前插入指定的新元素
bool listInsert_priorNode_newElement(LNode *p, elementType element) {
    /*在指定结点p之前插入新元素,不再依赖循环
     * 直接构造一个新节点(p节点的复制品),然后将新节点插入p节点之后
     * 再让p节点赋值为新元素,则新节点作为了p节点,原p节点成为了新元素所在的节点
     * 复杂度:O(1)*/
    LNode *s = (LNode *) malloc(sizeof(LNode));
    if (s == nullptr) {
        return false;/*内存分配失败*/
    }
    s->data = p->data;
    s->next = p->next;
    p->next = s;
    p->data = element;
    return true;
}
在指定的链表结点p之前插入指定的新结点s
bool listInsert_priorNode_newLNode(LNode *p, LNode *s) {
    /*在p结点之前插入结点s*/
    if (p == nullptr || s == nullptr) {
        return false;
    }
    s->next = p->next;
    p->next = s;
    elementType temp = s->data;
    s->data = p->data;
    p->data = temp;
    return true;
}

单链表删除

删除结点P后面链接的第一个结点(p->next)
bool listDelete_nextLNode_newElement(LNode *p, elementType *deletedElement) {
    /*要删除单个结点为p->next
     * 被删除结点的数据存储在*deleteElement中*/
    if (p == nullptr || p->next == nullptr) {
        return false;
    }
    LNode *s = p->next;
    *deletedElement = s->data;
    p->next = s->next;
    free(s);
    return true;
}
删除链表的某个索引位置的结点
bool listDelete_elementIndex_head(linkedList *L, int i, elementType *deletedElement) {
    if (i < 1) {
        return false;
    }
    LNode *p = *L;
    int j = 0;
    while (p != nullptr && j < i - 1) {
        p = p->next;
        j++;
    }
    /*p已经是要删除结点前一位结点,可以不执行下面的注释代码,直接调用前面的函数完成*/
    return listDelete_nextLNode_newElement(p, deletedElement);
    /*if(p == nullptr || p->next == nullptr){
        return false;
    }
    LNode* s = p->next;
    p->next = s->next;
    *deletedElement = s->data;
    //被删除结点的值存储在(*deleteElement)中
    free(s);
    return true;*/
}
删除指定结点P(P不是末尾结点时 O(1) )
bool listDelete_LNode(LNode *p) {
    /*删除结点p(p不为末尾结点时)*/
    if (p == nullptr) {
        return false;
    }
    if (p->next == nullptr) {
        /*如果p是最后一个节点,p-next == nullptr
         *这时要删除最后一个节点p的时候,需要让p的前驱结点q的next指针指向nullptr
         * 然后free(p),即:*/
        /*q->next = nullptr;
        free(p);
        return true;*/
        //但是在这个函数中无法找到p的前驱结点q(除非去做循环)
        return false;
    }
    /*偷梁换柱:把p结点用p->next结点赋值,然后让p再去连接p->next->next,
     * (p没有了,现在有两个p->next),然后删掉p->next,
     * (前提是P->next不为空,也就是说P不是末尾结点才行)*/
    LNode *s = p->next;
    p->data = p->next->data;
    p->next = s->next;
    free(s);
    return true;
}
删除指定结点P(先循环找到P的前驱结点,再删除P O(n) )
bool listDelete_LNode_new(linkedList *L, LNode *p) {
    /*删除结点p*/
    if (*L == nullptr || p == nullptr) {
        return false;
    }
    LNode *q = (*L);/*使得(*L)不变,依然指向头结点*/
    while (q->next != p) {
        q = q->next;
    }
    /*q指向p结点的前驱结点*/
    q->next = p->next;
    free(p);
    return true;
}

尾插法和头插法建立单链表

尾插法
linkedList InitList_end(linkedList *L){
    /*尾插法建立单链表*/
    elementType x = 0;
    LNode *p = *L;
    std::cin >> x;
    while(x != -10000){
        LNode* s = (LNode*) malloc(sizeof(LNode));
        s->data = x;
        p->next = s;
        p = p->next;
        std::cin >> x;
    }
    p->next = nullptr;/*末尾置空*/
    return *L;
}
头插法
linkedList InitList_first(linkedList *L){
    /*头插法建立链表*/
    elementType x = 0;
    LNode *p = *L;
    LNode *q = p->next;
    std::cin >> x;
    while(x != -10000){
        LNode *s = (LNode* ) malloc(sizeof(LNode));
        s->data = x;
        s->next = q;
        p->next = s;
        q = p->next;
        std::cin >> x;
    }
    return *L;
}

测试函数:test

void test() {
    /*linkedList L1;//声明一个指向单链表的指针
    InitList_noHead(&L1);//初始化一个不带头结点的空表
    //...后续代码*/
    /*带头结点的单链表:删除、插入、打印*/
    linkedList L2;//声明一个指向单链表的指针
    InitList_Head(&L2);//初始化一个带头结点的空表
    LNode *p;
    p = L2;
    std::cout << "被填入链表的数据时:\n";
    for (int j = 1; j <= 5; j++) {
        LNode *s = (LNode *) malloc(sizeof(LNode));
        L2->next = s;
        s->data = j;
        L2 = L2->next;
        std::cout << L2->data << " ";
        L2->next = nullptr;
    }
    LNode *q = L2;
    L2 = p;
    /*q指向末尾结点,p和L2都指向头结点*/
    std::cout << "\n最初整个链表:\n";
    listPrint_linkedList(p, 10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;

    listDelete_LNode_new(&p, q);
    std::cout << "删除最后一个链表结点之后:\n";
    listPrint_linkedList(p, 10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;

    listInsert_nextNode_Index_head(&p, 1, 195779);
    std::cout << "在链表第一个位置插入元素195779之后:\n";
    listPrint_linkedList(p, 10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;

    listInsert_priorNode_newElement(L2->next, 195778);
    std::cout << "在链表第一个结点之前(即更新第一个数据结点)插入元素195778之后:\n";
    listPrint_linkedList(p, 10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;

    LNode *p_2 = p->next->next;
    LNode *s = (LNode *) malloc(sizeof(LNode));
    s->data = 195780;
    listInsert_priorNode_newLNode(p_2, s);
    std::cout << "在链表第二个位置“之前”插入节点s之后:\n";
    listPrint_linkedList(p, 10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;

    LNode *s2 = (LNode *) malloc(sizeof(LNode));
    s2->data = 987654;
    listInsert_nextNode_newLNode(p_2, s2);
    std::cout << "在链表的第二个位置“之前”插入结点s2之后:\n";
    listPrint_linkedList(p, 10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;

    elementType x[3] = {0};
    for (int i = 0; i < 3; i++) {
        /*从第一个结点开始连续删除最初链表的前三个结点*/
        listDelete_elementIndex_head(&p, 1, &x[i]);
        /*这里的函数参数的i,三次都取1*/
        std::cout << "删除第" << i + 1 << "个节点之后的链表:\n";
        listPrint_linkedList(p, 10);
        std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
    }
    std::cout << "最初链表的被删除的三个结点的值为:\n";
    for (int i = 0; i < 3; i++) {
        std::cout << x[i] << "  ";
    }

    std::cout << "\n\n链表的查找:查找索引位置为5的结点的值为:";
    std::cout << listGetLNode_index(&p, 5)->data << endl;
    std::cout << "现在整个链表:\n";
    listPrint_linkedList(p, 10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl;
    std::cout << "链表的查找:查找值为195779的结点的下一个结点的值为:";
    LNode* test_x1 = listGetLNode_element(&p,195779)->next;
    if(test_x1 != nullptr){
        std::cout << test_x1->data << endl << endl;
    }
    
    std::cout<<"验证头插法建立单链表L3:\n";
    linkedList L3;
    InitList_Head(&L3);
    LNode* p_3 = L3;
    InitList_first(&L3);
    listPrint_linkedList(L3,10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p_3);
    std::cout<<"\n验证尾插法建立单链表L4:\n";
    linkedList L4;
    InitList_Head(&L4);
    LNode* p_4 = L4;
    InitList_end(&L4);
    listPrint_linkedList(L4,10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p_4);
}
E:\CODING__ALAN_CF\cmake-build-debug\LinkedList.exe
被填入链表的数据时:
1 2 3 4 5
最初整个链表:
1  2  3  4  5
此时链表结点总数为(包括头结点):6

删除最后一个链表结点之后:
1  2  3  4
此时链表结点总数为(包括头结点):5

在链表第一个位置插入元素195779之后:
195779  1  2  3  4
此时链表结点总数为(包括头结点):6

在链表第一个结点之前(即更新第一个数据结点)插入元素195778之后:
195778  195779  1  2  3  4
此时链表结点总数为(包括头结点):7

在链表第二个位置“之前”插入节点s之后:
195778  195780  195779  1  2  3  4
此时链表结点总数为(包括头结点):8

在链表的第二个位置“之前”插入结点s2之后:
195778  195780  987654  195779  1  2  3  4
此时链表结点总数为(包括头结点):9

删除第1个节点之后的链表:
195780  987654  195779  1  2  3  4
此时链表结点总数为(包括头结点):8

删除第2个节点之后的链表:
987654  195779  1  2  3  4
此时链表结点总数为(包括头结点):7

删除第3个节点之后的链表:
195779  1  2  3  4
此时链表结点总数为(包括头结点):6

最初链表的被删除的三个结点的值为:
195778  195780  987654

链表的查找:查找索引位置为5的结点的值为:4
现在整个链表:
195779  1  2  3  4
此时链表结点总数为(包括头结点):6
链表的查找:查找值为195779的结点的下一个结点的值为:1

验证头插法建立单链表L3:
15 25 30 -10000
30  25  15
此时链表结点总数为(包括头结点):4
验证尾插法建立单链表L4:
15 25 30 -10000
15  25  30
此时链表结点总数为(包括头结点):4
进程已结束,退出代码为 0

.h文件(不太会搞,好像可以只在.h里面放声明,函数定义在外面?弄不太懂,直接把定义都放进.h文件了)

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

#ifndef CODING__ALAN_CF_SINGLE_LINKEDLIST_H
#define CODING__ALAN_CF_SINGLE_LINKEDLIST_H

typedef double elementType;
typedef struct LNode {
    elementType data;/*数据域*/
    struct LNode *next;/*指针域*/
} LNode, *linkedList;

bool InitList_noHead(linkedList *L) {
    /*初始化一个空的不带头结点的单链表*/
    /*使用二级指针让test函数里链表指针置空*/
    *L = nullptr;
    return true;
}

bool InitList_Head(linkedList *L) {
    /*初始化一个空的带头结点的单链表*/
    *L = (LNode *) malloc(sizeof(LNode));/*分配一个头结点,头结点不存储数据*/
    if (*L == nullptr) {
        return false;/*内存不足,分配失败*/
    }
    (*L)->next = nullptr;
    return true;
}

/*判空*/
bool isEmpty_noHead(linkedList L) {
    /*是否为空,空则返回真*/
    return (L == nullptr);
}

bool isEmpty_Head(linkedList L) {
    /*是否为空,空则返回真*/
    return (L->next == nullptr);
}

bool listInsert_nextNode_newElement(LNode *p, elementType element) {
    /*在指定节点p后插入元素e*/
    if (p == nullptr) {
        return false;
    }
    LNode *s = (LNode *) malloc(sizeof(LNode));
    if (s == nullptr) {
        return false;/*内存分配失败*/
    }
    s->data = element;
    s->next = p->next;
    p->next = s;
    return true;
}

bool listInsert_nextNode_newLNode(LNode *p, LNode *s) {
    /*在p结点之后插入s结点*/
    if (p == nullptr || s == nullptr) {
        return false;
    }
    s->next = p->next;
    p->next = s;
    return true;
}

bool listInsert_nextNode_Index_head(linkedList *L, int i, elementType element) {
    /*含有头结点的单链表中,从0计数,头结点为第0个节点
     * 要求在第i个位置上插入指定元素E
     * 也就是需要第i-1个节点后,插入新元素*/
    if (i < 1) {
        /*>=1 :因为头结点位置索引为0,且不能被替换*/
        return false;
    }
    LNode *p;
    int j = 0;
    p = *L;
    while (p != nullptr && j < i - 1) {
        /*p指向i-1位置*/
        p = p->next;
        j++;
    }
    /*如果p为空,也就是第i-1个位置已经为空,链表已经结束,则第i个位置不存在*/
    /*if (p == nullptr) {
        return false;
    }
    //插入动作:在i-1位置之后插入新节点s
    LNode *s = (LNode *) malloc(sizeof(LNode));
    if (s == nullptr) {
        return false;
        //内存分配失败
    }
    s->data = element;
    s->next = p->next;
    p->next = s;
    return true;*/
    return listInsert_nextNode_newElement(p, element);
    /*在指定节点p后插入元素element*/
}

bool listInsert_nextNode_Index_noHead(linkedList *L, int i, elementType element) {
    /*没有头结点,不从0计数,从第1个到第n个节点,总共n个节点
     * 在第i个节点位置插入节点,i>=1*/
    if (i < 0) {
        return false;
    }
    if (i == 1) {
        LNode *s = (LNode *) malloc(sizeof(LNode));
        if (s == nullptr) {
            return false;/*内存分配失败*/
        }
        s->data = element;
        s->next = *L;
        *L = s;
        return true;
    }
    LNode *p = *L;
    int j = 1;
    /*p最初指向第1个节点(无头结点情况下的链表首个节点)*/
    while (p != nullptr && j < i - 1) {
        p = p->next;
        j++;
    }
    //此时p指向第i-1个节点的位置(首节点为第1个节点)
    /*if(p == nullptr){
        return false;
    }
    LNode *s = (LNode *) malloc(sizeof(LNode));
    if(s == nullptr){
        return false;
        //内存分配失败
    }
    s->data = element;
    s->next = p->next;
    p->next = s;
    return true;
    */
    return listInsert_nextNode_newElement(p, element);
    /*在指定节点p后插入元素element*/
}

bool listInsert_priorNode_newElement_old(linkedList *L, LNode *p, elementType element) {
    /*在指定结点之前插入元素*/
    /*先循环找到p的前驱结点,然后在它后面插入新元素
     * 复杂度:O(n)*/
    LNode *s = *L;
    while (s != nullptr) {
        if (p == s->next) {
            break;
        }
        s = s->next;
    }
    if (s == nullptr) {
        return false;
    }
    listInsert_nextNode_newElement(s, element);
}

bool listInsert_priorNode_newElement(LNode *p, elementType element) {
    /*在指定结点p之前插入新元素,不再依赖循环
     * 直接构造一个新节点(p节点的复制品),然后将新节点插入p节点之后
     * 再让p节点赋值为新元素,则新节点作为了p节点,原p节点成为了新元素所在的节点
     * 复杂度:O(1)*/
    LNode *s = (LNode *) malloc(sizeof(LNode));
    if (s == nullptr) {
        return false;/*内存分配失败*/
    }
    s->data = p->data;
    s->next = p->next;
    p->next = s;
    p->data = element;
    return true;
}

bool listInsert_priorNode_newLNode(LNode *p, LNode *s) {
    /*在p结点之前插入结点s*/
    if (p == nullptr || s == nullptr) {
        return false;
    }
    s->next = p->next;
    p->next = s;
    elementType temp = s->data;
    s->data = p->data;
    p->data = temp;
    return true;
}

bool listDelete_nextLNode_newElement(LNode *p, elementType *deletedElement) {
    /*要删除单个结点为p->next
     * 被删除结点的数据存储在*deleteElement中*/
    if (p == nullptr || p->next == nullptr) {
        return false;
    }
    LNode *s = p->next;
    *deletedElement = s->data;
    p->next = s->next;
    free(s);
    return true;
}

bool listDelete_elementIndex_head(linkedList *L, int i, elementType *deletedElement) {
    if (i < 1) {
        return false;
    }
    LNode *p = *L;
    int j = 0;
    while (p != nullptr && j < i - 1) {
        p = p->next;
        j++;
    }
    /*if(p == nullptr || p->next == nullptr){
        return false;
    }
    LNode* s = p->next;
    p->next = s->next;
    *deletedElement = s->data;
    //被删除结点的值存储在(*deleteElement)中
    free(s);
    return true;*/
    return listDelete_nextLNode_newElement(p, deletedElement);
}


bool listDelete_LNode(LNode *p) {
    /*删除结点p(p不为末尾结点时)*/
    if (p == nullptr) {
        return false;
    }
    if (p->next == nullptr) {
        /*如果p是最后一个节点,p-next == nullptr
         *这时要删除最后一个节点p的时候,需要让p的前驱结点q的next指针指向nullptr
         * 然后free(p),即:*/
        /*q->next = nullptr;
        free(p);
        return true;*/
        //但是在这个函数中无法找到p的前驱结点q(除非去做循环)
        return false;
    }
    /*偷梁换柱:把p结点用p->next结点赋值,然后让p再去连接p->next->next,
     * (p没有了,现在有两个p->next),然后删掉p->next,
     * (前提是P->next不为空,也就是说P不是末尾结点才行)*/
    LNode *s = p->next;
    p->data = p->next->data;
    p->next = s->next;
    free(s);
    return true;
}

bool listDelete_LNode_new(linkedList *L, LNode *p) {
    /*删除结点p*/
    if (*L == nullptr || p == nullptr) {
        return false;
    }
    LNode *q = (*L);/*使得(*L)不变,依然指向头结点*/
    while (q->next != p) {
        q = q->next;
    }
    /*q指向p结点的前驱结点*/
    q->next = p->next;
    free(p);
    return true;
}

bool listPrint_linkedList(LNode *p, int i) {
    /*从p开始打印i个节点*/
    if (p == nullptr) {
        return false;
    }
    LNode *q = p;/*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 listLength(LNode *p) {
    /*从结点p开始计数,统计后面链接的结点数量(包括p本身)
     * 如果从输入参数为头结点,则计算结果为单链表长度加一
     * (头结点单链表长度)*/
    if (p == nullptr) {
        return 0;
    }
    int number = 0;
    while (p != nullptr) {
        number++;
        p = p->next;
    }
    return number;
}


LNode *listGetLNode_index(linkedList *L, int i) {
    /*按索引位查找*/
    if (i < 0) {
        return nullptr;
    }
    LNode *p = *L;
    int j = 0;
    while (p != nullptr && j < i) {
        p = p->next;
        j++;
    }
    return p;
}

LNode *listGetLNode_element(linkedList *L, elementType element) {
    /*按值查找*/
    LNode *p = (*L)->next;
    while (p != nullptr && p->data != element) {
        p = p->next;
    }
    return p;
}

linkedList InitList_end(linkedList *L){
    /*尾插法建立单链表*/
    elementType x = 0;
    LNode *p = *L;
    std::cin >> x;
    while(x != -10000){
        LNode* s = (LNode*) malloc(sizeof(LNode));
        s->data = x;
        p->next = s;
        p = p->next;
        std::cin >> x;
    }
    p->next = nullptr;/*末尾置空*/
    return *L;
}
linkedList InitList_first(linkedList *L){
    /*头插法建立链表*/
    elementType x = 0;
    LNode *p = *L;
    LNode *q = p->next;
    std::cin >> x;
    while(x != -10000){
        LNode *s = (LNode* ) malloc(sizeof(LNode));
        s->data = x;
        s->next = q;
        p->next = s;
        q = p->next;
        std::cin >> x;
    }
    return *L;
}

#endif //CODING__ALAN_CF_SINGLE_LINKEDLIST_H

.cpp测试文件

//
// Created by 15328 on 2022/1/21.
//
#include<bits/stdc++.h>
#include"Single_linkedList.h"
/*把单链表的初始化、构造、判空、打印、计数、
 * 插入、查找、删除的操作函数都放在这个.h文件中*/
using namespace std;
void test() {
    /*linkedList L1;//声明一个指向单链表的指针
    InitList_noHead(&L1);//初始化一个不带头结点的空表
    //...后续代码*/
    /*带头结点的单链表:删除、插入、打印*/
    linkedList L2;//声明一个指向单链表的指针
    InitList_Head(&L2);//初始化一个带头结点的空表
    LNode *p;
    p = L2;
    std::cout << "被填入链表的数据时:\n";
    for (int j = 1; j <= 5; j++) {
        LNode *s = (LNode *) malloc(sizeof(LNode));
        L2->next = s;
        s->data = j;
        L2 = L2->next;
        std::cout << L2->data << " ";
        L2->next = nullptr;
    }
    LNode *q = L2;
    L2 = p;
    /*q指向末尾结点,p和L2都指向头结点*/
    std::cout << "\n最初整个链表:\n";
    listPrint_linkedList(p, 10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;

    listDelete_LNode_new(&p, q);
    std::cout << "删除最后一个链表结点之后:\n";
    listPrint_linkedList(p, 10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;

    listInsert_nextNode_Index_head(&p, 1, 195779);
    std::cout << "在链表第一个位置插入元素195779之后:\n";
    listPrint_linkedList(p, 10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;

    listInsert_priorNode_newElement(L2->next, 195778);
    std::cout << "在链表第一个结点之前(即更新第一个数据结点)插入元素195778之后:\n";
    listPrint_linkedList(p, 10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;

    LNode *p_2 = p->next->next;
    LNode *s = (LNode *) malloc(sizeof(LNode));
    s->data = 195780;
    listInsert_priorNode_newLNode(p_2, s);
    std::cout << "在链表第二个位置“之前”插入节点s之后:\n";
    listPrint_linkedList(p, 10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;

    LNode *s2 = (LNode *) malloc(sizeof(LNode));
    s2->data = 987654;
    listInsert_nextNode_newLNode(p_2, s2);
    std::cout << "在链表的第二个位置“之前”插入结点s2之后:\n";
    listPrint_linkedList(p, 10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;

    elementType x[3] = {0};
    for (int i = 0; i < 3; i++) {
        /*从第一个结点开始连续删除最初链表的前三个结点*/
        listDelete_elementIndex_head(&p, 1, &x[i]);
        /*这里的函数参数的i,三次都取1*/
        std::cout << "删除第" << i + 1 << "个节点之后的链表:\n";
        listPrint_linkedList(p, 10);
        std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl << endl;
    }
    std::cout << "最初链表的被删除的三个结点的值为:\n";
    for (int i = 0; i < 3; i++) {
        std::cout << x[i] << "  ";
    }

    std::cout << "\n\n链表的查找:查找索引位置为5的结点的值为:";
    std::cout << listGetLNode_index(&p, 5)->data << endl;
    std::cout << "现在整个链表:\n";
    listPrint_linkedList(p, 10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p) << endl;
    std::cout << "链表的查找:查找值为195779的结点的下一个结点的值为:";
    LNode* test_x1 = listGetLNode_element(&p,195779)->next;
    if(test_x1 != nullptr){
        std::cout << test_x1->data << endl << endl;
    }

    std::cout<<"验证头插法建立单链表L3:\n";
    linkedList L3;
    InitList_Head(&L3);
    LNode* p_3 = L3;
    InitList_first(&L3);
    listPrint_linkedList(L3,10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p_3);
    std::cout<<"\n验证尾插法建立单链表L4:\n";
    linkedList L4;
    InitList_Head(&L4);
    LNode* p_4 = L4;
    InitList_end(&L4);
    listPrint_linkedList(L4,10);
    std::cout << "此时链表结点总数为(包括头结点):" << listLength(p_4);
}

int main() {
    test();
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值