单链表顺序插入节点

主函数测试:

public static  void main(String[] args){
        Scanner scanner=new Scanner(System.in);
        //先创建节点
        HeroNode hero1=new HeroNode(1,"宋江","及时雨");
        HeroNode hero2=new HeroNode(2,"卢俊义","玉麒麟");
        HeroNode hero3=new HeroNode(3,"吴用","智多星");
        HeroNode hero4=new HeroNode(4,"林冲","豹子头");

        //创建要给链表
        SingleLinkedList singleLinkedList=new SingleLinkedList();
        //加入
        singleLinkedList.add(hero1);
        singleLinkedList.add(hero2);
        singleLinkedList.add(hero3);
        singleLinkedList.add(hero4);
        //显示
        singleLinkedList.list();

    }

定义单链表:

//定义SingleLinkedList管理我们的英雄
class SingleLinkedList{
    //先初始化一个头节点,头节点不能动,不存放具体的数据
    private HeroNode head=new HeroNode(0,"","");
    /**
     * 添加节点到单向链表
     * 思路:当不考虑编号顺序时
     * 1.找到当前链表的最后节点
     * 2.将最后这个节点的next指向新的节点
     */
    public void add(HeroNode heroNode){
        //因为head节点不能动,因此我们需要一个辅助遍历temp
        HeroNode temp=head;
        //遍历链表,找到最后
        while (true){
            //找到链表的最后
            if(temp.next==null){
                break;
            }
            //如果没有找到最后,就将temp后移
            temp=temp.next;
        }
        //当退出while循环时,temp就指向了链表的最后
        //将最后这个节点的next指向新的节点
        temp.next=heroNode;
    }
    //显示链表【遍历】
    public void list(){
        //判断链表是否为空
        if (head.next==null){
            System.out.println("链表为空");
            return;
        }
        //因为头节点不能动,因此我们需要一个辅助变量来遍历
        HeroNode temp=head.next;
        while (true){
            //判断是否到链表最后
            if (temp==null){
                break;
            }
            //输出节点的信息
            System.out.println(temp);
            //将next后移
            temp=temp.next;
        }
    }

}

实体类:

//定义HeroNode,每个HeroNode对象就是一个节点
class HeroNode{
    public int no;
    public String name;
    public String nickname;
    public HeroNode next; //指向下一个节点
    //构造器
    public HeroNode(int no,String name,String nickname){
        this.no=no;
        this.name=name;
        this.nickname=nickname;
    }
//为了显示方法,我们重新toString
    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickname='" + nickname +
                "'}";
    }
}

