22计算机408考研—数据结构—链表

140 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

2022计算机考研408—数据结构—线性表、栈、队列、数组 手把手教学考研大纲范围内的线性表、栈、队列、数组 22考研大纲数据结构要求的是C/C++,笔者以前使用的都是Java,对于C++还很欠缺, 如有什么建议或者不足欢迎大佬评论区或者私信指出

Talk is cheap. Show me the code. 理论到处都有,代码加例题自己练习才能真的学会

链表

链表和顺序表其实是差不多的
顺序表在访问下一个的时候是用下标访问
链表访问下一个只能通过结构体中的指针

插入,删除的时候不需要改变其他元素,只需要修改指定元素前后元素的指针即可

//此链表的index为序列号从1开始    !!!!不是下标
//此链表多处用到new ,建议大家删一个new调试一下,就能了解到new和不用new的区别了

#include "iostream"
#include "vector"

using namespace std;

typedef struct LNode {  //LNode类型 包含一个int值和一个指针指向下一个地址
    int data;
    struct LNode *next;
} LNode, *LinkList;

bool ListInit(LinkList &L, int val) {   //初始化链表,要给一个初始值当作链表头节点
    L = new LNode;
    L->next = NULL;
    L->data = val;
    return true;
}

bool ListInsertE(LinkList &L, int val) {    //添加一个元素到链表尾端
    LNode *headL = new LNode;   //保存一下链表当前的位置
    headL = L;
    while (L->next) {   //循环到L最后面,然后把当前值给L的下一个
        L = L->next;
    }
    LNode *temp = new LNode;    //new一个结点,如果不new可能会使用上一个temp结点
    temp->data = val;
    temp->next = NULL;
    L->next = temp;
    L = headL;  //链表的头位置给L
}

bool ListInsert(LinkList &L, int index, int val) {  //插入到链表的序列index(注意不是下标)位置
    LNode *headL = new LNode;   //保存头位置的上一个(headL的下一个是头位置)
    headL->next = L;            //这里不保存头位置,    防止添加第一个位置时,链表会添加到第二个位置
    int j = 0;
    while (headL && j < (index - 1)) {      //找到第index个位置
        j++;
        headL = headL->next;
    }
    if (!headL || index < 1) {
        return false;
    }
    LNode *temp = new LNode;    //new一个结点,(不new可能会用到上一个结点)
    temp->data = val;
    temp->next = headL->next;   //把headL的下一个结点给temp的下一个结点
    headL->next = temp;         //把temp给headL的下一个结点     现在temp的下一个就是原headL的下一个结点,相当于把temp插入到了里面
    L = headL->next;
    return true;
}

bool ListDelete(LinkList &L, int index) {   //删除指定序列index的值
    LNode *headL = new LNode;
    LNode *tempL = new LNode;
    tempL->next = L;            //tempL的下一个是头节点(防止删除第一个结点出现问题)
    headL = tempL;              //保存头结点的上一个,就是tempL
    int j = 0;
    while (tempL && j < (index - 1)) {  //找到序列index的结点
        tempL = tempL->next;
        j++;
    }
    if (!tempL) {   //如果tempL为NULL,直接退出,没有要删除的结点
        return false;
    }
    tempL->next = tempL->next->next;    //tempL的下一个的下一个给下一个   相当于下一个会被直接盖住(删除了下一个   )
    L = headL->next;    //把头结点给L
}

bool ListGetElem(LinkList L, int index, int &val) {     //找到知道序列index的值,传送给val
    int j = 0;
    while (L && j < (index - 1)) {  //找到序列为index的值
        L = L->next;
        j++;
    }
    if (!L) {       //如果L为空,直接退出,没有此节点
        return false;
    }
    val = L->data;
    return true;
}

int ListGetIndex(LinkList L, int val) {     //通过值找到指定序列下标
    int index = 1;
    while (L->data != val) {
        L = L->next;
        index++;
    }
    if (!L) {
        return 0;
    }
    return index;
}

void ListCreateH(LinkList &L, vector<int> num) {    //前插法创建节点(num数组的值创建链表)
    L = new LNode;
    L->next = NULL;
    for (int i = 0; i < num.size(); i++) {
        LNode *p = new LNode;
        p->data = num[i];
        p->next = L->next;  //每次把L的下一个给p的下一个
        L->next = p;        //然后把p给L的下一个    p的下一个是原来L的下一个
    }
    L = L->next;    //L的下一个才是num数组创建的第一个值
}

void ListCreateE(LinkList &L, vector<int> num) {    //前插法创建节点(num数组的值创建链表)
    L = new LNode;
    LNode *headL = new LNode;
    headL = L;
    L->next = NULL;
    for (int i = 0; i < num.size(); i++) {
        LNode *p = new LNode;
        p->data = num[i];
        p->next = NULL;
        L->next = p;    //当前指针p给L的下一个
        L = p;          //把p给L     p的上一个就是原L
    }
    L = headL->next;    //头结点的下一个才是num创建的第一个结点
}

void ListPrint(LinkList L) {    //输出链表各个的值
    while (L) {
        cout << L->data << " ";
        L = L->next;
    }
    cout << "\n";
}
int main() {
    vector<int> num = {1,2,3,4,5};
    LinkList temp;
//    ListCreateE(temp, num);
//    ListPrint(temp);
//    ListCreateH(temp, num);
//    ListPrint(temp);
    ListInit(temp, 10);     //创建List链表
    ListInsertE(temp, 10);  //尾端插入值
    ListInsertE(temp, 10);

    ListPrint(temp);
    ListInsert(temp, 1, 20);    //插入一个值 到序列index位置

    ListPrint(temp);
    ListDelete(temp, 3);            //删除链表中序列index的值
    ListPrint(temp);
    int val;
    ListGetElem(temp, 3, val);      //通过序列index找到值,传给val
    cout << val << "\n";
    ListPrint(temp);
    cout << ListGetIndex(temp, 2) << "\n";  //通过值找到序列index

}

在这里插入图片描述