单向链表的节点创建和头插、尾插、任意位置插入节点的实现

单向链表的节点创建和头插、尾插、任意位置插入节点的实现

今天复习了链表的知识,决定通过自己的理解直接手撕代码,不去参考已经写过的链表代码,在不断的调试中,总算写出来了同时发现对指针和单向链表有了更深的理解。
实现代码:

//单向链表
struct Node     //用结构体作为链表的节点
{
    Node *next; //用于存储下一个节点的地址
    string data;        //用于存储数据
};

typedef struct Node* List;  //为了简化书写和可读性,将struct Node* 命名为 List

//头节点的创建 不用于存储数据,只是为了作为链表首节点的地址
//bool init(List  &head) <==> bool init(Node*  &head) <==> bool init(List *head)
//参数为 Node* head 这是一个指针指向一个结构体,现在将它作为参数传递,涉及实参和形参的问题,需要改变这个指针则传入的参数就必须是该指针的地址,即指针的指针,二级指针,或者使用C++的引用
bool init(List  &head)      
{
    List newnode = new Node;    //动态创建一个节点
    if (nullptr == newnode)         //判断节点是否创建成功
    {
        cout << "new failed!" << endl;
        return false;
    }

    newnode->next = nullptr;        //因为是单向链表,所以尾部指向nullptr
    newnode->data = " ";            //头节点的数据不存储,但进行以下初始化
    head = newnode;                 //将创建的节点赋给头节点

    return true;
}

//头插法:在链表首部插入数据,注意头节点只是指示作用,所以头插法,应该是插入在头节点的后面,首个数据节点的前面
bool insert_head(List head, string value)
{
    List newnode = new Node;        //动态创建一个节点的内存
    if (nullptr == newnode)
    {
        cout << "new failed!" << endl;
        return false;
    }

    newnode->data = value;              //将数据赋给创建节点
    //将创建的节点插入到链表中
    newnode->next = head->next; //节点的下一个应为头节点的下一个 即首数据的节点   
    head->next = newnode;               //头节点的下一个即为创建的节点,此时完成了节点的插入

    return true;
}

//任意位置插入法
bool insert_index(List head, int index, string value)
{
    List temp = head;   //需要保存头节点的位置
    int count = 0;

    while (temp->next->next != nullptr) //计算出链表总过有几个节点,用于判断传入位置的参数是否合法
    {
        ++count;
        temp = temp->next;

    }

    if (index >= 0 && index <= count)
    {
        temp = head;
        for (int i = 0; i < index; ++i)     //定位到要插入的节点
        {
            temp = temp->next;
        }

        List newnode = new Node;    
        if (nullptr == newnode)
        {
            cout << "new failed!" << endl;
            return false;
        }
        newnode->data = value;

        newnode->next = temp->next; //进行插入操作
        temp->next = newnode;
    }
    else
    {
        cout << "out of range!!!" << endl;
        return false;
    }

    return true;
}

//尾插法
//尾插法即插入的节点插入到最后一个,即它的下一个指向nullptr 原本最后一个元素的下一个指向它
bool insert_tail(List head, string value)
{
    List newnode = new Node;
    if (nullptr == newnode)
    {
        cout << "new failed!" << endl;
        return false;
    }
    newnode->data = value;
    //进行尾插
    newnode->next = nullptr;            //节点的下一个为nullptr
    while (head->next != nullptr)   //寻找到尾节点
    {
        head = head->next;
    }
    head->next = newnode;           //将尾节点的下一个指向创捷的节点
    return true;
}

//打印所有节点
void display(List head)
{
    while (head->next != nullptr)
    {
        cout << head->next->data << " ";
        head = head->next;
    }
    cout << endl;
}

测试程序:

int main()
{
    List head = nullptr;

    init(head);

    //尾插法
    for (int i = 0; i < 10; i++)
    {
        insert_tail(head, "hello");
    }
    cout << "尾插法后: ";
    display(head);
    //头插法
    insert_head(head, "haha");
    cout << "头插法后: ";
    display(head);

    insert_index(head, 4, "zhou");
    cout << "指定位置插入插法后: ";
    display(head);

    system("pause");
    return 0;
}

运行结果:
这里写图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值