效果图:
在这里插入图片描述

  链表类List的源代码如下: import Java.io.*; public class List {  /*用变量来实现表头*/  private Node Head=null;  private Node Tail=null;  private Node Pointer=null;  private int Length=0;  public void deleteAll()  /*清空整个链表*/  {   Head=null;   Tail=null;   Pointer=null;   Length=0;  }  public void reset()  /*链表复位,使第一个结点成为当前结点*/  {   Pointer=null;  }  public boolean isEmpty()  /*判断链表是否为空*/  {   return(Length==0);  }  public boolean isEnd()  /*判断当前结点是否为最后一个结点*/  {   if(Length==0)    throw new Java.lang.NullPointerException();   else if(Length==1)    return true;   else    return(cursor()==Tail);  }  public Object nextNode()  /*返回当前结点的下一个结点的值,并使其成为当前结点*/  {   if(Length==1)    throw new Java.util.NoSuchElementException();   else if(Length==0)    throw new Java.lang.NullPointerException();   else   {    Node temp=cursor();    Pointer=temp;    if(temp!=Tail)     return(temp.next.data);    else     throw new Java.util.NoSuchElementException();   }  }  public Object currentNode()  /*返回当前结点的值*/  {   Node temp=cursor();   return temp.data;  }     public void insert(Object d)  /*在当前结点前插入一个结点,并使其成为当前结点*/  {   Node e=new Node(d);   if(Length==0)   {    Tail=e;    Head=e;   }   else   {    Node temp=cursor();    e.next=temp;    if(Pointer==null)     Head=e;    else     Pointer.next=e;   }   Length++;  }  public int size()  /*返回链表的大小*/  {   return (Length);  }
<think> 我们首先需要创建一个单链表。根据引用[1][2][3][4],单链表节点组成,每个节点包含数据域和指向下一个节点的指针域。 步骤: 1. 定义链表节点结构体,包含数据(这里假设是整数)和指向下一个节点的指针。 2. 创建链表:这里我们可以使用尾插法或头插法。根据题目要求,输入链表数据以-1结束,所以我们将使用尾插法来创建链表(因为头插法创建的链表顺序是逆序的,而题目没有要求逆序,所以通常使用尾插法保持输入顺序)。 3. 实现插入函数:在单链表的第n个元素前插入一个数据为m的节点。注意:如果n=1,则插入在头节点之后(即第一个节点之前);如果n大于链表长度,则插入在链表末尾(或者根据题目要求,如果位置超出则插入末尾?但通常题目会说明,这里题目没有明确,我们按照一般情况:如果n大于链表长度,则插入到链表末尾)。 4. 输出链表:遍历链表并输出每个节点的数据。 注意:单链表通常有一个头节点(不存储数据,仅作为起始标记)或者没有头节点(第一个节点就存储数据)。根据引用[3][4],有些实现使用头节点,有些不使用。这里我们按照常见做法,使用头节点(带头节点的链表在插入删除时更统一)。 但是,题目没有明确要求使用头节点,而输入数据以-1结束,我们可以选择使用头节点或者不使用。这里为了简化,我们使用头节点(这样在第一个节点插入时不需要特殊处理头指针)。 具体步骤: 1. 定义节点结构体Node,包含int data和Node* next。 2. 创建头节点head,其next初始化为nullptr。 3. 输入数据,当输入的数据不是-1时,创建新节点,并用尾插法插入链表(为了保持顺序,我们需要一个尾指针来记录当前链表的最后一个节点)。 4. 输入n和m,表示在第n个节点插入数据为m的节点(注意:n从1开始计数,即第一个节点就是头节点后面的那个节点)。如果n大于链表长度,则插入到链表末尾。 5. 插入操作:从头节点开始遍历,找到第n-1个节点(即要插入位置的前一个节点),然后插入节点。 6. 输出链表:从头节点的下一个节点开始遍历,直到链表末尾,输出每个节点的数据。 注意:如果n=1,那么我们要在第一个节点插入,也就是头节点后面插入;如果n大于链表长度,则我们遍历到最后一个节点,然后插入在最后。 但是,如果链表为空(即只有头节点),那么无论n是多少,我们都插入在头节点后面。 另外,题目要求输出插入后的链表。 代码结构: 1. 定义结构体 2. 创建头节点,并初始化 3. 创建链表(尾插法) 4. 输入n和m 5. 插入操作 6. 输出链表 7. 释放链表内存(题目未要求,但良好的习惯应该释放) 然而,题目没有要求释放内存,且程序结束后操作系统会回收,但为了完整性我们可以考虑。 但是,由于题目没有明确要求,我们重点放在插入操作上。 我们假设节点结构为: struct Node { int data; Node* next; }; 创建链表的过程: Node* head = new Node(); // 头节点,不存储数据 Node* tail = head; // 初始时尾指针指向头节点 int num; while (cin >> num && num != -1) { Node* newNode = new Node(); newNode->data = num; newNode->next = nullptr; tail->next = newNode; tail = newNode; // 更新尾指针 } 插入操作: 输入n和m,创建新节点newNode,其数据为m。 我们要找到第n-1个节点(即位置为n的节点的前一个节点),因为我们要在它后面插入。 从head开始,移动n-1步(注意:如果链表长度小于n-1,则我们只移动到最后一个节点)。 具体步骤: Node* p = head; int count = 0; // 当前p指向的是第count个节点(头节点是第0个) while (p->next != nullptr && count < n-1) { p = p->next; count++; } // 此时,p指向第n-1个节点(如果链表长度>=n-1)或者最后一个节点(如果链表长度<n-1) newNode->next = p->next; p->next = newNode; 注意:如果n=1,那么p就是head,然后插入在head后面,即第一个节点前面。 输出链表: Node* p = head->next; while (p != nullptr) { cout << p->data; if (p->next != nullptr) { cout << " "; } p = p->next; } cout << endl; 但是,题目要求输出插入后的链表,并且输入数据以-1结束,然后是n和m。 完整代码示例: 注意:输入分为两部分,第一部分是链表数据(以-1结束),第二部分是n和m(两个整数)。 例如输入: 1 2 3 4 5 -1 3 10 表示在第三个节点插入10,插入后链表为:1 2 10 3 4 5 如果输入: 1 2 3 4 5 -1 8 10 则在末尾插入10,输出:1 2 3 4 5 10 代码实现: </think> 以下是用C++实现单链表在第n个元素前插入数据为m的节点,并输出插入后链表的完整代码: ```cpp #include <iostream> using namespace std; // 定义链表节点结构体 struct Node { int data; // 数据域 Node* next; // 指针域 }; // 创建链表(尾插法) Node* createList() { Node* head = new Node(); // 头结点 Node* tail = head; // 尾指针 int value; while (cin >> value && value != -1) { Node* newNode = new Node(); newNode->data = value; newNode->next = nullptr; tail->next = newNode; // 尾指针指向新节点 tail = newNode; // 更新尾指针 } return head; } // 在第n个位置前插入节点 void insertNode(Node* head, int n, int m) { Node* p = head; int count = 0; // 找到第n-1个节点 while (p != nullptr && count < n - 1) { p = p->next; count++; } if (p != nullptr) { Node* newNode = new Node(); newNode->data = m; newNode->next = p->next; // 新节点指向原第n个节点 p->next = newNode; // 第n-1个节点指向新节点 } } // 打印链表 void printList(Node* head) { Node* p = head->next; // 跳过头结点 while (p != nullptr) { cout << p->data; if (p->next != nullptr) cout << " "; p = p->next; } cout << endl; } int main() { // 创建链表 Node* head = createList(); // 读取插入位置和数据 int n, m; cin >> n >> m; // 插入节点 insertNode(head, n, m); // 输出结果 printList(head); return 0; } ``` ### 代码说明 1. **数据结构**: - 使用`Node`结构体表示链表节点,包含`data`(数据域)和`next`(指针域)[^4][^3] - 头结点不存储实际数据,仅作为链表起始标记[^4] 2. **创建链表**: - 采用尾插法构建链表,保持输入顺序[^3] - 输入以`-1`作为结束标志 3. **插入操作**: - 定位到第`n-1`个节点插入位置的前驱节点)[^2] - 创建新节点并调整指针: ```cpp newNode->next = p->next; // 新节点指向原第n个节点 p->next = newNode; // 前驱节点指向新节点 ``` 4. **边界处理**: - 若`n`超过链表长度,新节点插入到链表末尾 - 若`n=1`,新节点成为首元节点 ### 使用示例 **输入**: ``` 1 2 3 4 5 -1 // 链表数据 3 10 // 在第3个位置前插入10 ``` **输出**: ``` 1 2 10 3 4 5 ``` **输入**: ``` 10 20 30 -1 // 链表数据 1 5 // 在第1个位置前插入5 ``` **输出**: ``` 5 10 20 30 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值